This commit is contained in:
Mattias Põldaru 2012-03-12 10:25:48 +02:00
commit 9e4cdf1a74
43 changed files with 1741 additions and 2245 deletions

View File

@ -21,3 +21,4 @@ openlp/core/resources.py.old
*.qm
resources/windows/warnOpenLP.txt
openlp.cfg
.idea

View File

@ -36,8 +36,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \
StringContent, build_icon, translate, Receiver, ListWidgetWithDnD
from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import UiStrings, context_menu_action, \
context_menu_separator, critical_error_message_box
from openlp.core.lib.ui import UiStrings, create_widget_action, \
critical_error_message_box
log = logging.getLogger(__name__)
@ -147,43 +147,6 @@ class MediaManagerItem(QtGui.QWidget):
self.toolbar = OpenLPToolbar(self)
self.pageLayout.addWidget(self.toolbar)
def addToolbarButton(
self, title, tooltip, icon, slot=None, checkable=False):
"""
A method to help developers easily add a button to the toolbar.
``title``
The title of the button.
``tooltip``
The tooltip to be displayed when the mouse hovers over the
button.
``icon``
The icon of the button. This can be an instance of QIcon, or a
string containing either the absolute path to the image, or an
internal resource path starting with ':/'.
``slot``
The method to call when the button is clicked.
``checkable``
If *True* the button has two, *off* and *on*, states. Default is
*False*, which means the buttons has only one state.
"""
# NB different order (when I broke this out, I didn't want to
# break compatability), but it makes sense for the icon to
# come before the tooltip (as you have to have an icon, but
# not neccesarily a tooltip)
return self.toolbar.addToolbarButton(title, icon, tooltip, slot,
checkable)
def addToolbarSeparator(self):
"""
A very simple method to add a separator to the toolbar.
"""
self.toolbar.addSeparator()
def setupUi(self):
"""
This method sets up the interface on the button. Plugin
@ -208,40 +171,41 @@ class MediaManagerItem(QtGui.QWidget):
toolbar_actions = []
## Import Button ##
if self.hasImportIcon:
toolbar_actions.append([StringContent.Import,
toolbar_actions.append([u'Import', StringContent.Import,
u':/general/general_import.png', self.onImportClick])
## Load Button ##
if self.hasFileIcon:
toolbar_actions.append([StringContent.Load,
toolbar_actions.append([u'Load', StringContent.Load,
u':/general/general_open.png', self.onFileClick])
## New Button ##
if self.hasNewIcon:
toolbar_actions.append([StringContent.New,
toolbar_actions.append([u'New', StringContent.New,
u':/general/general_new.png', self.onNewClick])
## Edit Button ##
if self.hasEditIcon:
toolbar_actions.append([StringContent.Edit,
toolbar_actions.append([u'Edit', StringContent.Edit,
u':/general/general_edit.png', self.onEditClick])
## Delete Button ##
if self.hasDeleteIcon:
toolbar_actions.append([StringContent.Delete,
toolbar_actions.append([u'Delete', StringContent.Delete,
u':/general/general_delete.png', self.onDeleteClick])
## Preview ##
toolbar_actions.append([StringContent.Preview,
toolbar_actions.append([u'Preview', StringContent.Preview,
u':/general/general_preview.png', self.onPreviewClick])
## Live Button ##
toolbar_actions.append([StringContent.Live,
toolbar_actions.append([u'Live', StringContent.Live,
u':/general/general_live.png', self.onLiveClick])
## Add to service Button ##
toolbar_actions.append([StringContent.Service,
toolbar_actions.append([u'Service', StringContent.Service,
u':/general/general_add.png', self.onAddClick])
for action in toolbar_actions:
if action[0] == StringContent.Preview:
self.addToolbarSeparator()
self.addToolbarButton(
self.plugin.getString(action[0])[u'title'],
self.plugin.getString(action[0])[u'tooltip'],
action[1], action[2])
self.toolbar.addSeparator()
self.toolbar.addToolbarAction(
u'%s%sAction' % (self.plugin.name, action[0]),
text=self.plugin.getString(action[1])[u'title'], icon=action[2],
tooltip=self.plugin.getString(action[1])[u'tooltip'],
triggers=action[3])
def addListViewToToolBar(self):
"""
@ -259,35 +223,37 @@ class MediaManagerItem(QtGui.QWidget):
# define and add the context menu
self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
if self.hasEditIcon:
context_menu_action(
self.listView, u':/general/general_edit.png',
self.plugin.getString(StringContent.Edit)[u'title'],
self.onEditClick)
context_menu_separator(self.listView)
create_widget_action(self.listView,
text=self.plugin.getString(StringContent.Edit)[u'title'],
icon=u':/general/general_edit.png',
triggers=self.onEditClick)
create_widget_action(self.listView, separator=True)
if self.hasDeleteIcon:
context_menu_action(
self.listView, u':/general/general_delete.png',
self.plugin.getString(StringContent.Delete)[u'title'],
self.onDeleteClick, [QtCore.Qt.Key_Delete])
context_menu_separator(self.listView)
context_menu_action(
self.listView, u':/general/general_preview.png',
self.plugin.getString(StringContent.Preview)[u'title'],
self.onPreviewClick, [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
context_menu_action(
self.listView, u':/general/general_live.png',
self.plugin.getString(StringContent.Live)[u'title'],
self.onLiveClick, [QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Enter,
QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Return])
context_menu_action(
self.listView, u':/general/general_add.png',
self.plugin.getString(StringContent.Service)[u'title'],
self.onAddClick, [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal])
create_widget_action(self.listView,
text=self.plugin.getString(StringContent.Delete)[u'title'],
icon=u':/general/general_delete.png',
shortcuts=[QtCore.Qt.Key_Delete], triggers=self.onDeleteClick)
create_widget_action(self.listView, separator=True)
create_widget_action(self.listView,
text=self.plugin.getString(StringContent.Preview)[u'title'],
icon=u':/general/general_preview.png',
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
triggers=self.onPreviewClick)
create_widget_action(self.listView,
text=self.plugin.getString(StringContent.Live)[u'title'],
icon=u':/general/general_live.png',
shortcuts=[QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter,
QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return],
triggers=self.onLiveClick)
create_widget_action(self.listView,
text=self.plugin.getString(StringContent.Service)[u'title'],
icon=u':/general/general_add.png',
shortcuts=[QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal],
triggers=self.onAddClick)
if self.addToServiceItem:
context_menu_action(
self.listView, u':/general/general_add.png',
translate('OpenLP.MediaManagerItem',
'&Add to selected Service Item'), self.onAddEditClick)
create_widget_action(self.listView, text=translate(
'OpenLP.MediaManagerItem', '&Add to selected Service Item'),
icon=u':/general/general_add.png', triggers=self.onAddEditClick)
self.addCustomContextActions()
# Create the context menu and add all actions from the listView.
self.menu = QtGui.QMenu()

View File

@ -30,7 +30,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon
from openlp.core.lib.ui import icon_action
from openlp.core.lib.ui import create_widget_action
log = logging.getLogger(__name__)
@ -150,12 +150,8 @@ class SearchEdit(QtGui.QLineEdit):
menu = QtGui.QMenu(self)
first = None
for identifier, icon, title in items:
action = icon_action(menu, u'', icon)
action.setText(title)
action.setData(QtCore.QVariant(identifier))
menu.addAction(action)
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'),
self._onMenuActionTriggered)
action = create_widget_action(menu, text=title, icon=icon,
data=identifier, triggers=self._onMenuActionTriggered)
if first is None:
first = action
self._currentSearchType = identifier

View File

@ -40,7 +40,7 @@ except ImportError:
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, FormattingTags
from openlp.core.lib.ui import checkable_action
from openlp.core.lib.ui import create_action
log = logging.getLogger(__name__)
@ -90,9 +90,8 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
lang_menu = QtGui.QMenu(
translate('OpenLP.SpellTextEdit', 'Language:'))
for lang in enchant.list_languages():
action = checkable_action(
lang_menu, lang, lang == self.dictionary.tag)
action.setText(lang)
action = create_action(lang_menu, lang, text=lang,
checked=lang == self.dictionary.tag)
lang_menu.addAction(action)
popupMenu.insertSeparator(popupMenu.actions()[0])
popupMenu.insertMenu(popupMenu.actions()[0], lang_menu)

View File

@ -31,7 +31,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon
from openlp.core.lib.ui import create_widget_action
log = logging.getLogger(__name__)
@ -46,122 +46,41 @@ class OpenLPToolbar(QtGui.QToolBar):
"""
QtGui.QToolBar.__init__(self, parent)
# useful to be able to reuse button icons...
self.icons = {}
self.setIconSize(QtCore.QSize(20, 20))
self.actions = {}
log.debug(u'Init done for %s' % parent.__class__.__name__)
def addToolbarButton(self, title, icon, tooltip=None, slot=None,
checkable=False, shortcuts=None, context=QtCore.Qt.WidgetShortcut):
def addToolbarAction(self, name, **kwargs):
"""
A method to help developers easily add a button to the toolbar.
``title``
The title of the button.
``icon``
The icon of the button. This can be an instance of QIcon, or a
string containing either the absolute path to the image, or an
internal resource path starting with ':/'.
``tooltip``
A hint or tooltip for this button.
``slot``
The method to run when this button is clicked.
``checkable``
If *True* the button has two, *off* and *on*, states. Default is
*False*, which means the buttons has only one state.
``shortcuts``
The list of shortcuts for this action
``context``
Specify the context in which this shortcut is valid
A new QAction is created by calling ``create_action()``. The action is
added to the toolbar and the toolbar is set as parent.
For more details please look at openlp.core.lib.ui.create_action()
"""
if icon:
actionIcon = build_icon(icon)
if slot and not checkable:
newAction = self.addAction(actionIcon, title, slot)
else:
newAction = self.addAction(actionIcon, title)
self.icons[title] = actionIcon
else:
newAction = QtGui.QAction(title, self)
self.addAction(newAction)
QtCore.QObject.connect(newAction,
QtCore.SIGNAL(u'triggered()'), slot)
if tooltip:
newAction.setToolTip(tooltip)
if checkable:
newAction.setCheckable(True)
QtCore.QObject.connect(newAction,
QtCore.SIGNAL(u'toggled(bool)'), slot)
self.actions[title] = newAction
if shortcuts is not None:
newAction.setShortcuts(shortcuts)
newAction.setShortcutContext(context)
return newAction
action = create_widget_action(self, name, **kwargs)
self.actions[name] = action
return action
def addToolbarSeparator(self, handle):
def addToolbarWidget(self, widget):
"""
Add a Separator bar to the toolbar and store it's Handle
"""
action = self.addSeparator()
self.actions[handle] = action
def addToolbarWidget(self, handle, widget):
"""
Add a Widget to the toolbar and store it's Handle
Add a widget and store it's handle under the widgets object name.
"""
action = self.addWidget(widget)
self.actions[handle] = action
self.actions[unicode(widget.objectName())] = action
def getIconFromTitle(self, title):
def setWidgetVisible(self, widgets, visible=True):
"""
Search through the list of icons for an icon with a particular title,
and return that icon.
Set the visibitity for a widget or a list of widgets.
``title``
The title of the icon to search for.
"""
title = QtCore.QString(title)
try:
if self.icons[title]:
return self.icons[title]
except KeyError:
log.exception(u'getIconFromTitle - no icon for %s' % title)
return QtGui.QIcon()
``widget``
A list of string with widget object names.
def makeWidgetsInvisible(self, widgets):
``visible``
The new state as bool.
"""
Hide a set of widgets.
for handle in widgets:
if handle in self.actions:
self.actions[handle].setVisible(visible)
else:
log.warn(u'No handle "%s" in actions list.', unicode(handle))
``widgets``
The list of names of widgets to be hidden.
"""
for widget in widgets:
self.actions[widget].setVisible(False)
def makeWidgetsVisible(self, widgets):
"""
Show a set of widgets.
``widgets``
The list of names of widgets to be shown.
"""
for widget in widgets:
self.actions[widget].setVisible(True)
def addPushButton(self, image_file=None, text=u''):
"""
Adds a push button to the toolbar.
Returns the push button
"""
push_button = QtGui.QPushButton(build_icon(image_file), text)
push_button.setCheckable(True)
push_button.setFlat(True)
self.addWidget(push_button)
return push_button

View File

@ -281,100 +281,102 @@ def create_up_down_push_button_set(parent):
QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked)
return up_button, down_button
def base_action(parent, name, category=None):
def create_action(parent, name, **kwargs):
"""
Return the most basic action with the object name set.
Return an action with the object name set and the given parameters.
``category``
The category the action should be listed in the shortcut dialog. If you
not wish, that this action is added to the shortcut dialog, then do not
state any.
"""
action = QtGui.QAction(parent)
action.setObjectName(name)
if category is not None:
action_list = ActionList.get_instance()
action_list.add_action(action, category)
return action
``parent``
A QtCore.QObject for the actions parent (required).
def checkable_action(parent, name, checked=None, category=None):
"""
Return a standard action with the checkable attribute set.
"""
action = base_action(parent, name, category)
action.setCheckable(True)
if checked is not None:
action.setChecked(checked)
return action
def icon_action(parent, name, icon, checked=None, category=None):
"""
Return a standard action with an icon.
"""
if checked is not None:
action = checkable_action(parent, name, checked, category)
else:
action = base_action(parent, name, category)
action.setIcon(build_icon(icon))
return action
def shortcut_action(parent, name, shortcuts, function, icon=None, checked=None,
category=None, context=QtCore.Qt.WindowShortcut):
"""
Return a shortcut enabled action.
"""
action = QtGui.QAction(parent)
action.setObjectName(name)
if icon is not None:
action.setIcon(build_icon(icon))
if checked is not None:
action.setCheckable(True)
action.setChecked(checked)
if shortcuts:
action.setShortcuts(shortcuts)
action.setShortcutContext(context)
action_list = ActionList.get_instance()
action_list.add_action(action, category)
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), function)
return action
def context_menu_action(base, icon, text, slot, shortcuts=None, category=None,
context=QtCore.Qt.WidgetShortcut):
"""
Utility method to help build context menus.
``base``
The parent menu to add this menu item to
``icon``
An icon for this action
``name``
A string which is set as object name (required).
``text``
The text to display for this action
A string for the action text.
``slot``
The code to run when this action is triggered
``icon``
Either a QIcon, a resource string, or a file location string for the
action icon.
``tooltip``
A string for the action tool tip.
``statustip``
A string for the action status tip.
``checked``
A bool for the state. If ``None`` the Action is not checkable.
``enabled``
False in case the action should be disabled.
``visible``
False in case the action should be hidden.
``separator``
True in case the action will be considered a separator.
``data``
Data which is set as QVariant type.
``shortcuts``
The action's shortcuts.
``category``
The category the shortcut should be listed in the shortcut dialog. If
left to ``None``, then the action will be hidden in the shortcut dialog.
A QList<QKeySequence> (or a list of strings) which are set as shortcuts.
``context``
The context the shortcut is valid.
A context for the shortcut execution.
``category``
A category the action should be listed in the shortcut dialog.
``triggers``
A slot which is connected to the actions ``triggered()`` slot.
"""
action = QtGui.QAction(text, base)
if icon:
action.setIcon(build_icon(icon))
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), slot)
if shortcuts is not None:
action.setShortcuts(shortcuts)
action.setShortcutContext(context)
action = QtGui.QAction(parent)
action.setObjectName(name)
if kwargs.get(u'text'):
action.setText(kwargs.pop(u'text'))
if kwargs.get(u'icon'):
action.setIcon(build_icon(kwargs.pop(u'icon')))
if kwargs.get(u'tooltip'):
action.setToolTip(kwargs.pop(u'tooltip'))
if kwargs.get(u'statustip'):
action.setStatusTip(kwargs.pop(u'statustip'))
if kwargs.get(u'checked') is not None:
action.setCheckable(True)
action.setChecked(kwargs.pop(u'checked'))
if not kwargs.pop(u'enabled', True):
action.setEnabled(False)
if not kwargs.pop(u'visible', True):
action.setVisible(False)
if kwargs.pop(u'separator', False):
action.setSeparator(True)
if u'data' in kwargs:
action.setData(QtCore.QVariant(kwargs.pop(u'data')))
if kwargs.get(u'shortcuts'):
action.setShortcuts(kwargs.pop(u'shortcuts'))
if u'context' in kwargs:
action.setShortcutContext(kwargs.pop(u'context'))
if kwargs.get(u'category'):
action_list = ActionList.get_instance()
action_list.add_action(action)
base.addAction(action)
action_list.add_action(action, unicode(kwargs.pop(u'category')))
if kwargs.get(u'triggers'):
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'),
kwargs.pop(u'triggers'))
for key in kwargs.keys():
if key not in [u'text', u'icon', u'tooltip', u'statustip', u'checked',
u'shortcuts', u'category', u'triggers']:
log.warn(u'Parameter %s was not consumed in create_action().', key)
return action
def create_widget_action(parent, name=u'', **kwargs):
"""
Return a new QAction by calling ``create_action(parent, name, **kwargs)``.
The shortcut context defaults to ``QtCore.Qt.WidgetShortcut`` and the action
is added to the parents action list.
"""
kwargs.setdefault(u'context', QtCore.Qt.WidgetShortcut)
action = create_action(parent, name, **kwargs)
parent.addAction(action)
return action
def context_menu(base, icon, text):
@ -394,18 +396,6 @@ def context_menu(base, icon, text):
action.setIcon(build_icon(icon))
return action
def context_menu_separator(base):
"""
Add a separator to a context menu
``base``
The menu object to add the separator to
"""
action = QtGui.QAction(u'', base)
action.setSeparator(True)
base.addAction(action)
return action
def add_widget_completer(cache, widget):
"""
Adds a text autocompleter to a widget.

View File

@ -357,7 +357,7 @@ class AdvancedTab(SettingsTab):
translate('OpenLP.GeneralTab', '&Next Item'))
self.nextItemLabel.setText(
translate('OpenLP.GeneralTab', 'Up and down arrow keys '
'advance to the the next or previous Service Item from the '
'advance to the next or previous Service Item from the '
'top and bottom slides of each Service Item.'))
def load(self):

View File

@ -150,7 +150,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
translate('OpenLP.ExceptionForm',
'Text files (*.txt *.log *.text)'))
if filename:
filename = unicode(QtCore.QDir.toNativeSeparators(filename))
filename = unicode(filename).replace(u'/', os.path.sep)
SettingsManager.set_last_dir(self.settingsSection, os.path.dirname(
filename))
report_text = report_text % self._createReport()

View File

@ -27,6 +27,7 @@
from PyQt4 import QtGui
from openlp.core.lib.ui import create_action
from openlp.core.utils import LanguageManager
from firsttimelanguagedialog import Ui_FirstTimeLanguageDialog
@ -55,8 +56,7 @@ class FirstTimeLanguageForm(QtGui.QDialog, Ui_FirstTimeLanguageDialog):
LanguageManager.set_language(False, False)
else:
LanguageManager.auto_language = False
action = QtGui.QAction(None)
action.setObjectName(unicode(self.languageComboBox.currentText()))
action = create_action(None, self.languageComboBox.currentText())
LanguageManager.set_language(action, False)
return QtGui.QDialog.accept(self)

View File

@ -53,60 +53,64 @@ class GeneralTab(SettingsTab):
"""
self.setObjectName(u'GeneralTab')
SettingsTab.setupUi(self)
self.tabLayout.setStretch(1, 1)
# Monitors
self.monitorGroupBox = QtGui.QGroupBox(self.leftColumn)
self.monitorGroupBox.setObjectName(u'monitorGroupBox')
self.monitorLayout = QtGui.QFormLayout(self.monitorGroupBox)
self.monitorLayout = QtGui.QGridLayout(self.monitorGroupBox)
self.monitorLayout.setObjectName(u'monitorLayout')
self.monitorLabel = QtGui.QLabel(self.monitorGroupBox)
self.monitorLabel.setObjectName(u'monitorLabel')
self.monitorLayout.addRow(self.monitorLabel)
self.monitorRadioButton = QtGui.QRadioButton(self.monitorGroupBox)
self.monitorRadioButton.setObjectName(u'monitorRadioButton')
self.monitorLayout.addWidget(self.monitorRadioButton, 0, 0, 1, 5)
self.monitorComboBox = QtGui.QComboBox(self.monitorGroupBox)
self.monitorComboBox.setObjectName(u'monitorComboBox')
self.monitorLayout.addRow(self.monitorComboBox)
self.monitorLayout.addWidget(self.monitorComboBox, 1, 1, 1, 4)
self.displayOnMonitorCheck = QtGui.QCheckBox(self.monitorGroupBox)
self.displayOnMonitorCheck.setObjectName(u'monitorComboBox')
self.monitorLayout.addRow(self.displayOnMonitorCheck)
self.monitorLayout.addWidget(self.displayOnMonitorCheck, 2, 1, 1, 4)
# Display Position
self.overrideRadioButton = QtGui.QRadioButton(self.monitorGroupBox)
self.overrideRadioButton.setObjectName(u'overrideRadioButton')
self.monitorLayout.addWidget(self.overrideRadioButton, 3, 0, 1, 5)
# Custom position
self.customXLabel = QtGui.QLabel(self.monitorGroupBox)
self.customXLabel.setObjectName(u'customXLabel')
self.monitorLayout.addWidget(self.customXLabel, 4, 1)
self.customXValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
self.customXValueEdit.setObjectName(u'customXValueEdit')
self.customXValueEdit.setRange(-9999, 9999)
self.monitorLayout.addWidget(self.customXValueEdit, 5, 1)
self.customYLabel = QtGui.QLabel(self.monitorGroupBox)
self.customYLabel.setObjectName(u'customYLabel')
self.monitorLayout.addWidget(self.customYLabel, 4, 2)
self.customYValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
self.customYValueEdit.setObjectName(u'customYValueEdit')
self.customYValueEdit.setRange(-9999, 9999)
self.monitorLayout.addWidget(self.customYValueEdit, 5, 2)
self.customWidthLabel = QtGui.QLabel(self.monitorGroupBox)
self.customWidthLabel.setObjectName(u'customWidthLabel')
self.monitorLayout.addWidget(self.customWidthLabel, 4, 3)
self.customWidthValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
self.customWidthValueEdit.setObjectName(u'customWidthValueEdit')
self.customWidthValueEdit.setMaximum(9999)
self.monitorLayout.addWidget(self.customWidthValueEdit, 5, 3)
self.customHeightLabel = QtGui.QLabel(self.monitorGroupBox)
self.customHeightLabel.setObjectName(u'customHeightLabel')
self.monitorLayout.addWidget(self.customHeightLabel, 4, 4)
self.customHeightValueEdit = QtGui.QSpinBox(self.monitorGroupBox)
self.customHeightValueEdit.setObjectName(u'customHeightValueEdit')
self.customHeightValueEdit.setMaximum(9999)
self.monitorLayout.addWidget(self.customHeightValueEdit, 5, 4)
# Set up the stretchiness of each column, so that the first column
# less stretchy (and therefore smaller) than the others
self.monitorLayout.setColumnStretch(0, 1)
self.monitorLayout.setColumnStretch(1, 3)
self.monitorLayout.setColumnStretch(2, 3)
self.monitorLayout.setColumnStretch(3, 3)
self.monitorLayout.setColumnStretch(4, 3)
self.leftLayout.addWidget(self.monitorGroupBox)
self.startupGroupBox = QtGui.QGroupBox(self.leftColumn)
self.startupGroupBox.setObjectName(u'startupGroupBox')
self.startupLayout = QtGui.QVBoxLayout(self.startupGroupBox)
self.startupLayout.setObjectName(u'startupLayout')
self.warningCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.warningCheckBox.setObjectName(u'warningCheckBox')
self.startupLayout.addWidget(self.warningCheckBox)
self.autoOpenCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.autoOpenCheckBox.setObjectName(u'autoOpenCheckBox')
self.startupLayout.addWidget(self.autoOpenCheckBox)
self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.showSplashCheckBox.setObjectName(u'showSplashCheckBox')
self.startupLayout.addWidget(self.showSplashCheckBox)
self.checkForUpdatesCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.checkForUpdatesCheckBox.setObjectName(u'checkForUpdatesCheckBox')
self.startupLayout.addWidget(self.checkForUpdatesCheckBox)
self.leftLayout.addWidget(self.startupGroupBox)
self.settingsGroupBox = QtGui.QGroupBox(self.leftColumn)
self.settingsGroupBox.setObjectName(u'settingsGroupBox')
self.settingsLayout = QtGui.QFormLayout(self.settingsGroupBox)
self.settingsLayout.setObjectName(u'settingsLayout')
self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.saveCheckServiceCheckBox.setObjectName(u'saveCheckServiceCheckBox')
self.settingsLayout.addRow(self.saveCheckServiceCheckBox)
self.autoUnblankCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoUnblankCheckBox.setObjectName(u'autoUnblankCheckBox')
self.settingsLayout.addRow(self.autoUnblankCheckBox)
self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox')
self.settingsLayout.addRow(self.autoPreviewCheckBox)
# Moved here from image tab
self.timeoutLabel = QtGui.QLabel(self.settingsGroupBox)
self.timeoutLabel.setObjectName(u'timeoutLabel')
self.timeoutSpinBox = QtGui.QSpinBox(self.settingsGroupBox)
self.timeoutSpinBox.setObjectName(u'timeoutSpinBox')
self.timeoutSpinBox.setRange(1, 180)
self.settingsLayout.addRow(self.timeoutLabel, self.timeoutSpinBox)
self.leftLayout.addWidget(self.settingsGroupBox)
self.leftLayout.addStretch()
self.ccliGroupBox = QtGui.QGroupBox(self.rightColumn)
# CCLI Details
self.ccliGroupBox = QtGui.QGroupBox(self.leftColumn)
self.ccliGroupBox.setObjectName(u'ccliGroupBox')
self.ccliLayout = QtGui.QFormLayout(self.ccliGroupBox)
self.ccliLayout.setObjectName(u'ccliLayout')
@ -127,48 +131,9 @@ class GeneralTab(SettingsTab):
self.passwordEdit.setEchoMode(QtGui.QLineEdit.Password)
self.passwordEdit.setObjectName(u'passwordEdit')
self.ccliLayout.addRow(self.passwordLabel, self.passwordEdit)
self.rightLayout.addWidget(self.ccliGroupBox)
# Moved here from display tab
self.displayGroupBox = QtGui.QGroupBox(self.rightColumn)
self.displayGroupBox.setObjectName(u'displayGroupBox')
self.displayLayout = QtGui.QGridLayout(self.displayGroupBox)
self.displayLayout.setObjectName(u'displayLayout')
self.overrideCheckBox = QtGui.QCheckBox(self.displayGroupBox)
self.overrideCheckBox.setObjectName(u'overrideCheckBox')
self.displayLayout.addWidget(self.overrideCheckBox, 2, 0, 1, 4)
self.rightLayout.addWidget(self.displayGroupBox)
# Custom position
self.customXLabel = QtGui.QLabel(self.displayGroupBox)
self.customXLabel.setObjectName(u'customXLabel')
self.displayLayout.addWidget(self.customXLabel, 3, 0)
self.customXValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customXValueEdit.setObjectName(u'customXValueEdit')
self.customXValueEdit.setRange(-9999, 9999)
self.displayLayout.addWidget(self.customXValueEdit, 4, 0)
self.customYLabel = QtGui.QLabel(self.displayGroupBox)
self.customYLabel.setObjectName(u'customYLabel')
self.displayLayout.addWidget(self.customYLabel, 3, 1)
self.customYValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customYValueEdit.setObjectName(u'customYValueEdit')
self.customYValueEdit.setRange(-9999, 9999)
self.displayLayout.addWidget(self.customYValueEdit, 4, 1)
self.customWidthLabel = QtGui.QLabel(self.displayGroupBox)
self.customWidthLabel.setObjectName(u'customWidthLabel')
self.displayLayout.addWidget(self.customWidthLabel, 3, 2)
self.customWidthValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customWidthValueEdit.setObjectName(u'customWidthValueEdit')
self.customWidthValueEdit.setMaximum(9999)
self.displayLayout.addWidget(self.customWidthValueEdit, 4, 2)
self.customHeightLabel = QtGui.QLabel(self.displayGroupBox)
self.customHeightLabel.setObjectName(u'customHeightLabel')
self.displayLayout.addWidget(self.customHeightLabel, 3, 3)
self.customHeightValueEdit = QtGui.QSpinBox(self.displayGroupBox)
self.customHeightValueEdit.setObjectName(u'customHeightValueEdit')
self.customHeightValueEdit.setMaximum(9999)
self.displayLayout.addWidget(self.customHeightValueEdit, 4, 3)
self.rightLayout.addWidget(self.displayGroupBox)
self.leftLayout.addWidget(self.ccliGroupBox)
# Background audio
self.audioGroupBox = QtGui.QGroupBox(self.rightColumn)
self.audioGroupBox = QtGui.QGroupBox(self.leftColumn)
self.audioGroupBox.setObjectName(u'audioGroupBox')
self.audioLayout = QtGui.QVBoxLayout(self.audioGroupBox)
self.audioLayout.setObjectName(u'audioLayout')
@ -178,11 +143,52 @@ class GeneralTab(SettingsTab):
self.repeatListCheckBox = QtGui.QCheckBox(self.audioGroupBox)
self.repeatListCheckBox.setObjectName(u'repeatListCheckBox')
self.audioLayout.addWidget(self.repeatListCheckBox)
self.rightLayout.addWidget(self.audioGroupBox)
self.leftLayout.addWidget(self.audioGroupBox)
self.leftLayout.addStretch()
# Application Startup
self.startupGroupBox = QtGui.QGroupBox(self.rightColumn)
self.startupGroupBox.setObjectName(u'startupGroupBox')
self.startupLayout = QtGui.QVBoxLayout(self.startupGroupBox)
self.startupLayout.setObjectName(u'startupLayout')
self.warningCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.warningCheckBox.setObjectName(u'warningCheckBox')
self.startupLayout.addWidget(self.warningCheckBox)
self.autoOpenCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.autoOpenCheckBox.setObjectName(u'autoOpenCheckBox')
self.startupLayout.addWidget(self.autoOpenCheckBox)
self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.showSplashCheckBox.setObjectName(u'showSplashCheckBox')
self.startupLayout.addWidget(self.showSplashCheckBox)
self.checkForUpdatesCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.checkForUpdatesCheckBox.setObjectName(u'checkForUpdatesCheckBox')
self.startupLayout.addWidget(self.checkForUpdatesCheckBox)
self.rightLayout.addWidget(self.startupGroupBox)
# Application Settings
self.settingsGroupBox = QtGui.QGroupBox(self.rightColumn)
self.settingsGroupBox.setObjectName(u'settingsGroupBox')
self.settingsLayout = QtGui.QFormLayout(self.settingsGroupBox)
self.settingsLayout.setObjectName(u'settingsLayout')
self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.saveCheckServiceCheckBox.setObjectName(u'saveCheckServiceCheckBox')
self.settingsLayout.addRow(self.saveCheckServiceCheckBox)
self.autoUnblankCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoUnblankCheckBox.setObjectName(u'autoUnblankCheckBox')
self.settingsLayout.addRow(self.autoUnblankCheckBox)
self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox')
self.settingsLayout.addRow(self.autoPreviewCheckBox)
# Moved here from image tab
self.timeoutLabel = QtGui.QLabel(self.settingsGroupBox)
self.timeoutLabel.setObjectName(u'timeoutLabel')
self.timeoutSpinBox = QtGui.QSpinBox(self.settingsGroupBox)
self.timeoutSpinBox.setObjectName(u'timeoutSpinBox')
self.timeoutSpinBox.setRange(1, 180)
self.settingsLayout.addRow(self.timeoutLabel, self.timeoutSpinBox)
self.rightLayout.addWidget(self.settingsGroupBox)
self.rightLayout.addStretch()
# Signals and slots
QtCore.QObject.connect(self.overrideCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideCheckBoxToggled)
QtCore.QObject.connect(self.overrideRadioButton,
QtCore.SIGNAL(u'toggled(bool)'), self.onOverrideRadioButtonPressed)
QtCore.QObject.connect(self.customHeightValueEdit,
QtCore.SIGNAL(u'valueChanged(int)'), self.onDisplayChanged)
QtCore.QObject.connect(self.customWidthValueEdit,
@ -209,7 +215,7 @@ class GeneralTab(SettingsTab):
self.tabTitleVisible = translate('OpenLP.GeneralTab', 'General')
self.monitorGroupBox.setTitle(translate('OpenLP.GeneralTab',
'Monitors'))
self.monitorLabel.setText(translate('OpenLP.GeneralTab',
self.monitorRadioButton.setText(translate('OpenLP.GeneralTab',
'Select monitor for output display:'))
self.displayOnMonitorCheck.setText(
translate('OpenLP.GeneralTab', 'Display if a single screen'))
@ -242,10 +248,8 @@ class GeneralTab(SettingsTab):
self.passwordLabel.setText(
translate('OpenLP.GeneralTab', 'SongSelect password:'))
# Moved from display tab
self.displayGroupBox.setTitle(
translate('OpenLP.GeneralTab', 'Display Position'))
self.overrideCheckBox.setText(translate('OpenLP.GeneralTab',
'Override display position'))
self.overrideRadioButton.setText(translate('OpenLP.GeneralTab',
'Override display position:'))
self.customXLabel.setText(translate('OpenLP.GeneralTab', 'X'))
self.customYLabel.setText(translate('OpenLP.GeneralTab', 'Y'))
self.customHeightLabel.setText(translate('OpenLP.GeneralTab', 'Height'))
@ -291,7 +295,9 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(False)).toBool())
self.timeoutSpinBox.setValue(settings.value(u'loop delay',
QtCore.QVariant(5)).toInt()[0])
self.overrideCheckBox.setChecked(settings.value(u'override position',
self.monitorRadioButton.setChecked(not settings.value(u'override position',
QtCore.QVariant(False)).toBool())
self.overrideRadioButton.setChecked(settings.value(u'override position',
QtCore.QVariant(False)).toBool())
self.customXValueEdit.setValue(settings.value(u'x position',
QtCore.QVariant(self.screens.current[u'size'].x())).toInt()[0])
@ -306,10 +312,12 @@ class GeneralTab(SettingsTab):
self.repeatListCheckBox.setChecked(settings.value(
u'audio repeat list', QtCore.QVariant(False)).toBool())
settings.endGroup()
self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customHeightValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customWidthValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.monitorComboBox.setDisabled(self.overrideRadioButton.isChecked())
self.displayOnMonitorCheck.setDisabled(self.overrideRadioButton.isChecked())
self.customXValueEdit.setEnabled(self.overrideRadioButton.isChecked())
self.customYValueEdit.setEnabled(self.overrideRadioButton.isChecked())
self.customHeightValueEdit.setEnabled(self.overrideRadioButton.isChecked())
self.customWidthValueEdit.setEnabled(self.overrideRadioButton.isChecked())
self.display_changed = False
settings.beginGroup(self.settingsSection)
@ -354,7 +362,7 @@ class GeneralTab(SettingsTab):
settings.setValue(u'width',
QtCore.QVariant(self.customWidthValueEdit.value()))
settings.setValue(u'override position',
QtCore.QVariant(self.overrideCheckBox.isChecked()))
QtCore.QVariant(self.overrideRadioButton.isChecked()))
settings.setValue(u'audio start paused',
QtCore.QVariant(self.startPausedCheckBox.isChecked()))
settings.setValue(u'audio repeat list',
@ -380,7 +388,7 @@ class GeneralTab(SettingsTab):
self.customYValueEdit.value(),
self.customWidthValueEdit.value(),
self.customHeightValueEdit.value())
if self.overrideCheckBox.isChecked():
if self.overrideRadioButton.isChecked():
self.screens.set_override_display()
else:
self.screens.reset_current_display()
@ -388,13 +396,15 @@ class GeneralTab(SettingsTab):
Receiver.send_message(u'config_screen_changed')
self.display_changed = False
def onOverrideCheckBoxToggled(self, checked):
def onOverrideRadioButtonPressed(self, checked):
"""
Toggle screen state depending on check box state.
``checked``
The state of the check box (boolean).
"""
self.monitorComboBox.setDisabled(checked)
self.displayOnMonitorCheck.setDisabled(checked)
self.customXValueEdit.setEnabled(checked)
self.customYValueEdit.setEnabled(checked)
self.customHeightValueEdit.setEnabled(checked)

View File

@ -37,6 +37,7 @@ from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, \
translate, PluginManager, expand_tags
from openlp.core.lib.theme import BackgroundType
from openlp.core.ui import HideMode, ScreenList, AlertLocation
@ -143,7 +144,7 @@ class MainDisplay(Display):
windowFlags |= QtCore.Qt.SplashScreen
self.setWindowFlags(windowFlags)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setTransparency(True)
self.setTransparency(False)
if self.isLive:
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_display_hide'), self.hideDisplay)
@ -387,6 +388,8 @@ class MainDisplay(Display):
# replace the background
background = self.imageManager. \
get_image_bytes(self.override[u'image'])
self.setTransparency(self.serviceItem.themedata.background_type ==
BackgroundType.to_string(BackgroundType.Transparent))
if self.serviceItem.themedata.background_filename:
self.serviceItem.bg_image_bytes = self.imageManager. \
get_image_bytes(self.serviceItem.themedata.theme_name)

View File

@ -36,8 +36,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
PluginManager, Receiver, translate, ImageManager, PluginStatus
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
icon_action, shortcut_action
from openlp.core.lib.ui import UiStrings, create_action
from openlp.core.lib import SlideLimits
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ThemeManager, SlideController, PluginForm, MediaDockManager, \
@ -179,75 +178,78 @@ class Ui_MainWindow(object):
action_list = ActionList.get_instance()
action_list.add_category(unicode(UiStrings().File),
CategoryOrder.standardMenu)
self.fileNewItem = shortcut_action(mainWindow, u'fileNewItem',
[QtGui.QKeySequence(u'Ctrl+N')],
self.serviceManagerContents.onNewServiceClicked,
u':/general/general_new.png', category=unicode(UiStrings().File))
self.fileOpenItem = shortcut_action(mainWindow, u'fileOpenItem',
[QtGui.QKeySequence(u'Ctrl+O')],
self.serviceManagerContents.onLoadServiceClicked,
u':/general/general_open.png', category=unicode(UiStrings().File))
self.fileSaveItem = shortcut_action(mainWindow, u'fileSaveItem',
[QtGui.QKeySequence(u'Ctrl+S')],
self.serviceManagerContents.saveFile,
u':/general/general_save.png', category=unicode(UiStrings().File))
self.fileSaveAsItem = shortcut_action(mainWindow, u'fileSaveAsItem',
[QtGui.QKeySequence(u'Ctrl+Shift+S')],
self.serviceManagerContents.saveFileAs,
category=unicode(UiStrings().File))
self.printServiceOrderItem = shortcut_action(mainWindow,
u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')],
self.serviceManagerContents.printServiceOrder,
category=unicode(UiStrings().File))
self.fileExitItem = shortcut_action(mainWindow, u'fileExitItem',
[QtGui.QKeySequence(u'Alt+F4')], mainWindow.close,
u':/system/system_exit.png', category=unicode(UiStrings().File))
self.fileNewItem = create_action(mainWindow, u'fileNewItem',
icon=u':/general/general_new.png',
shortcuts=[QtGui.QKeySequence(u'Ctrl+N')],
category=UiStrings().File,
triggers=self.serviceManagerContents.onNewServiceClicked)
self.fileOpenItem = create_action(mainWindow, u'fileOpenItem',
icon=u':/general/general_open.png',
shortcuts=[QtGui.QKeySequence(u'Ctrl+O')],
category=UiStrings().File,
triggers=self.serviceManagerContents.onLoadServiceClicked)
self.fileSaveItem = create_action(mainWindow, u'fileSaveItem',
icon=u':/general/general_save.png',
shortcuts=[QtGui.QKeySequence(u'Ctrl+S')],
category=UiStrings().File,
triggers=self.serviceManagerContents.saveFile)
self.fileSaveAsItem = create_action(mainWindow, u'fileSaveAsItem',
shortcuts=[QtGui.QKeySequence(u'Ctrl+Shift+S')],
category=UiStrings().File,
triggers=self.serviceManagerContents.saveFileAs)
self.printServiceOrderItem = create_action(mainWindow,
u'printServiceItem', shortcuts=[QtGui.QKeySequence(u'Ctrl+P')],
category=UiStrings().File,
triggers=self.serviceManagerContents.printServiceOrder)
self.fileExitItem = create_action(mainWindow, u'fileExitItem',
icon=u':/system/system_exit.png',
shortcuts=[QtGui.QKeySequence(u'Alt+F4')],
category=UiStrings().File, triggers=mainWindow.close)
action_list.add_category(unicode(UiStrings().Import),
CategoryOrder.standardMenu)
self.importThemeItem = base_action(
mainWindow, u'importThemeItem', unicode(UiStrings().Import))
self.importLanguageItem = base_action(
mainWindow, u'importLanguageItem')#, unicode(UiStrings().Import))
self.importThemeItem = create_action(mainWindow,
u'importThemeItem', category=UiStrings().Import)
self.importLanguageItem = create_action(mainWindow,
u'importLanguageItem')#, category=UiStrings().Import)
action_list.add_category(unicode(UiStrings().Export),
CategoryOrder.standardMenu)
self.exportThemeItem = base_action(
mainWindow, u'exportThemeItem', unicode(UiStrings().Export))
self.exportLanguageItem = base_action(
mainWindow, u'exportLanguageItem')#, unicode(UiStrings().Export))
self.exportThemeItem = create_action(mainWindow,
u'exportThemeItem', category=UiStrings().Export)
self.exportLanguageItem = create_action(mainWindow,
u'exportLanguageItem')#, category=UiStrings().Export)
action_list.add_category(unicode(UiStrings().View),
CategoryOrder.standardMenu)
self.viewMediaManagerItem = shortcut_action(mainWindow,
u'viewMediaManagerItem', [QtGui.QKeySequence(u'F8')],
self.toggleMediaManager, u':/system/system_mediamanager.png',
self.mediaManagerDock.isVisible(), unicode(UiStrings().View))
self.viewThemeManagerItem = shortcut_action(mainWindow,
u'viewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
self.toggleThemeManager, u':/system/system_thememanager.png',
self.themeManagerDock.isVisible(), unicode(UiStrings().View))
self.viewServiceManagerItem = shortcut_action(mainWindow,
u'viewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
self.toggleServiceManager, u':/system/system_servicemanager.png',
self.serviceManagerDock.isVisible(), unicode(UiStrings().View))
self.viewPreviewPanel = shortcut_action(mainWindow,
u'viewPreviewPanel', [QtGui.QKeySequence(u'F11')],
self.setPreviewPanelVisibility, checked=previewVisible,
category=unicode(UiStrings().View))
self.viewLivePanel = shortcut_action(mainWindow, u'viewLivePanel',
[QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility,
checked=liveVisible, category=unicode(UiStrings().View))
self.lockPanel = shortcut_action(mainWindow, u'lockPanel',
None, self.setLockPanel,
checked=panelLocked, category=None)
self.viewMediaManagerItem = create_action(mainWindow,
u'viewMediaManagerItem', shortcuts=[QtGui.QKeySequence(u'F8')],
icon=u':/system/system_mediamanager.png',
checked=self.mediaManagerDock.isVisible(),
category=UiStrings().View, triggers=self.toggleMediaManager)
self.viewThemeManagerItem = create_action(mainWindow,
u'viewThemeManagerItem', shortcuts=[QtGui.QKeySequence(u'F10')],
icon=u':/system/system_thememanager.png',
checked=self.themeManagerDock.isVisible(),
category=UiStrings().View, triggers=self.toggleThemeManager)
self.viewServiceManagerItem = create_action(mainWindow,
u'viewServiceManagerItem', shortcuts=[QtGui.QKeySequence(u'F9')],
icon=u':/system/system_servicemanager.png',
checked=self.serviceManagerDock.isVisible(),
category=UiStrings().View, triggers=self.toggleServiceManager)
self.viewPreviewPanel = create_action(mainWindow, u'viewPreviewPanel',
shortcuts=[QtGui.QKeySequence(u'F11')], checked=previewVisible,
category=UiStrings().View, triggers=self.setPreviewPanelVisibility)
self.viewLivePanel = create_action(mainWindow, u'viewLivePanel',
shortcuts=[QtGui.QKeySequence(u'F12')], checked=liveVisible,
category=UiStrings().View, triggers=self.setLivePanelVisibility)
self.lockPanel = create_action(mainWindow, u'lockPanel',
checked=panelLocked, triggers=self.setLockPanel)
action_list.add_category(unicode(UiStrings().ViewMode),
CategoryOrder.standardMenu)
self.modeDefaultItem = checkable_action(
mainWindow, u'modeDefaultItem',
category=unicode(UiStrings().ViewMode))
self.modeSetupItem = checkable_action(
mainWindow, u'modeSetupItem',
category=unicode(UiStrings().ViewMode))
self.modeLiveItem = checkable_action(
mainWindow, u'modeLiveItem', True, unicode(UiStrings().ViewMode))
self.modeDefaultItem = create_action(mainWindow, u'modeDefaultItem',
checked=False, category=UiStrings().ViewMode)
self.modeSetupItem = create_action(mainWindow, u'modeSetupItem',
checked=False, category=UiStrings().ViewMode)
self.modeLiveItem = create_action(mainWindow, u'modeLiveItem',
checked=True, category=UiStrings().ViewMode)
self.modeGroup = QtGui.QActionGroup(mainWindow)
self.modeGroup.addAction(self.modeDefaultItem)
self.modeGroup.addAction(self.modeSetupItem)
@ -255,25 +257,27 @@ class Ui_MainWindow(object):
self.modeDefaultItem.setChecked(True)
action_list.add_category(unicode(UiStrings().Tools),
CategoryOrder.standardMenu)
self.toolsAddToolItem = icon_action(mainWindow, u'toolsAddToolItem',
u':/tools/tools_add.png', category=unicode(UiStrings().Tools))
self.toolsOpenDataFolder = icon_action(mainWindow,
u'toolsOpenDataFolder', u':/general/general_open.png',
category=unicode(UiStrings().Tools))
self.toolsFirstTimeWizard = icon_action(mainWindow,
u'toolsFirstTimeWizard', u':/general/general_revert.png',
category=unicode(UiStrings().Tools))
self.updateThemeImages = base_action(mainWindow,
u'updateThemeImages', category=unicode(UiStrings().Tools))
self.toolsAddToolItem = create_action(mainWindow,
u'toolsAddToolItem', icon=u':/tools/tools_add.png',
category=UiStrings().Tools)
self.toolsOpenDataFolder = create_action(mainWindow,
u'toolsOpenDataFolder', icon=u':/general/general_open.png',
category=UiStrings().Tools)
self.toolsFirstTimeWizard = create_action(mainWindow,
u'toolsFirstTimeWizard', icon=u':/general/general_revert.png',
category=UiStrings().Tools)
self.updateThemeImages = create_action(mainWindow,
u'updateThemeImages', category=UiStrings().Tools)
action_list.add_category(unicode(UiStrings().Settings),
CategoryOrder.standardMenu)
self.settingsPluginListItem = shortcut_action(mainWindow,
u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')],
self.onPluginItemClicked, u':/system/settings_plugin_list.png',
category=unicode(UiStrings().Settings))
self.settingsPluginListItem = create_action(mainWindow,
u'settingsPluginListItem',
icon=u':/system/settings_plugin_list.png',
shortcuts=[QtGui.QKeySequence(u'Alt+F7')],
category=UiStrings().Settings, triggers=self.onPluginItemClicked)
# i18n Language Items
self.autoLanguageItem = checkable_action(mainWindow,
u'autoLanguageItem', LanguageManager.auto_language)
self.autoLanguageItem = create_action(mainWindow, u'autoLanguageItem',
checked=LanguageManager.auto_language)
self.languageGroup = QtGui.QActionGroup(mainWindow)
self.languageGroup.setExclusive(True)
self.languageGroup.setObjectName(u'languageGroup')
@ -281,44 +285,43 @@ class Ui_MainWindow(object):
qmList = LanguageManager.get_qm_list()
savedLanguage = LanguageManager.get_language()
for key in sorted(qmList.keys()):
languageItem = checkable_action(
mainWindow, key, qmList[key] == savedLanguage)
languageItem = create_action(mainWindow, key,
checked=qmList[key] == savedLanguage)
add_actions(self.languageGroup, [languageItem])
self.settingsShortcutsItem = icon_action(mainWindow,
self.settingsShortcutsItem = create_action(mainWindow,
u'settingsShortcutsItem',
u':/system/system_configure_shortcuts.png',
category=unicode(UiStrings().Settings))
icon=u':/system/system_configure_shortcuts.png',
category=UiStrings().Settings)
# Formatting Tags were also known as display tags.
self.formattingTagItem = icon_action(mainWindow,
u'displayTagItem', u':/system/tag_editor.png',
category=unicode(UiStrings().Settings))
self.settingsConfigureItem = icon_action(mainWindow,
u'settingsConfigureItem', u':/system/system_settings.png',
category=unicode(UiStrings().Settings))
self.settingsImportItem = base_action(mainWindow,
u'settingsImportItem', category=unicode(UiStrings().Settings))
self.settingsExportItem = base_action(mainWindow,
u'settingsExportItem', category=unicode(UiStrings().Settings))
self.formattingTagItem = create_action(mainWindow,
u'displayTagItem', icon=u':/system/tag_editor.png',
category=UiStrings().Settings)
self.settingsConfigureItem = create_action(mainWindow,
u'settingsConfigureItem', icon=u':/system/system_settings.png',
category=UiStrings().Settings)
self.settingsImportItem = create_action(mainWindow,
u'settingsImportItem', category=UiStrings().Settings)
self.settingsExportItem = create_action(mainWindow,
u'settingsExportItem', category=UiStrings().Settings)
action_list.add_category(unicode(UiStrings().Help),
CategoryOrder.standardMenu)
self.aboutItem = shortcut_action(mainWindow, u'aboutItem',
[QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked,
u':/system/system_about.png', category=unicode(UiStrings().Help))
self.aboutItem = create_action(mainWindow, u'aboutItem',
icon=u':/system/system_about.png',
shortcuts=[QtGui.QKeySequence(u'Ctrl+F1')],
category=UiStrings().Help, triggers=self.onAboutItemClicked)
if os.name == u'nt':
self.localHelpFile = os.path.join(
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
self.offlineHelpItem = shortcut_action(
mainWindow, u'offlineHelpItem', [QtGui.QKeySequence(u'F1')],
self.onOfflineHelpClicked,
u':/system/system_help_contents.png',
category=unicode(UiStrings().Help))
self.onlineHelpItem = shortcut_action(
mainWindow, u'onlineHelpItem',
[QtGui.QKeySequence(u'Alt+F1')], self.onOnlineHelpClicked,
u':/system/system_online_help.png',
category=unicode(UiStrings().Help))
self.webSiteItem = base_action(
mainWindow, u'webSiteItem', category=unicode(UiStrings().Help))
self.offlineHelpItem = create_action(mainWindow, u'offlineHelpItem',
icon=u':/system/system_help_contents.png',
shortcuts=[QtGui.QKeySequence(u'F1')],
category=UiStrings().Help, triggers=self.onOfflineHelpClicked)
self.onlineHelpItem = create_action(mainWindow, u'onlineHelpItem',
icon=u':/system/system_online_help.png',
shortcuts=[QtGui.QKeySequence(u'Alt+F1')],
category=UiStrings().Help, triggers=self.onOnlineHelpClicked)
self.webSiteItem = create_action(mainWindow,
u'webSiteItem', category=UiStrings().Help)
add_actions(self.fileImportMenu, (self.settingsImportItem, None,
self.importThemeItem, self.importLanguageItem))
add_actions(self.fileExportMenu, (self.settingsExportItem, None,
@ -1378,27 +1381,24 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
recentFileCount = QtCore.QSettings().value(
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
existingRecentFiles = [recentFile for recentFile in self.recentFiles
if QtCore.QFile.exists(recentFile)]
if os.path.isfile(unicode(recentFile))]
recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
self.recentFilesMenu.clear()
for fileId, filename in enumerate(recentFilesToDisplay):
log.debug('Recent file name: %s', filename)
action = base_action(self, u'')
action.setText(u'&%d %s' %
(fileId + 1, QtCore.QFileInfo(filename).fileName()))
action.setData(QtCore.QVariant(filename))
self.connect(action, QtCore.SIGNAL(u'triggered()'),
self.serviceManagerContents.onRecentServiceClicked)
action = create_action(self, u'',
text=u'&%d %s' % (fileId + 1, os.path.splitext(os.path.basename(
unicode(filename)))[0]), data=filename,
triggers=self.serviceManagerContents.onRecentServiceClicked)
self.recentFilesMenu.addAction(action)
clearRecentFilesAction = base_action(self, u'')
clearRecentFilesAction.setText(
translate('OpenLP.MainWindow', 'Clear List',
'Clear List of recent files'))
clearRecentFilesAction.setStatusTip(
translate('OpenLP.MainWindow', 'Clear the list of recent files.'))
clearRecentFilesAction = create_action(self, u'',
text=translate('OpenLP.MainWindow', 'Clear List',
'Clear List of recent files'),
statustip=translate('OpenLP.MainWindow',
'Clear the list of recent files.'),
enabled=not self.recentFiles.isEmpty(),
triggers=self.recentFiles.clear)
add_actions(self.recentFilesMenu, (None, clearRecentFilesAction))
self.connect(clearRecentFilesAction, QtCore.SIGNAL(u'triggered()'),
self.recentFiles.clear)
clearRecentFilesAction.setEnabled(not self.recentFiles.isEmpty())
def addRecentFile(self, filename):

View File

@ -47,7 +47,7 @@ class MediaController(object):
self.parent = parent
self.mediaPlayers = {}
self.controller = []
self.overridenPlayer = ''
self.overriddenPlayer = ''
self.curDisplayMediaPlayer = {}
# Timer for video state
self.timer = QtCore.QTimer()
@ -204,18 +204,21 @@ class MediaController(object):
controller.media_info = MediaInfo()
# Build a Media ToolBar
controller.mediabar = OpenLPToolbar(controller)
controller.mediabar.addToolbarButton(
u'media_playback_play', u':/slides/media_playback_start.png',
translate('OpenLP.SlideController', 'Start playing media.'),
controller.sendToPlugins)
controller.mediabar.addToolbarButton(
u'media_playback_pause', u':/slides/media_playback_pause.png',
translate('OpenLP.SlideController', 'Pause playing media.'),
controller.sendToPlugins)
controller.mediabar.addToolbarButton(
u'media_playback_stop', u':/slides/media_playback_stop.png',
translate('OpenLP.SlideController', 'Stop playing media.'),
controller.sendToPlugins)
controller.mediabar.addToolbarAction(u'playbackPlay',
text=u'media_playback_play',
icon=u':/slides/media_playback_start.png',
tooltip=translate('OpenLP.SlideController', 'Start playing media.'),
triggers=controller.sendToPlugins)
controller.mediabar.addToolbarAction(u'playbackPause',
text=u'media_playback_pause',
icon=u':/slides/media_playback_pause.png',
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'),
triggers=controller.sendToPlugins)
controller.mediabar.addToolbarAction(u'playbackStop',
text=u'media_playback_stop',
icon=u':/slides/media_playback_stop.png',
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'),
triggers=controller.sendToPlugins)
# Build the seekSlider.
controller.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
controller.seekSlider.setMaximum(1000)
@ -223,9 +226,8 @@ class MediaController(object):
controller.seekSlider.setToolTip(translate(
'OpenLP.SlideController', 'Video position.'))
controller.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
controller.seekSlider.setObjectName(u'seek_slider')
controller.mediabar.addToolbarWidget(u'Seek Slider',
controller.seekSlider)
controller.seekSlider.setObjectName(u'seekSlider')
controller.mediabar.addToolbarWidget(controller.seekSlider)
# Build the volumeSlider.
controller.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
controller.volumeSlider.setTickInterval(10)
@ -237,9 +239,8 @@ class MediaController(object):
'OpenLP.SlideController', 'Audio Volume.'))
controller.volumeSlider.setValue(controller.media_info.volume)
controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
controller.volumeSlider.setObjectName(u'volume_slider')
controller.mediabar.addToolbarWidget(u'Audio Volume',
controller.volumeSlider)
controller.volumeSlider.setObjectName(u'volumeSlider')
controller.mediabar.addToolbarWidget(controller.volumeSlider)
control_panel.addWidget(controller.mediabar)
controller.mediabar.setVisible(False)
# Signals
@ -282,8 +283,6 @@ class MediaController(object):
if self.curDisplayMediaPlayer and value:
if self.curDisplayMediaPlayer[controller.display] != self.mediaPlayers[u'webkit']:
controller.display.setTransparency(False)
else:
controller.display.setTransparency(True)
# Special controls: Here media type specific Controls will be enabled
# (e.g. for DVD control, ...)
# TODO
@ -367,8 +366,8 @@ class MediaController(object):
usedPlayers = playerSettings.split(u',')
if QtCore.QSettings().value(u'media/override player',
QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
if self.overridenPlayer != '':
usedPlayers = [self.overridenPlayer]
if self.overriddenPlayer != '':
usedPlayers = [self.overriddenPlayer]
if controller.media_info.file_info.isFile():
suffix = u'*.%s' % \
controller.media_info.file_info.suffix().toLower()
@ -586,7 +585,7 @@ class MediaController(object):
override_player_index < len(usedPlayers):
self.overridenPlayer = usedPlayers[override_player_index]
else:
self.overridenPlayer = ''
self.overriddenPlayer = ''
def finalise(self):
self.timer.stop()

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@ from openlp.core.ui.media import MediaState
log = logging.getLogger(__name__)
AUDIO_EXT = [
AUDIO_EXT = [
u'*.mp3'
, u'*.wav'
, u'*.ogg'

View File

@ -246,7 +246,7 @@ VIDEO_EXT = [
, u'*.swf'
]
AUDIO_EXT = [
AUDIO_EXT = [
u'*.mp3'
, u'*.ogg'
]

View File

@ -41,7 +41,7 @@ from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
ItemCapabilities, SettingsManager, translate, str_to_bool
from openlp.core.lib.theme import ThemeLevel
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
context_menu_action, context_menu_separator, find_and_set_in_combo_box
create_widget_action, find_and_set_in_combo_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.ui.printserviceform import PrintServiceForm
from openlp.core.utils import AppLocation, delete_file, split_filename
@ -117,22 +117,23 @@ class ServiceManager(QtGui.QWidget):
self.layout.setMargin(0)
# Create the top toolbar
self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton(
UiStrings().NewService, u':/general/general_new.png',
UiStrings().CreateService, self.onNewServiceClicked)
self.toolbar.addToolbarButton(
UiStrings().OpenService, u':/general/general_open.png',
translate('OpenLP.ServiceManager', 'Load an existing service.'),
self.onLoadServiceClicked)
self.toolbar.addToolbarButton(
UiStrings().SaveService, u':/general/general_save.png',
translate('OpenLP.ServiceManager', 'Save this service.'),
self.saveFile)
self.toolbar.addToolbarAction(u'newService',
text=UiStrings().NewService, icon=u':/general/general_new.png',
tooltip=UiStrings().CreateService,
triggers=self.onNewServiceClicked)
self.toolbar.addToolbarAction(u'openService',
text=UiStrings().OpenService, icon=u':/general/general_open.png',
tooltip=translate('OpenLP.ServiceManager',
'Load an existing service.'), triggers=self.onLoadServiceClicked)
self.toolbar.addToolbarAction(u'saveService',
text=UiStrings().SaveService, icon=u':/general/general_save.png',
tooltip=translate('OpenLP.ServiceManager', 'Save this service.'),
triggers=self.saveFile)
self.toolbar.addSeparator()
self.themeLabel = QtGui.QLabel(u'%s:' % UiStrings().Theme, self)
self.themeLabel.setMargin(3)
self.themeLabel.setObjectName(u'themeLabel')
self.toolbar.addToolbarWidget(u'ThemeLabel', self.themeLabel)
self.toolbar.addToolbarWidget(self.themeLabel)
self.themeComboBox = QtGui.QComboBox(self.toolbar)
self.themeComboBox.setToolTip(translate('OpenLP.ServiceManager',
'Select a theme for the service.'))
@ -141,7 +142,7 @@ class ServiceManager(QtGui.QWidget):
self.themeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.themeComboBox.setObjectName(u'themeComboBox')
self.toolbar.addToolbarWidget(u'ThemeWidget', self.themeComboBox)
self.toolbar.addToolbarWidget(self.themeComboBox)
self.toolbar.setObjectName(u'toolbar')
self.layout.addWidget(self.toolbar)
# Create the service manager list
@ -168,99 +169,77 @@ class ServiceManager(QtGui.QWidget):
self.layout.addWidget(self.serviceManagerList)
# Add the bottom toolbar
self.orderToolbar = OpenLPToolbar(self)
self.serviceManagerList.moveTop = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move to &top'),
u':/services/service_top.png',
translate('OpenLP.ServiceManager',
'Move item to the top of the service.'),
self.onServiceTop, shortcuts=[QtCore.Qt.Key_Home])
self.serviceManagerList.moveTop.setObjectName(u'moveTop')
action_list = ActionList.get_instance()
action_list.add_category(
unicode(UiStrings().Service), CategoryOrder.standardToolbar)
action_list.add_action(
self.serviceManagerList.moveTop, unicode(UiStrings().Service))
self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &up'),
u':/services/service_up.png',
translate('OpenLP.ServiceManager',
self.serviceManagerList.moveTop = self.orderToolbar.addToolbarAction(
u'moveTop', text=translate('OpenLP.ServiceManager', 'Move to &top'),
icon=u':/services/service_top.png', tooltip=translate(
'OpenLP.ServiceManager', 'Move item to the top of the service.'),
shortcuts=[QtCore.Qt.Key_Home], category=UiStrings().Service,
triggers=self.onServiceTop)
self.serviceManagerList.moveUp = self.orderToolbar.addToolbarAction(
u'moveUp', text=translate('OpenLP.ServiceManager', 'Move &up'),
icon=u':/services/service_up.png',
tooltip=translate( 'OpenLP.ServiceManager',
'Move item up one position in the service.'),
self.onServiceUp, shortcuts=[QtCore.Qt.Key_PageUp])
self.serviceManagerList.moveUp.setObjectName(u'moveUp')
action_list.add_action(
self.serviceManagerList.moveUp, unicode(UiStrings().Service))
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &down'),
u':/services/service_down.png',
translate('OpenLP.ServiceManager',
shortcuts=[QtCore.Qt.Key_PageUp], category=UiStrings().Service,
triggers=self.onServiceUp)
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarAction(
u'moveDown', text=translate('OpenLP.ServiceManager', 'Move &down'),
icon=u':/services/service_down.png',
tooltip=translate('OpenLP.ServiceManager',
'Move item down one position in the service.'),
self.onServiceDown, shortcuts=[QtCore.Qt.Key_PageDown])
self.serviceManagerList.moveDown.setObjectName(u'moveDown')
action_list.add_action(
self.serviceManagerList.moveDown, unicode(UiStrings().Service))
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move to &bottom'),
u':/services/service_bottom.png',
translate('OpenLP.ServiceManager',
'Move item to the end of the service.'),
self.onServiceEnd, shortcuts=[QtCore.Qt.Key_End])
self.serviceManagerList.moveBottom.setObjectName(u'moveBottom')
action_list.add_action(
self.serviceManagerList.moveBottom, unicode(UiStrings().Service))
self.serviceManagerList.down = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &down'),
None,
translate('OpenLP.ServiceManager',
'Moves the selection down the window.'),
self.onMoveSelectionDown, shortcuts=[QtCore.Qt.Key_Down])
self.serviceManagerList.down.setObjectName(u'down')
shortcuts=[QtCore.Qt.Key_PageDown], category=UiStrings().Service,
triggers=self.onServiceDown)
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarAction(
u'moveBottom',
text=translate('OpenLP.ServiceManager', 'Move to &bottom'),
icon=u':/services/service_bottom.png', tooltip=translate(
'OpenLP.ServiceManager', 'Move item to the end of the service.'),
shortcuts=[QtCore.Qt.Key_End], category=UiStrings().Service,
triggers=self.onServiceEnd)
self.serviceManagerList.down = self.orderToolbar.addToolbarAction(
u'down', text=translate('OpenLP.ServiceManager', 'Move &down'),
tooltip=translate('OpenLP.ServiceManager',
'Moves the selection down the window.'), visible=False,
shortcuts=[QtCore.Qt.Key_Down], triggers=self.onMoveSelectionDown)
action_list.add_action(self.serviceManagerList.down)
self.serviceManagerList.down.setVisible(False)
self.serviceManagerList.up = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move up'),
None,
translate('OpenLP.ServiceManager',
'Moves the selection up the window.'),
self.onMoveSelectionUp, shortcuts=[QtCore.Qt.Key_Up])
self.serviceManagerList.up.setObjectName(u'up')
self.serviceManagerList.up = self.orderToolbar.addToolbarAction(
u'up', text=translate('OpenLP.ServiceManager', 'Move up'),
tooltip=translate('OpenLP.ServiceManager',
'Moves the selection up the window.'), visible=False,
shortcuts=[QtCore.Qt.Key_Up], triggers=self.onMoveSelectionUp)
action_list.add_action(self.serviceManagerList.up)
self.serviceManagerList.up.setVisible(False)
self.orderToolbar.addSeparator()
self.serviceManagerList.delete = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Delete From Service'),
u':/general/general_delete.png',
translate('OpenLP.ServiceManager',
self.serviceManagerList.delete = self.orderToolbar.addToolbarAction(
u'delete',
text=translate('OpenLP.ServiceManager', '&Delete From Service'),
icon=u':/general/general_delete.png',
tooltip=translate('OpenLP.ServiceManager',
'Delete the selected item from the service.'),
self.onDeleteFromService)
triggers=self.onDeleteFromService)
self.orderToolbar.addSeparator()
self.serviceManagerList.expand = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Expand all'),
u':/services/service_expand_all.png',
translate('OpenLP.ServiceManager',
'Expand all the service items.'),
self.onExpandAll, shortcuts=[QtCore.Qt.Key_Plus])
self.serviceManagerList.expand.setObjectName(u'expand')
action_list.add_action(
self.serviceManagerList.expand, unicode(UiStrings().Service))
self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Collapse all'),
u':/services/service_collapse_all.png',
translate('OpenLP.ServiceManager',
'Collapse all the service items.'),
self.onCollapseAll, shortcuts=[QtCore.Qt.Key_Minus])
self.serviceManagerList.collapse.setObjectName(u'collapse')
action_list.add_action(
self.serviceManagerList.collapse, unicode(UiStrings().Service))
self.serviceManagerList.expand = self.orderToolbar.addToolbarAction(
u'expand', text=translate('OpenLP.ServiceManager', '&Expand all'),
icon=u':/services/service_expand_all.png', tooltip=translate(
'OpenLP.ServiceManager', 'Expand all the service items.'),
shortcuts=[QtCore.Qt.Key_Plus], category=UiStrings().Service,
triggers=self.onExpandAll)
self.serviceManagerList.collapse = self.orderToolbar.addToolbarAction(
u'collapse',
text=translate('OpenLP.ServiceManager', '&Collapse all'),
icon=u':/services/service_collapse_all.png', tooltip=translate(
'OpenLP.ServiceManager', 'Collapse all the service items.'),
shortcuts=[QtCore.Qt.Key_Minus], category=UiStrings().Service,
triggers=self.onCollapseAll)
self.orderToolbar.addSeparator()
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Go Live'),
u':/general/general_live.png',
translate('OpenLP.ServiceManager',
'Send the selected item to Live.'), self.makeLive,
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
self.serviceManagerList.makeLive.setObjectName(u'orderToolbar')
action_list.add_action(
self.serviceManagerList.makeLive, unicode(UiStrings().Service))
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarAction(
u'makeLive', text=translate('OpenLP.ServiceManager', 'Go Live'),
icon=u':/general/general_live.png', tooltip=translate(
'OpenLP.ServiceManager', 'Send the selected item to Live.'),
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
category=UiStrings().Service, triggers=self.makeLive)
self.layout.addWidget(self.orderToolbar)
# Connect up our signals and slots
QtCore.QObject.connect(self.themeComboBox,
@ -305,34 +284,32 @@ class ServiceManager(QtGui.QWidget):
self.addToAction.setIcon(build_icon(u':/general/general_edit.png'))
# build the context menu
self.menu = QtGui.QMenu()
self.editAction = context_menu_action(
self.menu, u':/general/general_edit.png',
translate('OpenLP.ServiceManager', '&Edit Item'), self.remoteEdit)
self.maintainAction = context_menu_action(
self.menu, u':/general/general_edit.png',
translate('OpenLP.ServiceManager', '&Reorder Item'),
self.onServiceItemEditForm)
self.notesAction = context_menu_action(
self.menu, u':/services/service_notes.png',
translate('OpenLP.ServiceManager', '&Notes'),
self.onServiceItemNoteForm)
self.timeAction = context_menu_action(
self.menu, u':/media/media_time.png',
translate('OpenLP.ServiceManager', '&Start Time'),
self.onStartTimeForm)
self.deleteAction = context_menu_action(
self.menu, u':/general/general_delete.png',
translate('OpenLP.ServiceManager', '&Delete From Service'),
self.onDeleteFromService)
context_menu_separator(self.menu)
self.previewAction = context_menu_action(
self.menu, u':/general/general_preview.png',
translate('OpenLP.ServiceManager', 'Show &Preview'),
self.makePreview)
self.liveAction = context_menu_action(
self.menu, u':/general/general_live.png',
translate('OpenLP.ServiceManager', 'Show &Live'), self.makeLive)
context_menu_separator(self.menu)
self.editAction = create_widget_action(self.menu,
text=translate('OpenLP.ServiceManager', '&Edit Item'),
icon=u':/general/general_edit.png', triggers=self.remoteEdit)
self.maintainAction = create_widget_action(self.menu,
text=translate('OpenLP.ServiceManager', '&Reorder Item'),
icon=u':/general/general_edit.png',
triggers=self.onServiceItemEditForm)
self.notesAction = create_widget_action(self.menu,
text=translate('OpenLP.ServiceManager', '&Notes'),
icon=u':/services/service_notes.png',
triggers=self.onServiceItemNoteForm)
self.timeAction = create_widget_action(self.menu,
text=translate('OpenLP.ServiceManager', '&Start Time'),
icon=u':/media/media_time.png', triggers=self.onStartTimeForm)
self.deleteAction = create_widget_action(self.menu,
text=translate('OpenLP.ServiceManager', '&Delete From Service'),
icon=u':/general/general_delete.png',
triggers=self.onDeleteFromService)
self.menu.addSeparator()
self.previewAction = create_widget_action(self.menu,
text=translate('OpenLP.ServiceManager', 'Show &Preview'),
icon=u':/general/general_preview.png', triggers=self.makePreview)
self.liveAction = create_widget_action(self.menu,
text=translate('OpenLP.ServiceManager', 'Show &Live'),
icon=u':/general/general_live.png', triggers=self.makeLive)
self.menu.addSeparator()
self.themeMenu = QtGui.QMenu(
translate('OpenLP.ServiceManager', '&Change Item Theme'))
self.menu.addMenu(self.themeMenu)
@ -683,7 +660,7 @@ class ServiceManager(QtGui.QWidget):
'File is not a valid service.\n'
'The content encoding is not UTF-8.'))
continue
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
osfile = ucsfile.replace(u'/', os.path.sep)
if not osfile.startswith(u'audio'):
osfile = os.path.split(osfile)[1]
log.debug(u'Extract file: %s', osfile)
@ -1143,12 +1120,9 @@ class ServiceManager(QtGui.QWidget):
sure the theme combo box is in the correct state.
"""
log.debug(u'themeChange')
if self.mainwindow.renderer.theme_level == ThemeLevel.Global:
self.toolbar.actions[u'ThemeLabel'].setVisible(False)
self.toolbar.actions[u'ThemeWidget'].setVisible(False)
else:
self.toolbar.actions[u'ThemeLabel'].setVisible(True)
self.toolbar.actions[u'ThemeWidget'].setVisible(True)
visible = self.mainwindow.renderer.theme_level == ThemeLevel.Global
self.themeLabel.setVisible(visible)
self.themeComboBox.setVisible(visible)
def regenerateServiceItems(self):
"""
@ -1450,19 +1424,16 @@ class ServiceManager(QtGui.QWidget):
themeGroup.setObjectName(u'themeGroup')
# Create a "Default" theme, which allows the user to reset the item's
# theme to the service theme or global theme.
defaultTheme = context_menu_action(self.themeMenu, None,
UiStrings().Default, self.onThemeChangeAction)
defaultTheme.setCheckable(True)
defaultTheme = create_widget_action(self.themeMenu,
text=UiStrings().Default, checked=False,
triggers=self.onThemeChangeAction)
self.themeMenu.setDefaultAction(defaultTheme)
themeGroup.addAction(defaultTheme)
context_menu_separator(self.themeMenu)
self.themeMenu.addSeparator()
for theme in theme_list:
self.themeComboBox.addItem(theme)
themeAction = context_menu_action(self.themeMenu, None, theme,
self.onThemeChangeAction)
themeAction.setObjectName(theme)
themeAction.setCheckable(True)
themeGroup.addAction(themeAction)
themeGroup.addAction(create_widget_action(self.themeMenu, theme,
text=theme, checked=False, triggers=self.onThemeChangeAction))
find_and_set_in_combo_box(self.themeComboBox, self.service_theme)
self.mainwindow.renderer.set_service_theme(self.service_theme)
self.regenerateServiceItems()

View File

@ -34,7 +34,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \
translate, build_icon, build_html, PluginManager, ServiceItem
from openlp.core.lib.ui import UiStrings, shortcut_action
from openlp.core.lib.ui import UiStrings, create_action
from openlp.core.lib import SlideLimits, ServiceItemAction
from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList
from openlp.core.utils.actions import ActionList, CategoryOrder
@ -92,16 +92,14 @@ class SlideController(Controller):
self.imageManager = self.parent().imageManager
self.mediaController = self.parent().mediaController
self.loopList = [
u'Play Slides Menu',
u'Loop Separator',
u'Image SpinBox'
u'playSlidesMenu',
u'loopSeparator',
u'delaySpinBox'
]
self.songEditList = [
u'Edit Song',
]
self.nextPreviousList = [
u'Previous Slide',
u'Next Slide'
self.audioList = [
u'songMenu',
u'audioPauseItem',
u'audioTimeLabel'
]
self.timer_id = 0
self.songEdit = False
@ -123,10 +121,14 @@ class SlideController(Controller):
self.typePrefix = u'live'
self.keypress_queue = deque()
self.keypress_loop = False
self.category = UiStrings().LiveToolbar
ActionList.get_instance().add_category(
unicode(self.category), CategoryOrder.standardToolbar)
else:
self.typeLabel.setText(UiStrings().Preview)
self.split = 0
self.typePrefix = u'preview'
self.category = None
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
self.panelLayout.addWidget(self.typeLabel)
@ -169,72 +171,71 @@ class SlideController(Controller):
sizeToolbarPolicy.setHeightForWidth(
self.toolbar.sizePolicy().hasHeightForWidth())
self.toolbar.setSizePolicy(sizeToolbarPolicy)
self.previousItem = self.toolbar.addToolbarButton(
u'Previous Slide',
u':/slides/slide_previous.png',
translate('OpenLP.SlideController', 'Move to previous.'),
self.onSlideSelectedPrevious,
self.previousItem = create_action(self,
u'previousItem_' + self.typePrefix,
text=translate('OpenLP.SlideController', 'Previous Slide'),
icon=u':/slides/slide_previous.png',
tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp],
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.nextItem = self.toolbar.addToolbarButton(
u'Next Slide',
u':/slides/slide_next.png',
translate('OpenLP.SlideController', 'Move to next.'),
self.onSlideSelectedNext,
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.onSlideSelectedPrevious)
self.toolbar.addAction(self.previousItem)
self.nextItem = create_action(self, u'nextItem_' + self.typePrefix,
text=translate('OpenLP.SlideController', 'Next Slide'),
icon=u':/slides/slide_next.png',
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown],
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.toolbar.addToolbarSeparator(u'Close Separator')
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.onSlideSelectedNext)
self.toolbar.addAction(self.nextItem)
self.toolbar.addSeparator()
if self.isLive:
# Hide Menu
self.hideMenu = QtGui.QToolButton(self.toolbar)
self.hideMenu.setObjectName(u'hideMenu')
self.hideMenu.setText(translate('OpenLP.SlideController', 'Hide'))
self.hideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.toolbar.addToolbarWidget(u'Hide Menu', self.hideMenu)
self.hideMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Hide'), self.toolbar))
self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen',
[QtCore.Qt.Key_Period], self.onBlankDisplay,
u':/slides/slide_blank.png', False,
unicode(UiStrings().LiveToolbar))
self.blankScreen.setText(
translate('OpenLP.SlideController', 'Blank Screen'))
self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen',
[QtGui.QKeySequence(u'T')], self.onThemeDisplay,
u':/slides/slide_theme.png', False,
unicode(UiStrings().LiveToolbar))
self.themeScreen.setText(
translate('OpenLP.SlideController', 'Blank to Theme'))
self.desktopScreen = shortcut_action(self.hideMenu,
u'desktopScreen', [QtGui.QKeySequence(u'D')],
self.onHideDisplay, u':/slides/slide_desktop.png', False,
unicode(UiStrings().LiveToolbar))
self.desktopScreen.setText(
translate('OpenLP.SlideController', 'Show Desktop'))
self.toolbar.addToolbarWidget(self.hideMenu)
self.blankScreen = create_action(self, u'blankScreen',
text=translate('OpenLP.SlideController', 'Blank Screen'),
icon=u':/slides/slide_blank.png', checked=False,
shortcuts=[QtCore.Qt.Key_Period],
category=self.category, triggers=self.onBlankDisplay)
self.themeScreen = create_action(self, u'themeScreen',
text=translate('OpenLP.SlideController', 'Blank to Theme'),
icon=u':/slides/slide_theme.png', checked=False,
shortcuts=[QtGui.QKeySequence(u'T')],
category=self.category, triggers=self.onThemeDisplay)
self.desktopScreen = create_action(self, u'desktopScreen',
text=translate('OpenLP.SlideController', 'Show Desktop'),
icon=u':/slides/slide_desktop.png', checked=False,
shortcuts=[QtGui.QKeySequence(u'D')],
category=self.category, triggers=self.onHideDisplay)
self.hideMenu.setDefaultAction(self.blankScreen)
self.hideMenu.menu().addAction(self.blankScreen)
self.hideMenu.menu().addAction(self.themeScreen)
self.hideMenu.menu().addAction(self.desktopScreen)
self.toolbar.addToolbarSeparator(u'Loop Separator')
self.toolbar.addToolbarAction(u'loopSeparator', separator=True)
# Play Slides Menu
self.playSlidesMenu = QtGui.QToolButton(self.toolbar)
self.playSlidesMenu.setObjectName(u'playSlidesMenu')
self.playSlidesMenu.setText(translate('OpenLP.SlideController',
'Play Slides'))
self.playSlidesMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.toolbar.addToolbarWidget(u'Play Slides Menu',
self.playSlidesMenu)
self.playSlidesMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Play Slides'),
self.toolbar))
self.playSlidesLoop = shortcut_action(self.playSlidesMenu,
u'playSlidesLoop', [], self.onPlaySlidesLoop,
u':/media/media_time.png', False,
unicode(UiStrings().LiveToolbar))
self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop)
self.playSlidesOnce = shortcut_action(self.playSlidesMenu,
u'playSlidesOnce', [], self.onPlaySlidesOnce,
u':/media/media_time.png', False,
unicode(UiStrings().LiveToolbar))
self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
self.toolbar.addToolbarWidget(self.playSlidesMenu)
self.playSlidesLoop = create_action(self, u'playSlidesLoop',
text=UiStrings().PlaySlidesInLoop,
icon=u':/media/media_time.png', checked=False, shortcuts=[],
category=self.category, triggers=self.onPlaySlidesLoop)
self.playSlidesOnce = create_action(self, u'playSlidesOnce',
text=UiStrings().PlaySlidesToEnd,
icon=u':/media/media_time.png', checked=False, shortcuts=[],
category=self.category, triggers=self.onPlaySlidesOnce)
if QtCore.QSettings().value(self.parent().generalSettingsSection +
u'/enable slide loop', QtCore.QVariant(True)).toBool():
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
@ -244,65 +245,60 @@ class SlideController(Controller):
self.playSlidesMenu.menu().addAction(self.playSlidesOnce)
# Loop Delay Spinbox
self.delaySpinBox = QtGui.QSpinBox()
self.delaySpinBox.setObjectName(u'delaySpinBox')
self.delaySpinBox.setRange(1, 180)
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
self.delaySpinBox.setSuffix(UiStrings().Seconds)
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
'Delay between slides in seconds.'))
self.toolbar.addToolbarWidget(self.delaySpinBox)
else:
self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Go Live', u':/general/general_live.png',
translate('OpenLP.SlideController', 'Move to live.'),
self.onGoLive)
self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Add to Service', u':/general/general_add.png',
translate('OpenLP.SlideController', 'Add to Service.'),
self.onPreviewAddToService)
self.toolbar.addToolbarSeparator(u'Close Separator')
self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Edit Song', u':/general/general_edit.png',
translate('OpenLP.SlideController',
'Edit and reload song preview.'),
self.onEditSong)
self.toolbar.addToolbarAction(u'goLive',
icon=u':/general/general_live.png',
tooltip=translate('OpenLP.SlideController', 'Move to live.'),
triggers=self.onGoLive)
self.toolbar.addToolbarAction(u'addToService',
icon=u':/general/general_add.png',
tooltip=translate('OpenLP.SlideController', 'Add to Service.'),
triggers=self.onPreviewAddToService)
self.toolbar.addSeparator()
self.toolbar.addToolbarAction(u'editSong',
icon=u':/general/general_edit.png',
tooltip=translate('OpenLP.SlideController',
'Edit and reload song preview.'), triggers=self.onEditSong)
self.controllerLayout.addWidget(self.toolbar)
# Build the Media Toolbar
self.mediaController.add_controller_items(self, self.controllerLayout)
if self.isLive:
# Build the Song Toolbar
self.songMenu = QtGui.QToolButton(self.toolbar)
self.songMenu.setObjectName(u'songMenu')
self.songMenu.setText(translate('OpenLP.SlideController', 'Go To'))
self.songMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
self.toolbar.addToolbarWidget(u'Song Menu', self.songMenu)
self.songMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Go To'), self.toolbar))
self.toolbar.addToolbarWidget(self.songMenu)
# Stuff for items with background audio.
self.audioPauseItem = QtGui.QToolButton(self.toolbar)
self.audioPauseItem.setIcon(
QtGui.QIcon(u':/slides/media_playback_pause.png'))
self.audioPauseItem.setText(translate('OpenLP.SlideController',
'Pause audio.'))
self.audioPauseItem.setCheckable(True)
self.toolbar.addToolbarWidget(u'Pause Audio', self.audioPauseItem)
QtCore.QObject.connect(self.audioPauseItem,
QtCore.SIGNAL(u'clicked(bool)'), self.onAudioPauseClicked)
self.audioPauseItem.setVisible(False)
self.audioPauseItem = self.toolbar.addToolbarAction(
u'audioPauseItem', icon=u':/slides/media_playback_pause.png',
text=translate('OpenLP.SlideController', 'Pause Audio'),
tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
checked=False, visible=False, category=self.category,
triggers=self.onAudioPauseClicked)
self.audioMenu = QtGui.QMenu(
translate('OpenLP.SlideController', 'Background Audio'),
self.toolbar)
self.nextTrackItem = shortcut_action(self.audioMenu,
u'nextTrackItem', [], self.onNextTrackClicked,
u':/slides/media_playback_next.png',
category=unicode(UiStrings().LiveToolbar))
self.nextTrackItem.setText(
translate('OpenLP.SlideController', 'Next Track'))
translate('OpenLP.SlideController', 'Background Audio'), self)
self.audioPauseItem.setMenu(self.audioMenu)
self.audioPauseItem.setParent(self)
self.toolbar.widgetForAction(self.audioPauseItem).setPopupMode(
QtGui.QToolButton.MenuButtonPopup)
self.nextTrackItem = create_action(self, u'nextTrackItem',
text=translate('OpenLP.SlideController', 'Next Track'),
icon=u':/slides/media_playback_next.png', tooltip=translate(
'OpenLP.SlideController', 'Go to next audio track.'),
category=self.category, context=QtCore.Qt.WindowShortcut,
triggers=self.onNextTrackClicked)
self.audioMenu.addAction(self.nextTrackItem)
self.trackMenu = self.audioMenu.addMenu(
translate('OpenLP.SlideController', 'Tracks'))
self.audioPauseItem.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.audioPauseItem.setMenu(self.audioMenu)
self.audioTimeLabel = QtGui.QLabel(u' 00:00 ', self.toolbar)
self.audioTimeLabel.setAlignment(
QtCore.Qt.AlignCenter|QtCore.Qt.AlignHCenter)
@ -316,10 +312,8 @@ class SlideController(Controller):
u'border-width: 1; font-family: monospace; margin: 2px;'
)
self.audioTimeLabel.setObjectName(u'audioTimeLabel')
self.toolbar.addToolbarWidget(
u'Time Remaining', self.audioTimeLabel)
self.toolbar.makeWidgetsInvisible([u'Song Menu', u'Pause Audio',
u'Time Remaining'])
self.toolbar.addToolbarWidget(self.audioTimeLabel)
self.toolbar.setWidgetVisible(self.audioList, False)
# Screen preview area
self.previewFrame = QtGui.QFrame(self.splitter)
self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio))
@ -364,89 +358,31 @@ class SlideController(Controller):
self.shortcutTimer = QtCore.QTimer()
self.shortcutTimer.setObjectName(u'shortcutTimer')
self.shortcutTimer.setSingleShot(True)
self.verseShortcut = shortcut_action(self, u'verseShortcut',
[QtGui.QKeySequence(u'V')], self.slideShortcutActivated,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.verseShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Verse"'))
self.shortcut0 = shortcut_action(self, u'0',
[QtGui.QKeySequence(u'0')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.shortcut1 = shortcut_action(self, u'1',
[QtGui.QKeySequence(u'1')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.shortcut2 = shortcut_action(self, u'2',
[QtGui.QKeySequence(u'2')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.shortcut3 = shortcut_action(self, u'3',
[QtGui.QKeySequence(u'3')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.shortcut4 = shortcut_action(self, u'4',
[QtGui.QKeySequence(u'4')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.shortcut5 = shortcut_action(self, u'5',
[QtGui.QKeySequence(u'5')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.shortcut6 = shortcut_action(self, u'6',
[QtGui.QKeySequence(u'6')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.shortcut7 = shortcut_action(self, u'7',
[QtGui.QKeySequence(u'7')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.shortcut8 = shortcut_action(self, u'8',
[QtGui.QKeySequence(u'8')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.shortcut9 = shortcut_action(self, u'9',
[QtGui.QKeySequence(u'9')], self.slideShortcutActivated,
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.chorusShortcut = shortcut_action(self, u'chorusShortcut',
[QtGui.QKeySequence(u'C')], self.slideShortcutActivated,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.chorusShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Chorus"'))
self.bridgeShortcut = shortcut_action(self, u'bridgeShortcut',
[QtGui.QKeySequence(u'B')], self.slideShortcutActivated,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.bridgeShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Bridge"'))
self.preChorusShortcut = shortcut_action(self, u'preChorusShortcut',
[QtGui.QKeySequence(u'P')], self.slideShortcutActivated,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.preChorusShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Pre-Chorus"'))
self.introShortcut = shortcut_action(self, u'introShortcut',
[QtGui.QKeySequence(u'I')], self.slideShortcutActivated,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.introShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Intro"'))
self.endingShortcut = shortcut_action(self, u'endingShortcut',
[QtGui.QKeySequence(u'E')], self.slideShortcutActivated,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.endingShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Ending"'))
self.otherShortcut = shortcut_action(self, u'otherShortcut',
[QtGui.QKeySequence(u'O')], self.slideShortcutActivated,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.otherShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Other"'))
self.previewListWidget.addActions([
self.shortcut0, self.shortcut1, self.shortcut2, self.shortcut3,
self.shortcut4, self.shortcut5, self.shortcut6, self.shortcut7,
self.shortcut8, self.shortcut9, self.verseShortcut,
self.chorusShortcut, self.bridgeShortcut,
self.preChorusShortcut, self.introShortcut, self.endingShortcut,
self.otherShortcut
])
shortcuts = [{u'key': u'V', u'configurable': True,
u'text': translate('OpenLP.SlideController', 'Go to "Verse"')},
{u'key': u'C', u'configurable': True,
u'text': translate('OpenLP.SlideController', 'Go to "Chorus"')},
{u'key': u'B', u'configurable': True,
u'text': translate('OpenLP.SlideController', 'Go to "Bridge"')},
{u'key': u'P', u'configurable': True,
u'text': translate('OpenLP.SlideController',
'Go to "Pre-Chorus"')},
{u'key': u'I', u'configurable': True,
u'text': translate('OpenLP.SlideController', 'Go to "Intro"')},
{u'key': u'E', u'configurable': True,
u'text': translate('OpenLP.SlideController', 'Go to "Ending"')},
{u'key': u'O', u'configurable': True,
u'text': translate('OpenLP.SlideController', 'Go to "Other"')}]
shortcuts += [{u'key': unicode(number)} for number in range(0, 10)]
self.previewListWidget.addActions([create_action(self,
u'shortcutAction_%s' % s[u'key'], text=s.get(u'text'),
shortcuts=[QtGui.QKeySequence(s[u'key'])],
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category if s.get(u'configurable') else None,
triggers=self._slideShortcutActivated) for s in shortcuts])
QtCore.QObject.connect(
self.shortcutTimer, QtCore.SIGNAL(u'timeout()'),
self.slideShortcutActivated)
self._slideShortcutActivated)
# Signals
QtCore.QObject.connect(self.previewListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
@ -457,20 +393,18 @@ class SlideController(Controller):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_toggle_display'),
self.toggleDisplay)
self.toolbar.makeWidgetsInvisible(self.loopList)
self.toolbar.setWidgetVisible(self.loopList, False)
else:
QtCore.QObject.connect(self.previewListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onGoLiveClick)
self.toolbar.makeWidgetsInvisible(self.songEditList)
self.toolbar.setWidgetVisible([u'editSong'], False)
if self.isLive:
self.setLiveHotkeys(self)
self.__addActionsToWidget(self.previewListWidget)
else:
self.setPreviewHotkeys()
self.previewListWidget.addActions(
[self.nextItem,
self.previousItem])
[self.nextItem, self.previousItem])
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix),
self.onStopLoop)
@ -496,7 +430,7 @@ class SlideController(Controller):
QtCore.SIGNAL(u'slidecontroller_update_slide_limits'),
self.updateSlideLimits)
def slideShortcutActivated(self):
def _slideShortcutActivated(self):
"""
Called, when a shortcut has been activated to jump to a chorus, verse,
etc.
@ -512,52 +446,38 @@ class SlideController(Controller):
SONGS_PLUGIN_AVAILABLE = True
except ImportError:
SONGS_PLUGIN_AVAILABLE = False
verse_type = unicode(self.sender().objectName())
if verse_type.startswith(u'verseShortcut'):
if SONGS_PLUGIN_AVAILABLE:
sender_name = unicode(self.sender().objectName())
verse_type = sender_name[15:] \
if sender_name[:15] == u'shortcutAction_' else u''
if SONGS_PLUGIN_AVAILABLE:
if verse_type == u'V':
self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Verse]
else:
self.current_shortcut = u'V'
elif verse_type.startswith(u'chorusShortcut'):
if SONGS_PLUGIN_AVAILABLE:
elif verse_type == u'C':
self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Chorus]
else:
self.current_shortcut = u'C'
elif verse_type.startswith(u'bridgeShortcut'):
if SONGS_PLUGIN_AVAILABLE:
elif verse_type == u'B':
self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Bridge]
else:
self.current_shortcut = u'B'
elif verse_type.startswith(u'preChorusShortcut'):
if SONGS_PLUGIN_AVAILABLE:
elif verse_type == u'P':
self.current_shortcut = \
VerseType.TranslatedTags[VerseType.PreChorus]
else:
self.current_shortcut = u'P'
elif verse_type.startswith(u'introShortcut'):
if SONGS_PLUGIN_AVAILABLE:
elif verse_type == u'I':
self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Intro]
else:
self.current_shortcut = u'I'
elif verse_type.startswith(u'endingShortcut'):
if SONGS_PLUGIN_AVAILABLE:
elif verse_type == u'E':
self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Ending]
else:
self.current_shortcut = u'E'
elif verse_type.startswith(u'otherShortcut'):
if SONGS_PLUGIN_AVAILABLE:
elif verse_type == u'O':
self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Other]
else:
self.current_shortcut = u'O'
elif verse_type.isnumeric():
self.current_shortcut += verse_type
self.current_shortcut = self.current_shortcut.upper()
elif verse_type.isnumeric():
self.current_shortcut += verse_type
self.current_shortcut = self.current_shortcut.upper()
elif verse_type:
self.current_shortcut = verse_type
keys = self.slideList.keys()
matches = [match for match in keys
if match.startswith(self.current_shortcut)]
@ -566,7 +486,7 @@ class SlideController(Controller):
self.current_shortcut = u''
self.__checkUpdateSelectedSlide(self.slideList[matches[0]])
self.slideSelected()
elif verse_type != u'shortcutTimer':
elif sender_name != u'shortcutTimer':
# Start the time as we did not have any match.
self.shortcutTimer.start(350)
else:
@ -580,39 +500,22 @@ class SlideController(Controller):
# Reset the shortcut.
self.current_shortcut = u''
def setPreviewHotkeys(self):
self.previousItem.setObjectName(u'previousItemPreview')
self.nextItem.setObjectName(u'nextItemPreview')
action_list = ActionList.get_instance()
action_list.add_action(self.previousItem)
action_list.add_action(self.nextItem)
def setLiveHotkeys(self, parent=None):
self.previousItem.setObjectName(u'previousItemLive')
self.nextItem.setObjectName(u'nextItemLive')
action_list = ActionList.get_instance()
action_list.add_category(
unicode(UiStrings().LiveToolbar), CategoryOrder.standardToolbar)
action_list.add_action(self.previousItem)
action_list.add_action(self.nextItem)
self.previousService = shortcut_action(parent, u'previousService',
[QtCore.Qt.Key_Left], self.servicePrevious,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.previousService.setText(
translate('OpenLP.SlideController', 'Previous Service'))
self.nextService = shortcut_action(parent, 'nextService',
[QtCore.Qt.Key_Right], self.serviceNext,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.nextService.setText(
translate('OpenLP.SlideController', 'Next Service'))
self.escapeItem = shortcut_action(parent, 'escapeItem',
[QtCore.Qt.Key_Escape], self.liveEscape,
category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.escapeItem.setText(
translate('OpenLP.SlideController', 'Escape Item'))
self.previousService = create_action(parent, u'previousService',
text=translate('OpenLP.SlideController', 'Previous Service'),
shortcuts=[QtCore.Qt.Key_Left],
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.servicePrevious)
self.nextService = create_action(parent, 'nextService',
text=translate('OpenLP.SlideController', 'Next Service'),
shortcuts=[QtCore.Qt.Key_Right],
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.serviceNext)
self.escapeItem = create_action(parent, 'escapeItem',
text=translate('OpenLP.SlideController', 'Escape Item'),
shortcuts=[QtCore.Qt.Key_Escape],
context=QtCore.Qt.WidgetWithChildrenShortcut,
category=self.category, triggers=self.liveEscape)
def liveEscape(self):
self.display.setVisible(False)
@ -779,9 +682,9 @@ class SlideController(Controller):
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.hide()
self.mediabar.setVisible(False)
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
self.toolbar.makeWidgetsInvisible(self.loopList)
self.mediabar.hide()
self.songMenu.hide()
self.toolbar.setWidgetVisible(self.loopList, False)
# Reset the button
self.playSlidesOnce.setChecked(False)
self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png'))
@ -791,17 +694,16 @@ class SlideController(Controller):
if QtCore.QSettings().value(
self.parent().songsSettingsSection + u'/display songbar',
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
self.toolbar.makeWidgetsVisible([u'Song Menu'])
self.songMenu.show()
if item.is_capable(ItemCapabilities.CanLoop) and \
len(item.get_frames()) > 1:
self.toolbar.makeWidgetsVisible(self.loopList)
self.toolbar.setWidgetVisible(self.loopList)
if item.is_media():
self.mediabar.setVisible(True)
self.toolbar.makeWidgetsInvisible(self.nextPreviousList)
else:
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.makeWidgetsVisible(self.nextPreviousList)
self.mediabar.show()
self.previousItem.setVisible(not item.is_media())
self.nextItem.setVisible(not item.is_media())
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.show()
def enablePreviewToolBar(self, item):
@ -811,17 +713,16 @@ class SlideController(Controller):
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.hide()
self.mediabar.setVisible(False)
self.toolbar.makeWidgetsInvisible(self.songEditList)
self.mediabar.hide()
self.toolbar.setWidgetVisible([u'editSong'], False)
if item.is_capable(ItemCapabilities.CanEdit) and item.from_plugin:
self.toolbar.makeWidgetsVisible(self.songEditList)
self.toolbar.setWidgetVisible([u'editSong'])
elif item.is_media():
self.mediabar.setVisible(True)
self.toolbar.makeWidgetsInvisible(self.nextPreviousList)
if not item.is_media():
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.makeWidgetsVisible(self.nextPreviousList)
self.mediabar.show()
self.previousItem.setVisible(not item.is_media())
self.nextItem.setVisible(not item.is_media())
# Work-around for OS X, hide and then show the toolbar
# See bug #791050
self.toolbar.show()
def refreshServiceItem(self):
@ -966,7 +867,7 @@ class SlideController(Controller):
self.slideList[unicode(row)] = row - 1
text.append(unicode(row))
self.previewListWidget.setItem(framenumber, 0, item)
if not slideHeight:
if slideHeight:
self.previewListWidget.setRowHeight(framenumber, slideHeight)
self.previewListWidget.setVerticalHeaderLabels(text)
if self.serviceItem.is_text():
@ -1181,7 +1082,7 @@ class SlideController(Controller):
"""
row = self.previewListWidget.currentRow()
self.selectedRow = 0
if row > -1 and row < self.previewListWidget.rowCount():
if -1 < row < self.previewListWidget.rowCount():
if self.serviceItem.is_command():
if self.isLive and not start:
Receiver.send_message(
@ -1317,7 +1218,7 @@ class SlideController(Controller):
"""
Stop the timer loop running
"""
if self.timer_id != 0:
if self.timer_id:
self.killTimer(self.timer_id)
self.timer_id = 0
@ -1364,12 +1265,7 @@ class SlideController(Controller):
self.onToggleLoop()
def setAudioItemsVisibility(self, visible):
if visible:
self.toolbar.makeWidgetsVisible(
[u'Song Menu', u'Pause Audio', u'Time Remaining'])
else:
self.toolbar.makeWidgetsInvisible(
[u'Song Menu', u'Pause Audio', u'Time Remaining'])
self.toolbar.setWidgetVisible(self.audioList, visible)
def onAudioPauseClicked(self, checked):
if not self.audioPauseItem.isVisible():
@ -1423,7 +1319,7 @@ class SlideController(Controller):
If preview copy slide item to live
"""
row = self.previewListWidget.currentRow()
if row > -1 and row < self.previewListWidget.rowCount():
if -1 < row < self.previewListWidget.rowCount():
if self.serviceItem.from_service:
Receiver.send_message('servicemanager_preview_live',
u'%s:%s' % (self.serviceItem._uuid, row))

View File

@ -41,7 +41,7 @@ from openlp.core.lib import OpenLPToolbar, get_text_file_string, build_icon, \
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \
BackgroundGradientType
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
context_menu_action, context_menu_separator
create_widget_action
from openlp.core.theme import Theme
from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding
@ -64,32 +64,32 @@ class ThemeManager(QtGui.QWidget):
self.layout.setMargin(0)
self.layout.setObjectName(u'layout')
self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton(UiStrings().NewTheme,
u':/themes/theme_new.png',
translate('OpenLP.ThemeManager', 'Create a new theme.'),
self.onAddTheme)
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Edit Theme'),
u':/themes/theme_edit.png',
translate('OpenLP.ThemeManager', 'Edit a theme.'),
self.onEditTheme)
self.deleteToolbarAction = self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Delete Theme'),
u':/general/general_delete.png',
translate('OpenLP.ThemeManager', 'Delete a theme.'),
self.onDeleteTheme)
self.toolbar.addSeparator()
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Import Theme'),
u':/general/general_import.png',
translate('OpenLP.ThemeManager', 'Import a theme.'),
self.onImportTheme)
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Export Theme'),
u':/general/general_export.png',
translate('OpenLP.ThemeManager', 'Export a theme.'),
self.onExportTheme)
self.toolbar.setObjectName(u'toolbar')
self.toolbar.addToolbarAction(u'newTheme',
text=UiStrings().NewTheme, icon=u':/themes/theme_new.png',
tooltip=translate('OpenLP.ThemeManager', 'Create a new theme.'),
triggers=self.onAddTheme)
self.toolbar.addToolbarAction(u'editTheme',
text=translate('OpenLP.ThemeManager', 'Edit Theme'),
icon=u':/themes/theme_edit.png',
tooltip=translate('OpenLP.ThemeManager', 'Edit a theme.'),
triggers=self.onEditTheme)
self.deleteToolbarAction = self.toolbar.addToolbarAction(u'deleteTheme',
text=translate('OpenLP.ThemeManager', 'Delete Theme'),
icon=u':/general/general_delete.png',
tooltip=translate('OpenLP.ThemeManager', 'Delete a theme.'),
triggers=self.onDeleteTheme)
self.toolbar.addSeparator()
self.toolbar.addToolbarAction(u'importTheme',
text=translate('OpenLP.ThemeManager', 'Import Theme'),
icon=u':/general/general_import.png',
tooltip=translate('OpenLP.ThemeManager', 'Import a theme.'),
triggers=self.onImportTheme)
self.toolbar.addToolbarAction(u'exportTheme',
text=translate('OpenLP.ThemeManager', 'Export Theme'),
icon=u':/general/general_export.png',
tooltip=translate('OpenLP.ThemeManager', 'Export a theme.'),
triggers=self.onExportTheme)
self.layout.addWidget(self.toolbar)
self.themeWidget = QtGui.QWidgetAction(self.toolbar)
self.themeWidget.setObjectName(u'themeWidget')
@ -105,29 +105,26 @@ class ThemeManager(QtGui.QWidget):
self.contextMenu)
# build the context menu
self.menu = QtGui.QMenu()
self.editAction = context_menu_action(
self.menu, u':/themes/theme_edit.png',
translate('OpenLP.ThemeManager', '&Edit Theme'), self.onEditTheme)
self.copyAction = context_menu_action(
self.menu, u':/themes/theme_edit.png',
translate('OpenLP.ThemeManager', '&Copy Theme'), self.onCopyTheme)
self.renameAction = context_menu_action(
self.menu, u':/themes/theme_edit.png',
translate('OpenLP.ThemeManager', '&Rename Theme'),
self.onRenameTheme)
self.deleteAction = context_menu_action(
self.menu, u':/general/general_delete.png',
translate('OpenLP.ThemeManager', '&Delete Theme'),
self.onDeleteTheme)
context_menu_separator(self.menu)
self.globalAction = context_menu_action(
self.menu, u':/general/general_export.png',
translate('OpenLP.ThemeManager', 'Set As &Global Default'),
self.changeGlobalFromScreen)
self.exportAction = context_menu_action(
self.menu, u':/general/general_export.png',
translate('OpenLP.ThemeManager', '&Export Theme'),
self.onExportTheme)
self.editAction = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Edit Theme'),
icon=u':/themes/theme_edit.png', triggers=self.onEditTheme)
self.copyAction = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Copy Theme'),
icon=u':/themes/theme_edit.png', triggers=self.onCopyTheme)
self.renameAction = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Rename Theme'),
icon=u':/themes/theme_edit.png', triggers=self.onRenameTheme)
self.deleteAction = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Delete Theme'),
icon=u':/general/general_delete.png', triggers=self.onDeleteTheme)
self.menu.addSeparator()
self.globalAction = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', 'Set As &Global Default'),
icon=u':/general/general_export.png',
triggers=self.changeGlobalFromScreen)
self.exportAction = create_widget_action(self.menu,
text=translate('OpenLP.ThemeManager', '&Export Theme'),
icon=u':/general/general_export.png', triggers=self.onExportTheme)
# Signals
QtCore.QObject.connect(self.themeListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
@ -140,13 +137,13 @@ class ThemeManager(QtGui.QWidget):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configUpdated)
# Variables
self.themelist = []
self.theme_list = []
self.path = AppLocation.get_section_data_path(self.settingsSection)
check_directory_exists(self.path)
self.thumbPath = os.path.join(self.path, u'thumbnails')
check_directory_exists(self.thumbPath)
self.thumb_path = os.path.join(self.path, u'thumbnails')
check_directory_exists(self.thumb_path)
self.themeForm.path = self.path
self.oldBackgroundImage = None
self.old_background_image = None
self.bad_v1_name_chars = re.compile(r'[%+\[\]]')
# Last little bits of setting up
self.configUpdated()
@ -159,7 +156,7 @@ class ThemeManager(QtGui.QWidget):
encoding = get_filesystem_encoding()
files = SettingsManager.get_files(self.settingsSection, u'.otz')
for file in files:
file = os.path.join(self.path, file).encode(encoding)
file = os.path.join(self.path, file)
self.unzipTheme(file, self.path)
delete_file(file)
Receiver.send_message(u'cursor_normal')
@ -178,10 +175,10 @@ class ThemeManager(QtGui.QWidget):
"""
if item is None:
return
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
themeName = unicode(item.text())
real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
theme_name = unicode(item.text())
# If default theme restrict actions
if realThemeName == themeName:
if real_theme_name == theme_name:
self.deleteToolbarAction.setVisible(True)
else:
self.deleteToolbarAction.setVisible(False)
@ -194,35 +191,35 @@ class ThemeManager(QtGui.QWidget):
item = self.themeListWidget.itemAt(point)
if item is None:
return
realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
themeName = unicode(item.text())
real_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
theme_name = unicode(item.text())
self.deleteAction.setVisible(False)
self.renameAction.setVisible(False)
self.globalAction.setVisible(False)
# If default theme restrict actions
if realThemeName == themeName:
if real_theme_name == theme_name:
self.deleteAction.setVisible(True)
self.renameAction.setVisible(True)
self.globalAction.setVisible(True)
self.menu.exec_(self.themeListWidget.mapToGlobal(point))
def changeGlobalFromTab(self, themeName):
def changeGlobalFromTab(self, theme_name):
"""
Change the global theme when it is changed through the Themes settings
tab
"""
log.debug(u'changeGlobalFromTab %s', themeName)
log.debug(u'changeGlobalFromTab %s', theme_name)
for count in range (0, self.themeListWidget.count()):
# reset the old name
item = self.themeListWidget.item(count)
oldName = item.text()
newName = unicode(item.data(QtCore.Qt.UserRole).toString())
if oldName != newName:
self.themeListWidget.item(count).setText(newName)
old_name = item.text()
new_name = unicode(item.data(QtCore.Qt.UserRole).toString())
if old_name != new_name:
self.themeListWidget.item(count).setText(new_name)
# Set the new name
if themeName == newName:
if theme_name == new_name:
name = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % newName
'%s (default)')) % new_name
self.themeListWidget.item(count).setText(name)
def changeGlobalFromScreen(self, index=-1):
@ -234,9 +231,9 @@ class ThemeManager(QtGui.QWidget):
selected_row = self.themeListWidget.currentRow()
for count in range (0, self.themeListWidget.count()):
item = self.themeListWidget.item(count)
oldName = item.text()
old_name = item.text()
# reset the old name
if oldName != unicode(item.data(QtCore.Qt.UserRole).toString()):
if old_name != unicode(item.data(QtCore.Qt.UserRole).toString()):
self.themeListWidget.item(count).setText(
unicode(item.data(QtCore.Qt.UserRole).toString()))
# Set the new name
@ -272,19 +269,19 @@ class ThemeManager(QtGui.QWidget):
unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')),
False, False):
item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(oldThemeName)
old_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(old_theme_name)
if self.fileRenameForm.exec_():
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
if oldThemeName == newThemeName:
new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
if old_theme_name == new_theme_name:
return
if self.checkIfThemeExists(newThemeName):
oldThemeData = self.getThemeData(oldThemeName)
self.cloneThemeData(oldThemeData, newThemeName)
self.deleteTheme(oldThemeName)
if self.checkIfThemeExists(new_theme_name):
old_theme_data = self.getThemeData(old_theme_name)
self.cloneThemeData(old_theme_data, new_theme_name)
self.deleteTheme(old_theme_name)
for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(oldThemeName):
plugin.renameTheme(oldThemeName, newThemeName)
if plugin.usesTheme(old_theme_name):
plugin.renameTheme(old_theme_name, new_theme_name)
self.loadThemes()
def onCopyTheme(self):
@ -292,30 +289,30 @@ class ThemeManager(QtGui.QWidget):
Copies an existing theme to a new name
"""
item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
old_theme_name = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(
unicode(translate('OpenLP.ThemeManager',
'Copy of %s','Copy of <theme name>')) % oldThemeName)
'Copy of %s', 'Copy of <theme name>')) % old_theme_name)
if self.fileRenameForm.exec_(True):
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
if self.checkIfThemeExists(newThemeName):
themeData = self.getThemeData(oldThemeName)
self.cloneThemeData(themeData, newThemeName)
new_theme_name = unicode(self.fileRenameForm.fileNameEdit.text())
if self.checkIfThemeExists(new_theme_name):
theme_data = self.getThemeData(old_theme_name)
self.cloneThemeData(theme_data, new_theme_name)
def cloneThemeData(self, themeData, newThemeName):
def cloneThemeData(self, theme_data, new_theme_name):
"""
Takes a theme and makes a new copy of it as well as saving it.
"""
log.debug(u'cloneThemeData')
saveTo = None
saveFrom = None
if themeData.background_type == u'image':
saveTo = os.path.join(self.path, newThemeName,
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)
save_to = None
save_from = None
if theme_data.background_type == u'image':
save_to = os.path.join(self.path, new_theme_name,
os.path.split(unicode(theme_data.background_filename))[1])
save_from = theme_data.background_filename
theme_data.theme_name = new_theme_name
theme_data.extend_image_filename(self.path)
self.saveTheme(theme_data, save_from, save_to)
def onEditTheme(self):
"""
@ -329,10 +326,10 @@ class ThemeManager(QtGui.QWidget):
theme = self.getThemeData(
unicode(item.data(QtCore.Qt.UserRole).toString()))
if theme.background_type == u'image':
self.oldBackgroundImage = theme.background_filename
self.old_background_image = theme.background_filename
self.themeForm.theme = theme
self.themeForm.exec_(True)
self.oldBackgroundImage = None
self.old_background_image = None
def onDeleteTheme(self):
"""
@ -358,10 +355,10 @@ class ThemeManager(QtGui.QWidget):
``theme``
The theme to delete.
"""
self.themelist.remove(theme)
self.theme_list.remove(theme)
thumb = u'%s.png' % theme
delete_file(os.path.join(self.path, thumb))
delete_file(os.path.join(self.thumbPath, thumb))
delete_file(os.path.join(self.thumb_path, thumb))
try:
encoding = get_filesystem_encoding()
shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
@ -386,10 +383,10 @@ class ThemeManager(QtGui.QWidget):
Receiver.send_message(u'cursor_busy')
if path:
SettingsManager.set_last_dir(self.settingsSection, path, 1)
themePath = os.path.join(path, theme + u'.otz')
theme_path = os.path.join(path, theme + u'.otz')
zip = None
try:
zip = zipfile.ZipFile(themePath, u'w')
zip = zipfile.ZipFile(theme_path, u'w')
source = os.path.join(self.path, theme)
for files in os.walk(source):
for name in files[2]:
@ -439,9 +436,8 @@ class ThemeManager(QtGui.QWidget):
The plugins will call back in to get the real list if they want it.
"""
log.debug(u'Load themes from dir')
self.themelist = []
self.theme_list = []
self.themeListWidget.clear()
dirList = os.listdir(self.path)
files = SettingsManager.get_files(self.settingsSection, u'.png')
if firstTime:
self.firstTime()
@ -458,29 +454,29 @@ class ThemeManager(QtGui.QWidget):
files = SettingsManager.get_files(self.settingsSection, u'.png')
# Sort the themes by its name considering language specific characters.
# lower() is needed for windows!
files.sort(key=lambda filename: unicode(filename).lower(),
files.sort(key=lambda file_name: unicode(file_name).lower(),
cmp=locale.strcoll)
# now process the file list of png files
for name in files:
# check to see file is in theme root directory
theme = os.path.join(self.path, name)
if os.path.exists(theme):
textName = os.path.splitext(name)[0]
if textName == self.global_theme:
text_name = os.path.splitext(name)[0]
if text_name == self.global_theme:
name = unicode(translate('OpenLP.ThemeManager',
'%s (default)')) % textName
'%s (default)')) % text_name
else:
name = textName
thumb = os.path.join(self.thumbPath, u'%s.png' % textName)
name = text_name
thumb = os.path.join(self.thumb_path, u'%s.png' % text_name)
item_name = QtGui.QListWidgetItem(name)
if validate_thumb(theme, thumb):
icon = build_icon(thumb)
else:
icon = create_thumb(theme, thumb)
item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(textName))
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(text_name))
self.themeListWidget.addItem(item_name)
self.themelist.append(textName)
self.theme_list.append(text_name)
self._pushThemes()
def _pushThemes(self):
@ -493,50 +489,68 @@ class ThemeManager(QtGui.QWidget):
"""
Return the list of loaded themes
"""
return self.themelist
return self.theme_list
def getThemeData(self, themeName):
def getThemeData(self, theme_name):
"""
Returns a theme object from an XML file
``themeName``
``theme_name``
Name of the theme to load from file
"""
log.debug(u'getthemedata for theme %s', themeName)
xmlFile = os.path.join(self.path, unicode(themeName),
unicode(themeName) + u'.xml')
xml = get_text_file_string(xmlFile)
log.debug(u'getthemedata for theme %s', theme_name)
xml_file = os.path.join(self.path, unicode(theme_name),
unicode(theme_name) + u'.xml')
xml = get_text_file_string(xml_file)
if not xml:
log.debug("No theme data - using default theme")
return ThemeXML()
else:
return self._createThemeFromXml(xml, self.path)
def unzipTheme(self, filename, dir):
def overWriteMessageBox(self, theme_name):
ret = QtGui.QMessageBox.question(self,
translate('OpenLP.ThemeManager', 'Theme Already Exists'),
translate('OpenLP.ThemeManager',
'Theme %s already exists. Do you want to replace it?'
% theme_name),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
return ret == QtGui.QMessageBox.Yes
def unzipTheme(self, file_name, dir):
"""
Unzip the theme, remove the preview file if stored
Generate a new preview file. Check the XML theme version and upgrade if
necessary.
"""
log.debug(u'Unzipping theme %s', filename)
filename = unicode(filename)
log.debug(u'Unzipping theme %s', file_name)
file_name = unicode(file_name)
zip = None
outfile = None
filexml = None
out_file = None
file_xml = None
try:
zip = zipfile.ZipFile(filename)
xmlfile = filter(lambda name:
zip = zipfile.ZipFile(file_name)
xml_file = filter(lambda name:
os.path.splitext(name)[1].lower() == u'.xml', zip.namelist())
if len(xmlfile) != 1:
log.exception(u'Theme contains "%s" XML files' % len(xmlfile))
if len(xml_file) != 1:
log.exception(u'Theme contains "%s" XML files' % len(xml_file))
raise Exception(u'validation')
xml_tree = ElementTree(element=XML(zip.read(xmlfile[0]))).getroot()
xml_tree = ElementTree(element=XML(zip.read(xml_file[0]))).getroot()
v1_background = xml_tree.find(u'BackgroundType')
if v1_background is not None:
(themename, filexml, outfile) = self.unzipVersion122(dir, zip,
xmlfile[0], xml_tree, v1_background, outfile)
theme_name, file_xml, out_file, abort_import = self.unzipVersion122(dir, zip,
xml_file[0], xml_tree, v1_background, out_file)
else:
themename = xml_tree.find(u'name').text.strip()
theme_name = xml_tree.find(u'name').text.strip()
theme_folder = os.path.join(dir, theme_name)
theme_exists = os.path.exists(theme_folder)
if theme_exists and not self.overWriteMessageBox(theme_name):
abort_import = True
return
else:
abort_import = False
for name in zip.namelist():
try:
uname = unicode(name, u'utf-8')
@ -544,23 +558,23 @@ class ThemeManager(QtGui.QWidget):
log.exception(u'Theme file contains non utf-8 filename'
u' "%s"' % name.decode(u'utf-8', u'replace'))
raise Exception(u'validation')
uname = unicode(QtCore.QDir.toNativeSeparators(uname))
splitname = uname.split(os.path.sep)
if splitname[-1] == u'' or len(splitname) == 1:
uname = uname.replace(u'/', os.path.sep)
split_name = uname.split(os.path.sep)
if split_name[-1] == u'' or len(split_name) == 1:
# is directory or preview file
continue
fullname = os.path.join(dir, uname)
check_directory_exists(os.path.dirname(fullname))
full_name = os.path.join(dir, uname)
check_directory_exists(os.path.dirname(full_name))
if os.path.splitext(uname)[1].lower() == u'.xml':
filexml = unicode(zip.read(name), u'utf-8')
outfile = open(fullname, u'w')
outfile.write(filexml.encode(u'utf-8'))
file_xml = unicode(zip.read(name), u'utf-8')
out_file = open(full_name, u'w')
out_file.write(file_xml.encode(u'utf-8'))
else:
outfile = open(fullname, u'wb')
outfile.write(zip.read(name))
outfile.close()
out_file = open(full_name, u'wb')
out_file.write(zip.read(name))
out_file.close()
except (IOError, zipfile.BadZipfile):
log.exception(u'Importing theme from zip failed %s' % filename)
log.exception(u'Importing theme from zip failed %s' % file_name)
raise Exception(u'validation')
except Exception as info:
if unicode(info) == u'validation':
@ -573,60 +587,65 @@ class ThemeManager(QtGui.QWidget):
# Close the files, to be able to continue creating the theme.
if zip:
zip.close()
if outfile:
outfile.close()
# As all files are closed, we can create the Theme.
if filexml:
theme = self._createThemeFromXml(filexml, self.path)
self.generateAndSaveImage(dir, themename, theme)
# Only show the error message, when IOError was not raised (in this
# case the error message has already been shown).
elif zip is not None:
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)
if out_file:
out_file.close()
if not abort_import:
# As all files are closed, we can create the Theme.
if file_xml:
theme = self._createThemeFromXml(file_xml, self.path)
self.generateAndSaveImage(dir, theme_name, theme)
# Only show the error message, when IOError was not raised (in this
# case the error message has already been shown).
elif zip is not None:
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' %
file_name)
def unzipVersion122(self, dir, zip, xmlfile, xml_tree, background, outfile):
def unzipVersion122(self, dir, zip, xml_file, xml_tree, background, out_file):
"""
Unzip openlp.org 1.2x theme file and upgrade the theme xml. When calling
this method, please keep in mind, that some parameters are redundant.
"""
themename = xml_tree.find(u'Name').text.strip()
themename = self.bad_v1_name_chars.sub(u'', themename)
themedir = os.path.join(dir, themename)
theme_name = xml_tree.find(u'Name').text.strip()
theme_name = self.bad_v1_name_chars.sub(u'', theme_name)
theme_folder = os.path.join(dir, theme_name)
theme_exists = os.path.exists(theme_folder)
if theme_exists and not self.overWriteMessageBox(theme_name):
return '', '', '', True
themedir = os.path.join(dir, theme_name)
check_directory_exists(themedir)
filexml = unicode(zip.read(xmlfile), u'utf-8')
filexml = self._migrateVersion122(filexml)
outfile = open(os.path.join(themedir, themename + u'.xml'), u'w')
outfile.write(filexml.encode(u'utf-8'))
outfile.close()
file_xml = unicode(zip.read(xml_file), u'utf-8')
file_xml = self._migrateVersion122(file_xml)
out_file = open(os.path.join(themedir, theme_name + u'.xml'), u'w')
out_file.write(file_xml.encode(u'utf-8'))
out_file.close()
if background.text.strip() == u'2':
imagename = xml_tree.find(u'BackgroundParameter1').text.strip()
image_name = xml_tree.find(u'BackgroundParameter1').text.strip()
# image file has same extension and is in subfolder
imagefile = filter(lambda name: os.path.splitext(name)[1].lower()
== os.path.splitext(imagename)[1].lower() and name.find(r'/'),
== os.path.splitext(image_name)[1].lower() and name.find(r'/'),
zip.namelist())
if len(imagefile) >= 1:
outfile = open(os.path.join(themedir, imagename), u'wb')
outfile.write(zip.read(imagefile[0]))
outfile.close()
out_file = open(os.path.join(themedir, image_name), u'wb')
out_file.write(zip.read(imagefile[0]))
out_file.close()
else:
log.exception(u'Theme file does not contain image file "%s"' %
imagename.decode(u'utf-8', u'replace'))
image_name.decode(u'utf-8', u'replace'))
raise Exception(u'validation')
return (themename, filexml, outfile)
return theme_name, file_xml, out_file, False
def checkIfThemeExists(self, themeName):
def checkIfThemeExists(self, theme_name):
"""
Check if theme already exists and displays error message
``themeName``
``theme_name``
Name of the Theme to test
"""
theme_dir = os.path.join(self.path, themeName)
theme_dir = os.path.join(self.path, theme_name)
if os.path.exists(theme_dir):
critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'),
@ -635,12 +654,12 @@ class ThemeManager(QtGui.QWidget):
return False
return True
def saveTheme(self, theme, imageFrom, imageTo):
def saveTheme(self, theme, image_from, image_to):
"""
Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list
"""
self._writeTheme(theme, imageFrom, imageTo)
self._writeTheme(theme, image_from, image_to)
if theme.background_type == \
BackgroundType.to_string(BackgroundType.Image):
self.mainwindow.imageManager.update_image(theme.theme_name,
@ -648,7 +667,7 @@ class ThemeManager(QtGui.QWidget):
self.mainwindow.imageManager.process_updates()
self.loadThemes()
def _writeTheme(self, theme, imageFrom, imageTo):
def _writeTheme(self, theme, image_from, image_to):
"""
Writes the theme to the disk and handles the background image if
necessary
@ -659,24 +678,24 @@ class ThemeManager(QtGui.QWidget):
theme_dir = os.path.join(self.path, name)
check_directory_exists(theme_dir)
theme_file = os.path.join(theme_dir, name + u'.xml')
if self.oldBackgroundImage and \
imageTo != self.oldBackgroundImage:
delete_file(self.oldBackgroundImage)
outfile = None
if self.old_background_image and \
image_to != self.old_background_image:
delete_file(self.old_background_image)
out_file = None
try:
outfile = open(theme_file, u'w')
outfile.write(theme_pretty_xml)
out_file = open(theme_file, u'w')
out_file.write(theme_pretty_xml)
except IOError:
log.exception(u'Saving theme to file failed')
finally:
if outfile:
outfile.close()
if imageFrom and imageFrom != imageTo:
if out_file:
out_file.close()
if image_from and image_from != image_to:
try:
encoding = get_filesystem_encoding()
shutil.copyfile(
unicode(imageFrom).encode(encoding),
unicode(imageTo).encode(encoding))
unicode(image_from).encode(encoding),
unicode(image_to).encode(encoding))
except IOError:
log.exception(u'Failed to save theme image')
self.generateAndSaveImage(self.path, name, theme)
@ -684,39 +703,39 @@ class ThemeManager(QtGui.QWidget):
def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s', dir, name)
frame = self.generateImage(theme)
samplepathname = os.path.join(self.path, name + u'.png')
if os.path.exists(samplepathname):
os.unlink(samplepathname)
frame.save(samplepathname, u'png')
thumb = os.path.join(self.thumbPath, u'%s.png' % name)
create_thumb(samplepathname, thumb, False)
log.debug(u'Theme image written to %s', samplepathname)
sample_path_name = os.path.join(self.path, name + u'.png')
if os.path.exists(sample_path_name):
os.unlink(sample_path_name)
frame.save(sample_path_name, u'png')
thumb = os.path.join(self.thumb_path, u'%s.png' % name)
create_thumb(sample_path_name, thumb, False)
log.debug(u'Theme image written to %s', sample_path_name)
def updatePreviewImages(self):
"""
Called to update the themes' preview images.
"""
self.mainwindow.displayProgressBar(len(self.themelist))
for theme in self.themelist:
self.mainwindow.displayProgressBar(len(self.theme_list))
for theme in self.theme_list:
self.mainwindow.incrementProgressBar()
self.generateAndSaveImage(
self.path, theme, self.getThemeData(theme))
self.mainwindow.finishedProgressBar()
self.loadThemes()
def generateImage(self, themeData, forcePage=False):
def generateImage(self, theme_data, forcePage=False):
"""
Call the renderer to build a Sample Image
``themeData``
``theme_data``
The theme to generated a preview for.
``forcePage``
Flag to tell message lines per page need to be generated.
"""
log.debug(u'generateImage \n%s ', themeData)
log.debug(u'generateImage \n%s ', theme_data)
return self.mainwindow.renderer.generate_preview(
themeData, forcePage)
theme_data, forcePage)
def getPreviewImage(self, theme):
"""
@ -729,15 +748,15 @@ class ThemeManager(QtGui.QWidget):
image = os.path.join(self.path, theme + u'.png')
return image
def _createThemeFromXml(self, themeXml, path):
def _createThemeFromXml(self, theme_xml, path):
"""
Return a theme object using information parsed from XML
``themeXml``
``theme_xml``
The XML data to load into the theme
"""
theme = ThemeXML()
theme.parse(themeXml)
theme.parse(theme_xml)
theme.extend_image_filename(path)
return theme
@ -792,53 +811,53 @@ class ThemeManager(QtGui.QWidget):
Version 1 theme to convert
"""
theme = Theme(xml_data)
newtheme = ThemeXML()
newtheme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name)
new_theme = ThemeXML()
new_theme.theme_name = self.bad_v1_name_chars.sub(u'', theme.Name)
if theme.BackgroundType == 0:
newtheme.background_type = \
new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Solid)
newtheme.background_color = \
new_theme.background_color = \
unicode(theme.BackgroundParameter1.name())
elif theme.BackgroundType == 1:
newtheme.background_type = \
new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Gradient)
newtheme.background_direction = \
new_theme.background_direction = \
BackgroundGradientType. \
to_string(BackgroundGradientType.Horizontal)
if theme.BackgroundParameter3.name() == 1:
newtheme.background_direction = \
new_theme.background_direction = \
BackgroundGradientType. \
to_string(BackgroundGradientType.Horizontal)
newtheme.background_start_color = \
new_theme.background_start_color = \
unicode(theme.BackgroundParameter1.name())
newtheme.background_end_color = \
new_theme.background_end_color = \
unicode(theme.BackgroundParameter2.name())
elif theme.BackgroundType == 2:
newtheme.background_type = \
new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Image)
newtheme.background_filename = unicode(theme.BackgroundParameter1)
new_theme.background_filename = unicode(theme.BackgroundParameter1)
elif theme.BackgroundType == 3:
newtheme.background_type = \
new_theme.background_type = \
BackgroundType.to_string(BackgroundType.Transparent)
newtheme.font_main_name = theme.FontName
newtheme.font_main_color = unicode(theme.FontColor.name())
newtheme.font_main_size = theme.FontProportion * 3
newtheme.font_footer_name = theme.FontName
newtheme.font_footer_color = unicode(theme.FontColor.name())
newtheme.font_main_shadow = False
new_theme.font_main_name = theme.FontName
new_theme.font_main_color = unicode(theme.FontColor.name())
new_theme.font_main_size = theme.FontProportion * 3
new_theme.font_footer_name = theme.FontName
new_theme.font_footer_color = unicode(theme.FontColor.name())
new_theme.font_main_shadow = False
if theme.Shadow == 1:
newtheme.font_main_shadow = True
newtheme.font_main_shadow_color = unicode(theme.ShadowColor.name())
new_theme.font_main_shadow = True
new_theme.font_main_shadow_color = unicode(theme.ShadowColor.name())
if theme.Outline == 1:
newtheme.font_main_outline = True
newtheme.font_main_outline_color = \
new_theme.font_main_outline = True
new_theme.font_main_outline_color = \
unicode(theme.OutlineColor.name())
vAlignCorrection = VerticalType.Top
if theme.VerticalAlign == 2:
vAlignCorrection = VerticalType.Middle
elif theme.VerticalAlign == 1:
vAlignCorrection = VerticalType.Bottom
newtheme.display_horizontal_align = theme.HorizontalAlign
newtheme.display_vertical_align = vAlignCorrection
return newtheme.extract_xml()
new_theme.display_horizontal_align = theme.HorizontalAlign
new_theme.display_vertical_align = vAlignCorrection
return new_theme.extract_xml()

View File

@ -39,7 +39,7 @@ class ThemesTab(SettingsTab):
self.mainwindow = mainwindow
generalTranslated = translate('OpenLP.ThemesTab', 'Themes')
SettingsTab.__init__(self, parent, u'Themes', generalTranslated)
self.icon_path = u':/themes/theme_new.png'
self.icon_path = u':/themes/theme_new.png'
def setupUi(self):
self.setObjectName(u'ThemesTab')

View File

@ -400,7 +400,7 @@ def clean_filename(filename):
"""
if not isinstance(filename, unicode):
filename = unicode(filename, u'utf-8')
return re.sub(r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_')
return re.sub(r'[/\\?*|<>\[\]":<>+%\n]+', u'_', filename).strip(u'_')
def delete_file(file_path_name):
"""

View File

@ -281,7 +281,7 @@ class ActionList(object):
return
self.categories[category].actions.remove(action)
# Remove empty categories.
if len(self.categories[category].actions) == 0:
if not self.categories[category].actions:
self.categories.remove(category)
shortcuts = map(unicode,
map(QtGui.QKeySequence.toString, action.shortcuts()))
@ -354,18 +354,31 @@ class ActionList(object):
``action``
The action which wants to use a particular shortcut.
"""
local = action.shortcutContext() in \
[QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]
affected_actions = filter(lambda a: isinstance(a, QtGui.QAction),
self.getAllChildObjects(action.parent())) if local else []
for existing_action in existing_actions:
if action is existing_action:
continue
if existing_action.parent() is action.parent():
if not local or existing_action in affected_actions:
return False
if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut,
QtCore.Qt.ApplicationShortcut]:
if existing_action.shortcutContext() \
in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
return False
if action.shortcutContext() in [QtCore.Qt.WindowShortcut,
QtCore.Qt.ApplicationShortcut]:
elif action in self.getAllChildObjects(existing_action.parent()):
return False
return True
def getAllChildObjects(self, qobject):
"""
Goes recursively through the children of ``qobject`` and returns a list
of all child objects.
"""
children = [child for child in qobject.children()]
for child in qobject.children():
children.append(self.getAllChildObjects(child))
return children
class CategoryOrder(object):

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.db import Manager
from openlp.core.lib.ui import icon_action, UiStrings
from openlp.core.lib.ui import create_action, UiStrings
from openlp.core.lib.theme import VerticalType
from openlp.core.utils.actions import ActionList
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
@ -133,16 +133,12 @@ class AlertsPlugin(Plugin):
use it as their parent.
"""
log.info(u'add tools menu')
self.toolsAlertItem = icon_action(tools_menu, u'toolsAlertItem',
u':/plugins/plugin_alerts.png')
self.toolsAlertItem.setText(translate('AlertsPlugin', '&Alert'))
self.toolsAlertItem.setStatusTip(
translate('AlertsPlugin', 'Show an alert message.'))
self.toolsAlertItem.setShortcut(u'F7')
self.toolsAlertItem = create_action(tools_menu, u'toolsAlertItem',
text=translate('AlertsPlugin', '&Alert'),
icon=u':/plugins/plugin_alerts.png',
statustip=translate('AlertsPlugin', 'Show an alert message.'),
visible=False, shortcuts=[u'F7'], triggers=self.onAlertsTrigger)
self.serviceManager.mainwindow.toolsMenu.addAction(self.toolsAlertItem)
QtCore.QObject.connect(self.toolsAlertItem,
QtCore.SIGNAL(u'triggered()'), self.onAlertsTrigger)
self.toolsAlertItem.setVisible(False)
def initialise(self):
log.info(u'Alerts Initialising')

View File

@ -30,7 +30,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import base_action, UiStrings
from openlp.core.lib.ui import create_action, UiStrings
from openlp.core.utils.actions import ActionList
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
from openlp.plugins.bibles.forms import BibleUpgradeForm
@ -93,19 +93,16 @@ class BiblePlugin(Plugin):
self.onToolsUpgradeItemTriggered()
def addImportMenuItem(self, import_menu):
self.importBibleItem = base_action(import_menu, u'importBibleItem')
self.importBibleItem.setText(translate('BiblesPlugin', '&Bible'))
self.importBibleItem = create_action(import_menu, u'importBibleItem',
text=translate('BiblesPlugin', '&Bible'), visible=False,
triggers=self.onBibleImportClick)
import_menu.addAction(self.importBibleItem)
# signals and slots
QtCore.QObject.connect(self.importBibleItem,
QtCore.SIGNAL(u'triggered()'), self.onBibleImportClick)
self.importBibleItem.setVisible(False)
def addExportMenuItem(self, export_menu):
self.exportBibleItem = base_action(export_menu, u'exportBibleItem')
self.exportBibleItem.setText(translate('BiblesPlugin', '&Bible'))
self.exportBibleItem = create_action(export_menu, u'exportBibleItem',
text=translate('BiblesPlugin', '&Bible'),
visible=False)
export_menu.addAction(self.exportBibleItem)
self.exportBibleItem.setVisible(False)
def addToolsMenuItem(self, tools_menu):
"""
@ -117,17 +114,12 @@ class BiblePlugin(Plugin):
use it as their parent.
"""
log.debug(u'add tools menu')
self.toolsUpgradeItem = QtGui.QAction(tools_menu)
self.toolsUpgradeItem.setObjectName(u'toolsUpgradeItem')
self.toolsUpgradeItem.setText(
translate('BiblesPlugin', '&Upgrade older Bibles'))
self.toolsUpgradeItem.setStatusTip(
translate('BiblesPlugin', 'Upgrade the Bible databases to the '
'latest format.'))
self.toolsUpgradeItem = create_action(tools_menu, u'toolsUpgradeItem',
text=translate('BiblesPlugin', '&Upgrade older Bibles'),
statustip=translate('BiblesPlugin',
'Upgrade the Bible databases to the latest format.'),
visible=False, triggers=self.onToolsUpgradeItemTriggered)
tools_menu.addAction(self.toolsUpgradeItem)
QtCore.QObject.connect(self.toolsUpgradeItem,
QtCore.SIGNAL(u'triggered()'), self.onToolsUpgradeItemTriggered)
self.toolsUpgradeItem.setVisible(False)
def onToolsUpgradeItemTriggered(self):
"""

View File

@ -34,6 +34,7 @@ import re
from PyQt4 import QtCore
from openlp.core.lib import translate
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
log = logging.getLogger(__name__)
@ -59,6 +60,122 @@ class DisplayStyle(object):
Square = 3
class LanguageSelection(object):
"""
An enumeration for bible bookname language.
And standard strings for use throughout the bibles plugin.
"""
Bible = 0
Application = 1
English = 2
class BibleStrings(object):
"""
Provide standard strings for objects to use.
"""
__instance__ = None
def __new__(cls):
"""
Override the default object creation method to return a single instance.
"""
if not cls.__instance__:
cls.__instance__ = object.__new__(cls)
return cls.__instance__
def __init__(self):
"""
These strings should need a good reason to be retranslated elsewhere.
"""
self.Booknames = {
u'Gen': translate('BiblesPlugin', 'Genesis'),
u'Exod': translate('BiblesPlugin', 'Exodus'),
u'Lev': translate('BiblesPlugin', 'Leviticus'),
u'Num': translate('BiblesPlugin', 'Numbers'),
u'Deut': translate('BiblesPlugin', 'Deuteronomy'),
u'Josh': translate('BiblesPlugin', 'Joshua'),
u'Judg': translate('BiblesPlugin', 'Judges'),
u'Ruth': translate('BiblesPlugin', 'Ruth'),
u'1Sam': translate('BiblesPlugin', '1 Samuel'),
u'2Sam': translate('BiblesPlugin', '2 Samuel'),
u'1Kgs': translate('BiblesPlugin', '1 Kings'),
u'2Kgs': translate('BiblesPlugin', '2 Kings'),
u'1Chr': translate('BiblesPlugin', '1 Chronicles'),
u'2Chr': translate('BiblesPlugin', '2 Chronicles'),
u'Esra': translate('BiblesPlugin', 'Ezra'),
u'Neh': translate('BiblesPlugin', 'Nehemiah'),
u'Esth': translate('BiblesPlugin', 'Esther'),
u'Job': translate('BiblesPlugin', 'Job'),
u'Ps': translate('BiblesPlugin', 'Psalms'),
u'Prov': translate('BiblesPlugin', 'Proverbs'),
u'Eccl': translate('BiblesPlugin', 'Ecclesiastes'),
u'Song': translate('BiblesPlugin', 'Song of Solomon'),
u'Isa': translate('BiblesPlugin', 'Isaiah'),
u'Jer': translate('BiblesPlugin', 'Jeremiah'),
u'Lam': translate('BiblesPlugin', 'Lamentations'),
u'Ezek': translate('BiblesPlugin', 'Ezekiel'),
u'Dan': translate('BiblesPlugin', 'Daniel'),
u'Hos': translate('BiblesPlugin', 'Hosea'),
u'Joel': translate('BiblesPlugin', 'Joel'),
u'Amos': translate('BiblesPlugin', 'Amos'),
u'Obad': translate('BiblesPlugin', 'Obadiah'),
u'Jonah': translate('BiblesPlugin', 'Jonah'),
u'Mic': translate('BiblesPlugin', 'Micah'),
u'Nah': translate('BiblesPlugin', 'Nahum'),
u'Hab': translate('BiblesPlugin', 'Habakkuk'),
u'Zeph': translate('BiblesPlugin', 'Zephaniah'),
u'Hag': translate('BiblesPlugin', 'Haggai'),
u'Zech': translate('BiblesPlugin', 'Zechariah'),
u'Mal': translate('BiblesPlugin', 'Malachi'),
u'Matt': translate('BiblesPlugin', 'Matthew'),
u'Mark': translate('BiblesPlugin', 'Mark'),
u'Luke': translate('BiblesPlugin', 'Luke'),
u'John': translate('BiblesPlugin', 'John'),
u'Acts': translate('BiblesPlugin', 'Acts'),
u'Rom': translate('BiblesPlugin', 'Romans'),
u'1Cor': translate('BiblesPlugin', '1 Corinthians'),
u'2Cor': translate('BiblesPlugin', '2 Corinthians'),
u'Gal': translate('BiblesPlugin', 'Galatians'),
u'Eph': translate('BiblesPlugin', 'Ephesians'),
u'Phil': translate('BiblesPlugin', 'Philippians'),
u'Col': translate('BiblesPlugin', 'Colossians'),
u'1Thess': translate('BiblesPlugin', '1 Thessalonians'),
u'2Thess': translate('BiblesPlugin', '2 Thessalonians'),
u'1Tim': translate('BiblesPlugin', '1 Timothy'),
u'2Tim': translate('BiblesPlugin', '2 Timothy'),
u'Titus': translate('BiblesPlugin', 'Titus'),
u'Phlm': translate('BiblesPlugin', 'Philemon'),
u'Heb': translate('BiblesPlugin', 'Hebrews'),
u'Jas': translate('BiblesPlugin', 'James'),
u'1Pet': translate('BiblesPlugin', '1 Peter'),
u'2Pet': translate('BiblesPlugin', '2 Peter'),
u'1John': translate('BiblesPlugin', '1 John'),
u'2John': translate('BiblesPlugin', '2 John'),
u'3John': translate('BiblesPlugin', '3 John'),
u'Jude': translate('BiblesPlugin', 'Jude'),
u'Rev': translate('BiblesPlugin', 'Revelation'),
u'Jdt': translate('BiblesPlugin', 'Judith'),
u'Wis': translate('BiblesPlugin', 'Wisdom'),
u'Tob': translate('BiblesPlugin', 'Tobit'),
u'Sir': translate('BiblesPlugin', 'Sirach'),
u'Bar': translate('BiblesPlugin', 'Baruch'),
u'1Macc': translate('BiblesPlugin', '1 Maccabees'),
u'2Macc': translate('BiblesPlugin', '2 Maccabees'),
u'3Macc': translate('BiblesPlugin', '3 Maccabees'),
u'4Macc': translate('BiblesPlugin', '4 Maccabees'),
u'AddDan': translate('BiblesPlugin', 'Rest of Daniel'),
u'AddEsth': translate('BiblesPlugin', 'Rest of Esther'),
u'PrMan': translate('BiblesPlugin', 'Prayer of Manasses'),
u'LetJer': translate('BiblesPlugin', 'Letter of Jeremiah'),
u'PrAza': translate('BiblesPlugin', 'Prayer of Azariah'),
u'Sus': translate('BiblesPlugin', 'Susanna'),
u'Bel': translate('BiblesPlugin', 'Bel'),
u'1Esdr': translate('BiblesPlugin', '1 Esdras'),
u'2Esdr': translate('BiblesPlugin', '2 Esdras')
}
def update_reference_separators():
"""
Updates separators and matches for parsing and formating scripture
@ -89,7 +206,7 @@ def update_reference_separators():
while u'||' in source_string:
source_string = source_string.replace(u'||', u'|')
if role != u'e':
REFERENCE_SEPARATORS[u'sep_%s_display' % role] = \
REFERENCE_SEPARATORS[u'sep_%s_display' % role] = \
source_string.split(u'|')[0]
# escape reserved characters
for character in u'\\.^$*+?{}[]()':
@ -139,7 +256,7 @@ def get_reference_match(match_type):
update_reference_separators()
return REFERENCE_MATCHES[match_type]
def parse_reference(reference):
def parse_reference(reference, bible, language_selection, book_ref_id=False):
"""
This is the next generation über-awesome function that takes a person's
typed in string and converts it to a list of references to be queried from
@ -147,6 +264,16 @@ def parse_reference(reference):
``reference``
A string. The Bible reference to parse.
``bible``
A object. The Bible database object.
``language_selection``
An int. The language selection the user has choosen in settings
section.
``book_ref_id``
A string. The book reference id.
Returns ``None`` or a reference list.
@ -232,6 +359,51 @@ def parse_reference(reference):
if match:
log.debug(u'Matched reference %s' % reference)
book = match.group(u'book')
if not book_ref_id:
booknames = BibleStrings().Booknames
# escape reserved characters
book_escaped = book
for character in u'\\.^$*+?{}[]()':
book_escaped = book_escaped.replace(
character, u'\\' + character)
regex_book = re.compile(u'\s*%s\s*' % u'\s*'.join(
book_escaped.split()), re.UNICODE | re.IGNORECASE)
if language_selection == LanguageSelection.Bible:
db_book = bible.get_book(book)
if db_book:
book_ref_id = db_book.book_reference_id
elif language_selection == LanguageSelection.Application:
book_list = []
for key, value in booknames.iteritems():
if regex_book.match(unicode(value)):
book_list.append(key)
books = []
if book_list:
for value in book_list:
item = BiblesResourcesDB.get_book(value)
if item:
books.append(item)
if books:
for value in books:
if bible.get_book_by_book_ref_id(value[u'id']):
book_ref_id = value[u'id']
break
elif language_selection == LanguageSelection.English:
books = BiblesResourcesDB.get_books_like(book)
if books:
book_list = []
for value in books:
if regex_book.match(value[u'name']):
book_list.append(value)
if not book_list:
book_list = books
for value in book_list:
if bible.get_book_by_book_ref_id(value[u'id']):
book_ref_id = value[u'id']
break
else:
if not bible.get_book_by_book_ref_id(book_ref_id):
book_ref_id = False
ranges = match.group(u'ranges')
range_list = get_reference_match(u'range_separator').split(ranges)
ref_list = []
@ -277,16 +449,18 @@ def parse_reference(reference):
if not to_verse:
to_verse = -1
if to_chapter > from_chapter:
ref_list.append((book, from_chapter, from_verse, -1))
ref_list.append((book_ref_id, from_chapter, from_verse, -1))
for i in range(from_chapter + 1, to_chapter):
ref_list.append((book, i, 1, -1))
ref_list.append((book, to_chapter, 1, to_verse))
ref_list.append((book_ref_id, i, 1, -1))
ref_list.append((book_ref_id, to_chapter, 1, to_verse))
elif to_verse >= from_verse or to_verse == -1:
ref_list.append((book, from_chapter, from_verse, to_verse))
ref_list.append((book_ref_id, from_chapter,
from_verse, to_verse))
elif from_verse:
ref_list.append((book, from_chapter, from_verse, from_verse))
ref_list.append((book_ref_id, from_chapter,
from_verse, from_verse))
else:
ref_list.append((book, from_chapter, 1, -1))
ref_list.append((book_ref_id, from_chapter, 1, -1))
return ref_list
else:
log.debug(u'Invalid reference: %s' % reference)

View File

@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsTab, translate
from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
update_reference_separators, get_reference_separator
update_reference_separators, get_reference_separator, LanguageSelection
log = logging.getLogger(__name__)
@ -140,9 +140,25 @@ class BiblesTab(SettingsTab):
self.scriptureReferenceLayout.addWidget(self.endSeparatorLineEdit, 3,
1)
self.leftLayout.addWidget(self.scriptureReferenceGroupBox)
self.leftLayout.addStretch()
self.rightColumn.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
self.languageSelectionGroupBox = QtGui.QGroupBox(self.rightColumn)
self.languageSelectionGroupBox.setObjectName(
u'languageSelectionGroupBox')
self.languageSelectionLayout = QtGui.QVBoxLayout(
self.languageSelectionGroupBox)
self.languageSelectionLabel = QtGui.QLabel(
self.languageSelectionGroupBox)
self.languageSelectionLabel.setObjectName(u'languageSelectionLabel')
self.languageSelectionComboBox = QtGui.QComboBox(
self.languageSelectionGroupBox)
self.languageSelectionComboBox.setObjectName(
u'languageSelectionComboBox')
self.languageSelectionComboBox.addItems([u'', u'', u''])
self.languageSelectionLayout.addWidget(self.languageSelectionLabel)
self.languageSelectionLayout.addWidget(self.languageSelectionComboBox)
self.rightLayout.addWidget(self.languageSelectionGroupBox)
self.leftLayout.addStretch()
self.rightLayout.addStretch()
# Signals and slots
QtCore.QObject.connect(
@ -198,6 +214,9 @@ class BiblesTab(SettingsTab):
self.onEndSeparatorLineEditFinished)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
QtCore.QObject.connect(
self.languageSelectionComboBox, QtCore.SIGNAL(u'activated(int)'),
self.onLanguageSelectionComboBoxChanged)
def retranslateUi(self):
self.verseDisplayGroupBox.setTitle(
@ -257,6 +276,23 @@ class BiblesTab(SettingsTab):
'end marks may be defined.\nThey have to be separated by a '
'vertical bar "|".\nPlease clear this edit line to use the '
'default value.'))
self.languageSelectionGroupBox.setTitle(
translate('BiblesPlugin.BiblesTab', 'Preferred Bookname Language'))
self.languageSelectionLabel.setText(translate('BiblesPlugin.BiblesTab',
'Choose the language in which the book names of the\nBible should '
'be displayed in the Bible search:'))
self.languageSelectionComboBox.setItemText(LanguageSelection.Bible,
translate('BiblesPlugin.BiblesTab', 'Bible language'))
self.languageSelectionComboBox.setItemText(
LanguageSelection.Application,
translate('BiblesPlugin.BiblesTab', 'Application language'))
self.languageSelectionComboBox.setItemText(LanguageSelection.English,
translate('BiblesPlugin.BiblesTab', 'English'))
self.languageSelectionComboBox.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple options:\n '
'Bible language - the language in which the Bible book names '
'were imported\n Application language - the language you have '
'chosen for OpenLP\n English - always use English book names'))
def onBibleThemeComboBoxChanged(self):
self.bible_theme = self.bibleThemeComboBox.currentText()
@ -267,6 +303,9 @@ class BiblesTab(SettingsTab):
def onLayoutStyleComboBoxChanged(self):
self.layout_style = self.layoutStyleComboBox.currentIndex()
def onLanguageSelectionComboBoxChanged(self):
self.language_selection = self.languageSelectionComboBox.currentIndex()
def onNewChaptersCheckBoxChanged(self, check_state):
self.show_new_chapters = False
# We have a set value convert to True/False.
@ -448,6 +487,9 @@ class BiblesTab(SettingsTab):
self.endSeparatorLineEdit.setPalette(
self.getGreyTextPalette(False))
self.endSeparatorCheckBox.setChecked(True)
self.language_selection = settings.value(
u'bookname language', QtCore.QVariant(0)).toInt()[0]
self.languageSelectionComboBox.setCurrentIndex(self.language_selection)
settings.endGroup()
def save(self):
@ -459,6 +501,8 @@ class BiblesTab(SettingsTab):
QtCore.QVariant(self.display_style))
settings.setValue(u'verse layout style',
QtCore.QVariant(self.layout_style))
settings.setValue(u'bookname language',
QtCore.QVariant(self.language_selection))
settings.setValue(u'second bibles', QtCore.QVariant(self.second_bibles))
settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme))
if self.verseSeparatorCheckBox.isChecked():
@ -482,6 +526,7 @@ class BiblesTab(SettingsTab):
else:
settings.remove(u'end separator')
update_reference_separators()
Receiver.send_message(u'bibles_load_list')
settings.endGroup()
def updateThemeList(self, theme_list):

View File

@ -435,19 +435,19 @@ class BibleDB(QtCore.QObject, Manager):
else:
return count
def get_verse_count(self, book_id, chapter):
def get_verse_count(self, book_ref_id, chapter):
"""
Return the number of verses in a chapter.
``book``
The book containing the chapter.
``book_ref_id``
The book reference id.
``chapter``
The chapter to get the verse count for.
"""
log.debug(u'BibleDB.get_verse_count("%s", "%s")', book_id, chapter)
log.debug(u'BibleDB.get_verse_count("%s", "%s")', book_ref_id, chapter)
count = self.session.query(Verse).join(Book)\
.filter(Book.book_reference_id==book_id)\
.filter(Book.book_reference_id==book_ref_id)\
.filter(Verse.chapter==chapter)\
.count()
if not count:
@ -595,6 +595,35 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
else:
return None
@staticmethod
def get_books_like(string):
"""
Return the books which include string.
``string``
The string to search for in the booknames or abbreviations.
"""
log.debug(u'BiblesResourcesDB.get_book_like("%s")', string)
if not isinstance(string, unicode):
name = unicode(string)
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM book_reference WHERE '
u'LOWER(name) LIKE ? OR LOWER(abbreviation) LIKE ?',
(u'%' + string.lower() + u'%', u'%' + string.lower() + u'%'))
if books:
return [
{
u'id': book[0],
u'testament_id': book[1],
u'name': unicode(book[2]),
u'abbreviation': unicode(book[3]),
u'chapters': book[4]
}
for book in books
]
else:
return None
@staticmethod
def get_book_by_id(id):
"""
@ -621,23 +650,23 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
return None
@staticmethod
def get_chapter(book_id, chapter):
def get_chapter(book_ref_id, chapter):
"""
Return the chapter details for a specific chapter of a book.
``book_id``
``book_ref_id``
The id of a book.
``chapter``
The chapter number.
"""
log.debug(u'BiblesResourcesDB.get_chapter("%s", "%s")', book_id,
log.debug(u'BiblesResourcesDB.get_chapter("%s", "%s")', book_ref_id,
chapter)
if not isinstance(chapter, int):
chapter = int(chapter)
chapters = BiblesResourcesDB.run_sql(u'SELECT id, book_reference_id, '
u'chapter, verse_count FROM chapters WHERE book_reference_id = ?',
(book_id,))
(book_ref_id,))
try:
return {
u'id': chapters[chapter-1][0],
@ -649,21 +678,21 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
return None
@staticmethod
def get_chapter_count(book_id):
def get_chapter_count(book_ref_id):
"""
Return the number of chapters in a book.
``book_id``
``book_ref_id``
The id of the book.
"""
log.debug(u'BiblesResourcesDB.get_chapter_count("%s")', book_id)
details = BiblesResourcesDB.get_book_by_id(book_id)
log.debug(u'BiblesResourcesDB.get_chapter_count("%s")', book_ref_id)
details = BiblesResourcesDB.get_book_by_id(book_ref_id)
if details:
return details[u'chapters']
return 0
@staticmethod
def get_verse_count(book_id, chapter):
def get_verse_count(book_ref_id, chapter):
"""
Return the number of verses in a chapter.
@ -673,9 +702,9 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
``chapter``
The number of the chapter.
"""
log.debug(u'BiblesResourcesDB.get_verse_count("%s", "%s")', book_id,
log.debug(u'BiblesResourcesDB.get_verse_count("%s", "%s")', book_ref_id,
chapter)
details = BiblesResourcesDB.get_chapter(book_id, chapter)
details = BiblesResourcesDB.get_chapter(book_ref_id, chapter)
if details:
return details[u'verse_count']
return 0

View File

@ -33,7 +33,8 @@ from PyQt4 import QtCore
from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.utils import AppLocation, delete_file
from openlp.plugins.bibles.lib import parse_reference, get_reference_separator
from openlp.plugins.bibles.lib import parse_reference, \
get_reference_separator, LanguageSelection
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from csvbible import CSVBible
from http import HTTPBible
@ -227,6 +228,19 @@ class BibleManager(object):
for book in self.db_cache[bible].get_books()
]
def get_book_by_id(self, bible, id):
"""
Returns a book object by given id.
``bible``
Unicode. The Bible to get the list of books from.
``id``
Unicode. The book_reference_id to get the book for.
"""
log.debug(u'BibleManager.get_book_by_id("%s", "%s")', bible, id)
return self.db_cache[bible].get_book_by_book_ref_id(id)
def get_chapter_count(self, bible, book):
"""
Returns the number of Chapters for a given book.
@ -252,7 +266,16 @@ class BibleManager(object):
book_ref_id = db_book.book_reference_id
return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
def get_verses(self, bible, versetext, firstbible=False, show_error=True):
def get_verse_count_by_book_ref_id(self, bible, book_ref_id, chapter):
"""
Returns all the number of verses for a given
book_ref_id and chapterMaxBibleBookVerses.
"""
log.debug(u'BibleManager.get_verse_count_by_book_ref_id("%s", "%s", '
u'"%s")', bible, book_ref_id, chapter)
return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
def get_verses(self, bible, versetext, book_ref_id=False, show_error=True):
"""
Parses a scripture reference, fetches the verses from the Bible
specified, and returns a list of ``Verse`` objects.
@ -270,6 +293,10 @@ class BibleManager(object):
- Genesis 1:1-10,15-20
- Genesis 1:1-2:10
- Genesis 1:1-10,2:1-10
``book_ref_id``
Unicode. The book referece id from the book in versetext.
For second bible this is necessary.
"""
log.debug(u'BibleManager.get_verses("%s", "%s")', bible, versetext)
if not bible:
@ -282,30 +309,12 @@ class BibleManager(object):
'Import Wizard to install one or more Bibles.')
})
return None
reflist = parse_reference(versetext)
language_selection = QtCore.QSettings().value(
self.settingsSection + u'/bookname language',
QtCore.QVariant(0)).toInt()[0]
reflist = parse_reference(versetext, self.db_cache[bible],
language_selection, book_ref_id)
if reflist:
new_reflist = []
for item in reflist:
if item:
if firstbible:
db_book = self.db_cache[firstbible].get_book(item[0])
db_book = self.db_cache[bible].get_book_by_book_ref_id(
db_book.book_reference_id)
else:
db_book = self.db_cache[bible].get_book(item[0])
if db_book:
book_id = db_book.book_reference_id
log.debug(u'Book name corrected to "%s"', db_book.name)
new_reflist.append((book_id, item[1], item[2],
item[3]))
else:
log.debug(u'OpenLP failed to find book %s', item[0])
critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching book '
'could be found in this Bible. Check that you have '
'spelled the name of the book correctly.'))
reflist = new_reflist
return self.db_cache[bible].get_verses(reflist, show_error)
else:
if show_error:

View File

@ -38,7 +38,8 @@ from openlp.core.lib.ui import UiStrings, add_widget_completer, \
find_and_set_in_combo_box, build_icon
from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
VerseReferenceList, get_reference_separator
VerseReferenceList, get_reference_separator, LanguageSelection, BibleStrings
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
log = logging.getLogger(__name__)
@ -424,20 +425,37 @@ class BibleMediaItem(MediaManagerItem):
book_data = book_data_temp
self.advancedBookComboBox.clear()
first = True
language_selection = QtCore.QSettings().value(
self.settingsSection + u'/bookname language',
QtCore.QVariant(0)).toInt()[0]
booknames = BibleStrings().Booknames
for book in book_data:
row = self.advancedBookComboBox.count()
self.advancedBookComboBox.addItem(book[u'name'])
if language_selection == LanguageSelection.Bible:
self.advancedBookComboBox.addItem(book[u'name'])
elif language_selection == LanguageSelection.Application:
data = BiblesResourcesDB.get_book_by_id(
book[u'book_reference_id'])
self.advancedBookComboBox.addItem(
booknames[data[u'abbreviation']])
elif language_selection == LanguageSelection.English:
data = BiblesResourcesDB.get_book_by_id(
book[u'book_reference_id'])
self.advancedBookComboBox.addItem(data[u'name'])
self.advancedBookComboBox.setItemData(
row, QtCore.QVariant(book[u'chapters']))
row, QtCore.QVariant(book[u'book_reference_id']))
if first:
first = False
self.initialiseChapterVerse(bible, book[u'name'],
book[u'chapters'])
book[u'book_reference_id'])
def initialiseChapterVerse(self, bible, book, chapter_count):
log.debug(u'initialiseChapterVerse %s, %s', bible, book)
self.chapter_count = chapter_count
verse_count = self.plugin.manager.get_verse_count(bible, book, 1)
def initialiseChapterVerse(self, bible, book, book_ref_id):
log.debug(u'initialiseChapterVerse %s, %s, %s', bible, book,
book_ref_id)
book = self.plugin.manager.get_book_by_id(bible, book_ref_id)
self.chapter_count = self.plugin.manager.get_chapter_count(bible, book)
verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(bible,
book_ref_id, 1)
if verse_count == 0:
self.advancedSearchButton.setEnabled(False)
critical_error_message_box(
@ -456,6 +474,7 @@ class BibleMediaItem(MediaManagerItem):
completion depends on the bible. It is only updated when we are doing a
reference search, otherwise the auto completion list is removed.
"""
log.debug(u'updateAutoCompleter')
# Save the current search type to the configuration.
QtCore.QSettings().setValue(u'%s/last search type' %
self.settingsSection,
@ -480,7 +499,22 @@ class BibleMediaItem(MediaManagerItem):
secondbook.book_reference_id:
book_data_temp.append(book)
book_data = book_data_temp
books = [book.name + u' ' for book in book_data]
language_selection = QtCore.QSettings().value(
self.settingsSection + u'/bookname language',
QtCore.QVariant(0)).toInt()[0]
if language_selection == LanguageSelection.Bible:
books = [book.name + u' ' for book in book_data]
elif language_selection == LanguageSelection.Application:
booknames = BibleStrings().Booknames
for book in book_data:
data = BiblesResourcesDB.get_book_by_id(
book.book_reference_id)
books.append(data[u'name'] + u' ')
elif language_selection == LanguageSelection.English:
for book in book_data:
data = BiblesResourcesDB.get_book_by_id(
book.book_reference_id)
books.append(data[u'name'] + u' ')
books.sort(cmp=locale.strcoll)
add_widget_completer(books, self.quickSearchEdit)
@ -547,29 +581,31 @@ class BibleMediaItem(MediaManagerItem):
self.initialiseChapterVerse(
unicode(self.advancedVersionComboBox.currentText()),
unicode(self.advancedBookComboBox.currentText()),
self.advancedBookComboBox.itemData(item).toInt()[0])
unicode(self.advancedBookComboBox.itemData(item).toString()))
def onAdvancedFromVerse(self):
chapter_from = int(self.advancedFromChapter.currentText())
chapter_to = int(self.advancedToChapter.currentText())
if chapter_from == chapter_to:
bible = unicode(self.advancedVersionComboBox.currentText())
book = unicode(self.advancedBookComboBox.currentText())
book_ref_id = unicode(self.advancedBookComboBox.itemData(
int(self.advancedBookComboBox.currentIndex())).toString())
verse_from = int(self.advancedFromVerse.currentText())
verse_count = self.plugin.manager.get_verse_count(bible, book,
chapter_to)
verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(
bible, book_ref_id, chapter_to)
self.adjustComboBox(verse_from, verse_count,
self.advancedToVerse, True)
def onAdvancedToChapter(self):
bible = unicode(self.advancedVersionComboBox.currentText())
book = unicode(self.advancedBookComboBox.currentText())
book_ref_id = unicode(self.advancedBookComboBox.itemData(
int(self.advancedBookComboBox.currentIndex())).toString())
chapter_from = int(self.advancedFromChapter.currentText())
chapter_to = int(self.advancedToChapter.currentText())
verse_from = int(self.advancedFromVerse.currentText())
verse_to = int(self.advancedToVerse.currentText())
verse_count = self.plugin.manager.get_verse_count(bible, book,
chapter_to)
verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(bible,
book_ref_id, chapter_to)
if chapter_from == chapter_to and verse_from > verse_to:
self.adjustComboBox(verse_from, verse_count, self.advancedToVerse)
else:
@ -577,11 +613,12 @@ class BibleMediaItem(MediaManagerItem):
def onAdvancedFromChapter(self):
bible = unicode(self.advancedVersionComboBox.currentText())
book = unicode(self.advancedBookComboBox.currentText())
book_ref_id = unicode(self.advancedBookComboBox.itemData(
int(self.advancedBookComboBox.currentIndex())).toString())
chapter_from = int(self.advancedFromChapter.currentText())
chapter_to = int(self.advancedToChapter.currentText())
verse_count = self.plugin.manager.get_verse_count(bible, book,
chapter_from)
verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(bible,
book_ref_id, chapter_from)
self.adjustComboBox(1, verse_count, self.advancedFromVerse)
if chapter_from > chapter_to:
self.adjustComboBox(1, verse_count, self.advancedToVerse)
@ -630,6 +667,8 @@ class BibleMediaItem(MediaManagerItem):
bible = unicode(self.advancedVersionComboBox.currentText())
second_bible = unicode(self.advancedSecondComboBox.currentText())
book = unicode(self.advancedBookComboBox.currentText())
book_ref_id = unicode(self.advancedBookComboBox.itemData(
int(self.advancedBookComboBox.currentIndex())).toString())
chapter_from = self.advancedFromChapter.currentText()
chapter_to = self.advancedToChapter.currentText()
verse_from = self.advancedFromVerse.currentText()
@ -640,10 +679,11 @@ class BibleMediaItem(MediaManagerItem):
range_separator + chapter_to + verse_separator + verse_to
versetext = u'%s %s' % (book, verse_range)
Receiver.send_message(u'cursor_busy')
self.search_results = self.plugin.manager.get_verses(bible, versetext)
self.search_results = self.plugin.manager.get_verses(bible, versetext,
book_ref_id)
if second_bible:
self.second_search_results = self.plugin.manager.get_verses(
second_bible, versetext, bible)
second_bible, versetext, book_ref_id)
if not self.advancedLockButton.isChecked():
self.listView.clear()
if self.listView.count() != 0:
@ -671,7 +711,8 @@ class BibleMediaItem(MediaManagerItem):
self.search_results = self.plugin.manager.get_verses(bible, text)
if second_bible and self.search_results:
self.second_search_results = self.plugin.manager.get_verses(
second_bible, text, bible)
second_bible, text,
self.search_results[0].book.book_reference_id)
else:
# We are doing a 'Text Search'.
Receiver.send_message(u'cursor_busy')
@ -989,8 +1030,7 @@ class BibleMediaItem(MediaManagerItem):
Search for some Bible verses (by reference).
"""
bible = unicode(self.quickVersionComboBox.currentText())
search_results = self.plugin.manager.get_verses(bible, string, False,
False)
search_results = self.plugin.manager.get_verses(bible, string, False)
if search_results:
versetext = u' '.join([verse.text for verse in search_results])
return [[string, versetext]]

View File

@ -68,7 +68,7 @@ class CustomMediaItem(MediaManagerItem):
self.manager = plugin.manager
def addEndHeaderBar(self):
self.addToolbarSeparator()
self.toolbar.addSeparator()
self.addSearchToToolBar()
# Signals and slots
QtCore.QObject.connect(self.searchTextEdit,

View File

@ -89,11 +89,11 @@ class ImageMediaItem(MediaManagerItem):
self.listView.addAction(self.replaceAction)
def addEndHeaderBar(self):
self.replaceAction = self.addToolbarButton(u'', u'',
u':/slides/slide_blank.png', self.onReplaceClick, False)
self.resetAction = self.addToolbarButton(u'', u'',
u':/system/system_close.png', self.onResetClick, False)
self.resetAction.setVisible(False)
self.replaceAction = self.toolbar.addToolbarAction(u'replaceAction',
icon=u':/slides/slide_blank.png', triggers=self.onReplaceClick)
self.resetAction = self.toolbar.addToolbarAction(u'resetAction',
icon=u':/system/system_close.png', visible=False,
triggers=self.onResetClick)
def onDeleteClick(self):
"""

View File

@ -118,11 +118,11 @@ class MediaMediaItem(MediaManagerItem):
def addEndHeaderBar(self):
# Replace backgrounds do not work at present so remove functionality.
self.replaceAction = self.addToolbarButton(u'', u'',
u':/slides/slide_blank.png', self.onReplaceClick, False)
self.resetAction = self.addToolbarButton(u'', u'',
u':/system/system_close.png', self.onResetClick, False)
self.resetAction.setVisible(False)
self.replaceAction = self.toolbar.addToolbarAction(u'replaceAction',
icon=u':/slides/slide_blank.png', triggers=self.onReplaceClick)
self.resetAction = self.toolbar.addToolbarAction(u'resetAction',
icon=u':/system/system_close.png', visible=False,
triggers=self.onResetClick)
self.mediaWidget = QtGui.QWidget(self)
self.mediaWidget.setObjectName(u'mediaWidget')
self.displayLayout = QtGui.QFormLayout(self.mediaWidget)

View File

@ -28,7 +28,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate, Receiver
from openlp.core.lib.ui import UiStrings
from openlp.core.lib.ui import UiStrings, create_up_down_push_button_set
class MediaQCheckBox(QtGui.QCheckBox):
"""
@ -65,7 +65,7 @@ class MediaTab(SettingsTab):
self.leftLayout.addWidget(self.mediaPlayerGroupBox)
self.playerOrderGroupBox = QtGui.QGroupBox(self.leftColumn)
self.playerOrderGroupBox.setObjectName(u'playerOrderGroupBox')
self.playerOrderLayout = QtGui.QVBoxLayout(self.playerOrderGroupBox)
self.playerOrderLayout = QtGui.QHBoxLayout(self.playerOrderGroupBox)
self.playerOrderLayout.setObjectName(u'playerOrderLayout')
self.playerOrderlistWidget = QtGui.QListWidget( \
self.playerOrderGroupBox)
@ -84,18 +84,15 @@ class MediaTab(SettingsTab):
QtGui.QAbstractItemView.NoEditTriggers)
self.playerOrderlistWidget.setObjectName(u'playerOrderlistWidget')
self.playerOrderLayout.addWidget(self.playerOrderlistWidget)
self.orderingButtonsWidget = QtGui.QWidget(self.playerOrderGroupBox)
self.orderingButtonsWidget.setObjectName(u'orderingButtonsWidget')
self.orderingButtonLayout = QtGui.QHBoxLayout( \
self.orderingButtonsWidget)
self.orderingButtonLayout = QtGui.QVBoxLayout()
self.orderingButtonLayout.setObjectName(u'orderingButtonLayout')
self.orderingDownButton = QtGui.QPushButton(self.orderingButtonsWidget)
self.orderingDownButton.setObjectName(u'orderingDownButton')
self.orderingButtonLayout.addWidget(self.orderingDownButton)
self.orderingUpButton = QtGui.QPushButton(self.playerOrderGroupBox)
self.orderingUpButton.setObjectName(u'orderingUpButton')
self.orderingButtonLayout.addStretch(1)
self.orderingUpButton, self.orderingDownButton = \
create_up_down_push_button_set(self)
self.orderingButtonLayout.addWidget(self.orderingUpButton)
self.playerOrderLayout.addWidget(self.orderingButtonsWidget)
self.orderingButtonLayout.addWidget(self.orderingDownButton)
self.orderingButtonLayout.addStretch(1)
self.playerOrderLayout.addLayout(self.orderingButtonLayout)
self.leftLayout.addWidget(self.playerOrderGroupBox)
self.advancedGroupBox = QtGui.QGroupBox(self.leftColumn)
self.advancedGroupBox.setObjectName(u'advancedGroupBox')
@ -113,10 +110,6 @@ class MediaTab(SettingsTab):
QtCore.QObject.connect(checkbox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onPlayerCheckBoxChanged)
QtCore.QObject.connect(self.orderingUpButton,
QtCore.SIGNAL(u'pressed()'), self.onOrderingUpButtonPressed)
QtCore.QObject.connect(self.orderingDownButton,
QtCore.SIGNAL(u'pressed()'), self.onOrderingDownButtonPressed)
def retranslateUi(self):
self.mediaPlayerGroupBox.setTitle(
@ -133,14 +126,10 @@ class MediaTab(SettingsTab):
'%s (unavailable)')) % player.display_name)
self.playerOrderGroupBox.setTitle(
translate('MediaPlugin.MediaTab', 'Player O&rder'))
self.orderingDownButton.setText(
translate('MediaPlugin.MediaTab', '&Down'))
self.orderingUpButton.setText(
translate('MediaPlugin.MediaTab', '&Up'))
self.advancedGroupBox.setTitle(UiStrings().Advanced)
self.overridePlayerCheckBox.setText(
translate('MediaPlugin.MediaTab',
'&Allow media player to be overriden'))
'&Allow media player to be overridden'))
def onPlayerCheckBoxChanged(self, check_state):
player = self.sender().playerName
@ -164,21 +153,23 @@ class MediaTab(SettingsTab):
self.playerOrderlistWidget.addItem(
self.mediaPlayers[unicode(player)].original_name)
def onOrderingUpButtonPressed(self):
currentRow = self.playerOrderlistWidget.currentRow()
if currentRow > 0:
item = self.playerOrderlistWidget.takeItem(currentRow)
self.playerOrderlistWidget.insertItem(currentRow - 1, item)
self.playerOrderlistWidget.setCurrentRow(currentRow - 1)
self.usedPlayers.move(currentRow, currentRow - 1)
def onUpButtonClicked(self):
row = self.playerOrderlistWidget.currentRow()
if row <= 0:
return
item = self.playerOrderlistWidget.takeItem(row)
self.playerOrderlistWidget.insertItem(row - 1, item)
self.playerOrderlistWidget.setCurrentRow(row - 1)
self.usedPlayers.move(row, row - 1)
def onOrderingDownButtonPressed(self):
currentRow = self.playerOrderlistWidget.currentRow()
if currentRow < self.playerOrderlistWidget.count() - 1:
item = self.playerOrderlistWidget.takeItem(currentRow)
self.playerOrderlistWidget.insertItem(currentRow + 1, item)
self.playerOrderlistWidget.setCurrentRow(currentRow + 1)
self.usedPlayers.move(currentRow, currentRow + 1)
def onDownButtonClicked(self):
row = self.playerOrderlistWidget.currentRow()
if row == -1 or row > self.playerOrderlistWidget.count() - 1:
return
item = self.playerOrderlistWidget.takeItem(row)
self.playerOrderlistWidget.insertItem(row + 1, item)
self.playerOrderlistWidget.setCurrentRow(row + 1)
self.usedPlayers.move(row, row + 1)
def load(self):
self.usedPlayers = QtCore.QSettings().value(

View File

@ -85,7 +85,7 @@ class PresentationTab(SettingsTab):
self.AdvancedGroupBox.setTitle(UiStrings().Advanced)
self.OverrideAppCheckBox.setText(
translate('PresentationPlugin.PresentationTab',
'Allow presentation application to be overriden'))
'Allow presentation application to be overridden'))
def setControllerText(self, checkbox, controller):
if checkbox.isEnabled():

View File

@ -280,8 +280,15 @@ class Ui_EditSongDialog(object):
self.songTabWidget.addTab(self.audioTab, u'')
# Last few bits
self.dialogLayout.addWidget(self.songTabWidget)
self.bottomLayout = QtGui.QHBoxLayout()
self.bottomLayout.setObjectName(u'bottomLayout')
self.warningLabel = QtGui.QLabel(editSongDialog)
self.warningLabel.setObjectName(u'warningLabel')
self.warningLabel.setVisible(False)
self.bottomLayout.addWidget(self.warningLabel)
self.buttonBox = create_accept_reject_button_box(editSongDialog)
self.dialogLayout.addWidget(self.buttonBox)
self.bottomLayout.addWidget(self.buttonBox)
self.dialogLayout.addLayout(self.bottomLayout)
self.retranslateUi(editSongDialog)
QtCore.QMetaObject.connectSlotsByName(editSongDialog)
@ -349,14 +356,19 @@ class Ui_EditSongDialog(object):
translate('SongsPlugin.EditSongForm', '&Remove'))
self.audioRemoveAllButton.setText(
translate('SongsPlugin.EditSongForm', 'Remove &All'))
self.warningLabel.setText(
translate('SongsPlugin.EditSongForm', '<strong>Warning:</strong>'
' Not all of the verses are in use.'))
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.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
comboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
comboBox.setEditable(True)
comboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
comboBox.setObjectName(name)

View File

@ -92,6 +92,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtCore.QObject.connect(self.verseListWidget,
QtCore.SIGNAL(u'itemClicked(QTableWidgetItem*)'),
self.onVerseListViewPressed)
QtCore.QObject.connect(self.verseOrderEdit,
QtCore.SIGNAL(u'textChanged(QString)'),
self.onVerseOrderTextChanged)
QtCore.QObject.connect(self.themeAddButton,
QtCore.SIGNAL(u'clicked()'),
self.mediaitem.plugin.renderer.themeManager.onAddTheme)
@ -574,7 +577,76 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.verseEditButton.setEnabled(False)
self.verseDeleteButton.setEnabled(False)
def _validate_song(self):
def onVerseOrderTextChanged(self, text):
verses = []
verse_names = []
order = self.__extractVerseOrder(text)
for index in range(0, self.verseListWidget.rowCount()):
verse = self.verseListWidget.item(index, 0)
verse = unicode(verse.data(QtCore.Qt.UserRole).toString())
if verse not in verse_names:
verses.append(verse)
verse_names.append(u'%s%s' % (
VerseType.translated_tag(verse[0]), verse[1:]))
verses_not_used = []
for count, verse in enumerate(verses):
if not verse in order:
verses_not_used.append(verse)
self.warningLabel.setVisible(len(verses_not_used) > 0)
def __extractVerseOrder(self, verse_order):
order = []
order_names = unicode(verse_order).split()
for item in order_names:
if len(item) == 1:
verse_index = VerseType.from_translated_tag(item, None)
if verse_index is not None:
order.append(VerseType.Tags[verse_index] + u'1')
else:
# it matches no verses anyway
order.append(u'')
else:
verse_index = VerseType.from_translated_tag(item[0], None)
if verse_index is None:
# it matches no verses anyway
order.append(u'')
else:
verse_tag = VerseType.Tags[verse_index]
verse_num = item[1:].lower()
order.append(verse_tag + verse_num)
return order
def __validateVerseList(self, verse_order, verse_count):
verses = []
invalid_verses = []
verse_names = []
order_names = unicode(verse_order).split()
order = self.__extractVerseOrder(verse_order)
for index in range(0, verse_count):
verse = self.verseListWidget.item(index, 0)
verse = unicode(verse.data(QtCore.Qt.UserRole).toString())
if verse not in verse_names:
verses.append(verse)
verse_names.append(u'%s%s' % (
VerseType.translated_tag(verse[0]), verse[1:]))
for count, item in enumerate(order):
if item not in verses:
invalid_verses.append(order_names[count])
if invalid_verses:
valid = create_separated_list(verse_names)
if len(invalid_verses) > 1:
critical_error_message_box(message=unicode(translate(
'SongsPlugin.EditSongForm', 'The verse order is invalid. '
'There are no verses corresponding to %s. Valid entries '
'are %s.')) % (u', '.join(invalid_verses), valid))
else:
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.')) % (invalid_verses[0], valid))
return len(invalid_verses) == 0
def __validateSong(self):
"""
Check the validity of the song.
"""
@ -604,56 +676,10 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
'You need to have an author for this song.'))
return False
if self.verseOrderEdit.text():
order = []
order_names = unicode(self.verseOrderEdit.text()).split()
for item in order_names:
if len(item) == 1:
verse_index = VerseType.from_translated_tag(item, None)
if verse_index is not None:
order.append(VerseType.Tags[verse_index] + u'1')
else:
# it matches no verses anyway
order.append(u'')
else:
verse_index = VerseType.from_translated_tag(item[0], None)
if verse_index is None:
# it matches no verses anyway
order.append(u'')
else:
verse_tag = VerseType.Tags[verse_index]
verse_num = item[1:].lower()
order.append(verse_tag + verse_num)
verses = []
verse_names = []
for index in range(0, self.verseListWidget.rowCount()):
verse = self.verseListWidget.item(index, 0)
verse = unicode(verse.data(QtCore.Qt.UserRole).toString())
if verse not in verse_names:
verses.append(verse)
verse_names.append(u'%s%s' % (
VerseType.translated_tag(verse[0]), verse[1:]))
for count, item in enumerate(order):
if item not in verses:
valid = create_separated_list(verse_names)
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.')) % \
(order_names[count], valid))
return False
for count, verse in enumerate(verses):
if verse not in order:
self.songTabWidget.setCurrentIndex(0)
self.verseOrderEdit.setFocus()
answer = QtGui.QMessageBox.warning(self,
translate('SongsPlugin.EditSongForm', 'Warning'),
unicode(translate('SongsPlugin.EditSongForm',
'You have not used %s anywhere in the verse '
'order. Are you sure you want to save the song '
'like this?')) % verse_names[count],
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
return False
result = self.__validateVerseList(self.verseOrderEdit.text(),
self.verseListWidget.rowCount())
if not result:
return False
item = int(self.songBookComboBox.currentIndex())
text = unicode(self.songBookComboBox.currentText())
if self.songBookComboBox.findText(text, QtCore.Qt.MatchExactly) < 0:
@ -790,7 +816,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
"""
log.debug(u'SongEditForm.accept')
self.clearCaches()
if self._validate_song():
if self.__validateSong():
self.saveSong()
self.song = None
QtGui.QDialog.accept(self)

View File

@ -36,8 +36,7 @@ from sqlalchemy.sql import or_
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
translate, check_item_selected, PluginStatus, create_separated_list
from openlp.core.lib.ui import UiStrings, context_menu_action, \
context_menu_separator
from openlp.core.lib.ui import UiStrings, create_action, create_widget_action
from openlp.core.utils import AppLocation
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm, SongExportForm
@ -99,10 +98,11 @@ class SongMediaItem(MediaManagerItem):
self.plugin.manager.save_object(song, True)
def addEndHeaderBar(self):
self.addToolbarSeparator()
self.toolbar.addSeparator()
## Song Maintenance Button ##
self.maintenanceAction = self.addToolbarButton(u'', u'',
':/songs/song_maintenance.png', self.onSongMaintenanceClick)
self.maintenanceAction = self.toolbar.addToolbarAction(
u'maintenanceAction', icon=':/songs/song_maintenance.png',
triggers=self.onSongMaintenanceClick)
self.addSearchToToolBar()
# Signals and slots
QtCore.QObject.connect(Receiver.get_receiver(),
@ -122,11 +122,10 @@ class SongMediaItem(MediaManagerItem):
self.onSearchTextButtonClick)
def addCustomContextActions(self):
context_menu_separator(self.listView)
context_menu_action(
self.listView, u':/general/general_clone.png',
translate('OpenLP.MediaManagerItem',
'&Clone'), self.onCloneClick)
create_widget_action(self.listView, separator=True)
create_widget_action(self.listView,
text=translate('OpenLP.MediaManagerItem', '&Clone'),
icon=u':/general/general_clone.png', triggers=self.onCloneClick)
def onFocus(self):
self.searchTextEdit.setFocus()

View File

@ -38,6 +38,7 @@ from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.songs.lib.songimport import SongImport
from openlp.plugins.songs.lib.ui import SongStrings
from openlp.plugins.songs.lib import OpenLyrics
from openlp.plugins.songs.lib.xml import OpenLyricsError
log = logging.getLogger(__name__)
@ -73,3 +74,7 @@ class OpenLyricsImport(SongImport):
except etree.XMLSyntaxError:
log.exception(u'XML syntax error in file %s' % file_path)
self.logError(file_path, SongStrings.XMLSyntaxError)
except OpenLyricsError as exception:
log.exception(u'OpenLyricsException %d in file %s: %s'
% (exception.type, file_path, exception.log_message))
self.logError(file_path, exception.display_message)

View File

@ -238,7 +238,7 @@ class OpenSongImport(SongImport):
verse_tag = match.group(1)
verse_num = match.group(2)
if not len(verse_tag):
verse_tag = VerseType.Tags[VerseType.Verse]
verse_tag = VerseType.Tags[VerseType.Verse]
else:
# Assume it's no.1 if there are no digits
verse_tag = verse_def

View File

@ -31,6 +31,7 @@ Worship songs into the OpenLP database.
import os
import logging
from openlp.core.lib import translate
from openlp.plugins.songs.lib.songimport import SongImport
BLOCK_TYPES = (u'V', u'C', u'B')
@ -52,18 +53,19 @@ class WowImport(SongImport):
* A block can be a verse, chorus or bridge.
File Header:
Bytes are counted from one, i.e. the first byte is byte 1. These bytes,
up to the 56 byte, can change but no real meaning has been found. The
Bytes are counted from one, i.e. the first byte is byte 1. The first 19
bytes should be "WoW File \\nSong Words" The bytes after this and up to
the 56th byte, can change but no real meaning has been found. The
56th byte specifies how many blocks there are. The first block starts
with byte 83 after the "CSongDoc::CBlock" declaration.
Blocks:
Each block has a starting header, some lines of text, and an ending
footer. Each block starts with 4 bytes, the first byte specifies how
many lines are in that block, the next three bytes are null bytes.
footer. Each block starts with a 32 bit number, which specifies how
many lines are in that block.
Each block ends with 4 bytes, the first of which defines what type of
block it is, and the rest which are null bytes:
Each block ends with a 32 bit number, which defines what type of
block it is:
* ``NUL`` (0x00) - Verse
* ``SOH`` (0x01) - Chorus
@ -76,7 +78,6 @@ class WowImport(SongImport):
Each line starts with a byte which specifies how long that line is,
the line text, and ends with a null byte.
Footer:
The footer follows on after the last block, the first byte specifies
the length of the author text, followed by the author text, if
@ -107,22 +108,28 @@ class WowImport(SongImport):
for file in self.importSource:
if self.stopImportFlag:
return
file_name = os.path.split(file)[1]
# Get the song title
self.title = file_name.rpartition(u'.')[0]
self.setDefaults()
song_data = open(file, 'rb')
if song_data.read(19) != u'WoW File\nSong Words':
self.logError(file)
self.logError(file, unicode(
translate('SongsPlugin.WordsofWorshipSongImport',
('Invalid Words of Worship song file. Missing '
'"Wow File\\nSong Words" header.'))))
continue
# Seek to byte which stores number of blocks in the song
song_data.seek(56)
no_of_blocks = ord(song_data.read(1))
song_data.seek(66)
if song_data.read(16) != u'CSongDoc::CBlock':
self.logError(file, unicode(
translate('SongsPlugin.WordsofWorshipSongImport',
('Invalid Words of Worship song file. Missing '
'"CSongDoc::CBlock" string.'))))
continue
# Seek to the beging of the first block
song_data.seek(82)
for block in range(no_of_blocks):
self.linesToRead = ord(song_data.read(1))
# Skip 3 nulls to the beginnig of the 1st line
song_data.seek(3, os.SEEK_CUR)
self.linesToRead = ord(song_data.read(4)[:1])
block_text = u''
while self.linesToRead:
self.lineText = unicode(
@ -132,9 +139,7 @@ class WowImport(SongImport):
block_text += u'\n'
block_text += self.lineText
self.linesToRead -= 1
block_type = BLOCK_TYPES[ord(song_data.read(1))]
# Skip 3 nulls at the end of the block
song_data.seek(3, os.SEEK_CUR)
block_type = BLOCK_TYPES[ord(song_data.read(4)[:1])]
# Blocks are seperated by 2 bytes, skip them, but not if
# this is the last block!
if block + 1 < no_of_blocks:
@ -150,6 +155,9 @@ class WowImport(SongImport):
if copyright_length:
self.addCopyright(unicode(
song_data.read(copyright_length), u'cp1252'))
file_name = os.path.split(file)[1]
# Get the song title
self.title = file_name.rpartition(u'.')[0]
song_data.close()
if not self.finish():
self.logError(file)

View File

@ -66,7 +66,7 @@ import re
from lxml import etree, objectify
from openlp.core.lib import FormattingTags
from openlp.core.lib import FormattingTags, translate
from openlp.plugins.songs.lib import clean_song, VerseType
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic
from openlp.core.utils import get_application_version
@ -673,9 +673,22 @@ class OpenLyrics(object):
sxml = SongXML()
verses = {}
verse_def_list = []
lyrics = song_xml.lyrics
try:
lyrics = song_xml.lyrics
except AttributeError:
raise OpenLyricsError(OpenLyricsError.LyricsError,
'<lyrics> tag is missing.',
unicode(translate('OpenLP.OpenLyricsImportError',
'<lyrics> tag is missing.')))
try:
verse_list = lyrics.verse
except AttributeError:
raise OpenLyricsError(OpenLyricsError.VerseError,
'<verse> tag is missing.',
unicode(translate('OpenLP.OpenLyricsImportError',
'<verse> tag is missing.')))
# Loop over the "verse" elements.
for verse in lyrics.verse:
for verse in verse_list:
text = u''
# Loop over the "lines" elements.
for lines in verse.lines:
@ -791,3 +804,15 @@ class OpenLyrics(object):
"""
return etree.tostring(xml, encoding=u'UTF-8',
xml_declaration=True, pretty_print=True)
class OpenLyricsError(Exception):
# XML tree is missing the lyrics tag
LyricsError = 1
# XML tree has no verse tags
VerseError = 2
def __init__(self, type, log_message, display_message):
self.type = type
self.log_message = log_message
self.display_message = display_message

View File

@ -34,7 +34,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate, \
Receiver
from openlp.core.lib.db import Manager
from openlp.core.lib.ui import UiStrings, base_action, icon_action
from openlp.core.lib.ui import UiStrings, create_action
from openlp.core.utils.actions import ActionList
from openlp.plugins.songs.lib import clean_song, upgrade, SongMediaItem, \
SongsTab
@ -93,14 +93,12 @@ class SongsPlugin(Plugin):
use it as their parent.
"""
# Main song import menu item - will eventually be the only one
self.songImportItem = base_action(import_menu, u'songImportItem')
self.songImportItem.setText(translate('SongsPlugin', '&Song'))
self.songImportItem.setToolTip(translate('SongsPlugin',
'Import songs using the import wizard.'))
self.songImportItem = create_action(import_menu, u'songImportItem',
text=translate('SongsPlugin', '&Song'),
tooltip=translate('SongsPlugin',
'Import songs using the import wizard.'),
triggers=self.onSongImportItemClicked)
import_menu.addAction(self.songImportItem)
# Signals and slots
QtCore.QObject.connect(self.songImportItem,
QtCore.SIGNAL(u'triggered()'), self.onSongImportItemClicked)
def addExportMenuItem(self, export_menu):
"""
@ -112,14 +110,12 @@ class SongsPlugin(Plugin):
use it as their parent.
"""
# Main song import menu item - will eventually be the only one
self.songExportItem = base_action(export_menu, u'songExportItem')
self.songExportItem.setText(translate('SongsPlugin', '&Song'))
self.songExportItem.setToolTip(translate('SongsPlugin',
'Exports songs using the export wizard.'))
self.songExportItem = create_action(export_menu, u'songExportItem',
text=translate('SongsPlugin', '&Song'),
tooltip=translate('SongsPlugin',
'Exports songs using the export wizard.'),
triggers=self.onSongExportItemClicked)
export_menu.addAction(self.songExportItem)
# Signals and slots
QtCore.QObject.connect(self.songExportItem,
QtCore.SIGNAL(u'triggered()'), self.onSongExportItemClicked)
def addToolsMenuItem(self, tools_menu):
"""
@ -131,17 +127,13 @@ class SongsPlugin(Plugin):
use it as their parent.
"""
log.info(u'add tools menu')
self.toolsReindexItem = icon_action(tools_menu, u'toolsReindexItem',
u':/plugins/plugin_songs.png')
self.toolsReindexItem.setText(
translate('SongsPlugin', '&Re-index Songs'))
self.toolsReindexItem.setStatusTip(
translate('SongsPlugin', 'Re-index the songs database to improve '
'searching and ordering.'))
self.toolsReindexItem = create_action(tools_menu, u'toolsReindexItem',
text=translate('SongsPlugin', '&Re-index Songs'),
icon=u':/plugins/plugin_songs.png',
statustip=translate('SongsPlugin',
'Re-index the songs database to improve searching and ordering.'),
visible=False, triggers=self.onToolsReindexItemTriggered)
tools_menu.addAction(self.toolsReindexItem)
QtCore.QObject.connect(self.toolsReindexItem,
QtCore.SIGNAL(u'triggered()'), self.onToolsReindexItemTriggered)
self.toolsReindexItem.setVisible(False)
def onToolsReindexItemTriggered(self):
"""

View File

@ -33,7 +33,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, Receiver, build_icon, \
translate
from openlp.core.lib.db import Manager
from openlp.core.lib.ui import base_action, shortcut_action
from openlp.core.lib.ui import create_action
from openlp.core.utils.actions import ActionList
from openlp.plugins.songusage.forms import SongUsageDetailForm, \
SongUsageDeleteForm
@ -73,24 +73,24 @@ class SongUsagePlugin(Plugin):
self.songUsageMenu.setTitle(translate(
'SongUsagePlugin', '&Song Usage Tracking'))
# SongUsage Delete
self.songUsageDelete = base_action(tools_menu, u'songUsageDelete')
self.songUsageDelete.setText(translate('SongUsagePlugin',
'&Delete Tracking Data'))
self.songUsageDelete.setStatusTip(translate('SongUsagePlugin',
'Delete song usage data up to a specified date.'))
self.songUsageDelete = create_action(tools_menu, u'songUsageDelete',
text=translate('SongUsagePlugin', '&Delete Tracking Data'),
statustip=translate('SongUsagePlugin',
'Delete song usage data up to a specified date.'),
triggers=self.onSongUsageDelete)
# SongUsage Report
self.songUsageReport = base_action(tools_menu, u'songUsageReport')
self.songUsageReport.setText(
translate('SongUsagePlugin', '&Extract Tracking Data'))
self.songUsageReport.setStatusTip(
translate('SongUsagePlugin', 'Generate a report on song usage.'))
self.songUsageReport = create_action(tools_menu, u'songUsageReport',
text=translate('SongUsagePlugin', '&Extract Tracking Data'),
statustip=translate('SongUsagePlugin',
'Generate a report on song usage.'),
triggers=self.onSongUsageReport)
# SongUsage activation
self.songUsageStatus = shortcut_action(tools_menu, u'songUsageStatus',
[QtCore.Qt.Key_F4], self.toggleSongUsageState, checked=False)
self.songUsageStatus.setText(translate(
'SongUsagePlugin', 'Toggle Tracking'))
self.songUsageStatus.setStatusTip(translate('SongUsagePlugin',
'Toggle the tracking of song usage.'))
self.songUsageStatus = create_action(tools_menu, u'songUsageStatus',
text=translate('SongUsagePlugin', 'Toggle Tracking'),
statustip=translate('SongUsagePlugin',
'Toggle the tracking of song usage.'), checked=False,
shortcuts=[QtCore.Qt.Key_F4],
triggers=self.toggleSongUsageState)
# Add Menus together
self.toolsMenu.addAction(self.songUsageMenu.menuAction())
self.songUsageMenu.addAction(self.songUsageStatus)
@ -114,10 +114,6 @@ class SongUsagePlugin(Plugin):
QtCore.QObject.connect(self.songUsageActiveButton,
QtCore.SIGNAL(u'toggled(bool)'),
self.toggleSongUsageState)
QtCore.QObject.connect(self.songUsageDelete,
QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete)
QtCore.QObject.connect(self.songUsageReport,
QtCore.SIGNAL(u'triggered()'), self.onSongUsageReport)
self.songUsageMenu.menuAction().setVisible(False)
def initialise(self):