This commit is contained in:
Tim Bentley 2012-03-14 20:58:45 +00:00
commit 5b4ab7ce7c
47 changed files with 1192 additions and 1888 deletions

View File

@ -0,0 +1,7 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" />
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

View File

@ -328,7 +328,7 @@ def create_separated_list(stringlist):
``stringlist`` ``stringlist``
List of unicode strings List of unicode strings
""" """
if Qt.PYQT_VERSION_STR >= u'4.9': if Qt.PYQT_VERSION_STR >= u'4.9' and Qt.qVersion() >= u'4.8':
return unicode(QtCore.QLocale().createSeparatedList(stringlist)) return unicode(QtCore.QLocale().createSeparatedList(stringlist))
if not stringlist: if not stringlist:
return u'' return u''

View File

@ -199,6 +199,10 @@ class Manager(object):
urlquote(unicode(settings.value(u'db password').toString())), urlquote(unicode(settings.value(u'db password').toString())),
urlquote(unicode(settings.value(u'db hostname').toString())), urlquote(unicode(settings.value(u'db hostname').toString())),
urlquote(unicode(settings.value(u'db database').toString()))) urlquote(unicode(settings.value(u'db database').toString())))
if db_type == u'mysql':
db_encoding = unicode(
settings.value(u'db encoding', u'utf8').toString())
self.db_url += u'?charset=%s' % urlquote(db_encoding)
settings.endGroup() settings.endGroup()
if upgrade_mod: if upgrade_mod:
db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod) db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod)

View File

@ -36,8 +36,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \ from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \
StringContent, build_icon, translate, Receiver, ListWidgetWithDnD StringContent, build_icon, translate, Receiver, ListWidgetWithDnD
from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import UiStrings, context_menu_action, \ from openlp.core.lib.ui import UiStrings, create_widget_action, \
context_menu_separator, critical_error_message_box critical_error_message_box
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -147,43 +147,6 @@ class MediaManagerItem(QtGui.QWidget):
self.toolbar = OpenLPToolbar(self) self.toolbar = OpenLPToolbar(self)
self.pageLayout.addWidget(self.toolbar) 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): def setupUi(self):
""" """
This method sets up the interface on the button. Plugin This method sets up the interface on the button. Plugin
@ -208,40 +171,41 @@ class MediaManagerItem(QtGui.QWidget):
toolbar_actions = [] toolbar_actions = []
## Import Button ## ## Import Button ##
if self.hasImportIcon: if self.hasImportIcon:
toolbar_actions.append([StringContent.Import, toolbar_actions.append([u'Import', StringContent.Import,
u':/general/general_import.png', self.onImportClick]) u':/general/general_import.png', self.onImportClick])
## Load Button ## ## Load Button ##
if self.hasFileIcon: if self.hasFileIcon:
toolbar_actions.append([StringContent.Load, toolbar_actions.append([u'Load', StringContent.Load,
u':/general/general_open.png', self.onFileClick]) u':/general/general_open.png', self.onFileClick])
## New Button ## ## New Button ##
if self.hasNewIcon: if self.hasNewIcon:
toolbar_actions.append([StringContent.New, toolbar_actions.append([u'New', StringContent.New,
u':/general/general_new.png', self.onNewClick]) u':/general/general_new.png', self.onNewClick])
## Edit Button ## ## Edit Button ##
if self.hasEditIcon: if self.hasEditIcon:
toolbar_actions.append([StringContent.Edit, toolbar_actions.append([u'Edit', StringContent.Edit,
u':/general/general_edit.png', self.onEditClick]) u':/general/general_edit.png', self.onEditClick])
## Delete Button ## ## Delete Button ##
if self.hasDeleteIcon: if self.hasDeleteIcon:
toolbar_actions.append([StringContent.Delete, toolbar_actions.append([u'Delete', StringContent.Delete,
u':/general/general_delete.png', self.onDeleteClick]) u':/general/general_delete.png', self.onDeleteClick])
## Preview ## ## Preview ##
toolbar_actions.append([StringContent.Preview, toolbar_actions.append([u'Preview', StringContent.Preview,
u':/general/general_preview.png', self.onPreviewClick]) u':/general/general_preview.png', self.onPreviewClick])
## Live Button ## ## Live Button ##
toolbar_actions.append([StringContent.Live, toolbar_actions.append([u'Live', StringContent.Live,
u':/general/general_live.png', self.onLiveClick]) u':/general/general_live.png', self.onLiveClick])
## Add to service Button ## ## Add to service Button ##
toolbar_actions.append([StringContent.Service, toolbar_actions.append([u'Service', StringContent.Service,
u':/general/general_add.png', self.onAddClick]) u':/general/general_add.png', self.onAddClick])
for action in toolbar_actions: for action in toolbar_actions:
if action[0] == StringContent.Preview: if action[0] == StringContent.Preview:
self.addToolbarSeparator() self.toolbar.addSeparator()
self.addToolbarButton( self.toolbar.addToolbarAction(
self.plugin.getString(action[0])[u'title'], u'%s%sAction' % (self.plugin.name, action[0]),
self.plugin.getString(action[0])[u'tooltip'], text=self.plugin.getString(action[1])[u'title'], icon=action[2],
action[1], action[2]) tooltip=self.plugin.getString(action[1])[u'tooltip'],
triggers=action[3])
def addListViewToToolBar(self): def addListViewToToolBar(self):
""" """
@ -259,35 +223,37 @@ class MediaManagerItem(QtGui.QWidget):
# define and add the context menu # define and add the context menu
self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
if self.hasEditIcon: if self.hasEditIcon:
context_menu_action( create_widget_action(self.listView,
self.listView, u':/general/general_edit.png', text=self.plugin.getString(StringContent.Edit)[u'title'],
self.plugin.getString(StringContent.Edit)[u'title'], icon=u':/general/general_edit.png',
self.onEditClick) triggers=self.onEditClick)
context_menu_separator(self.listView) create_widget_action(self.listView, separator=True)
if self.hasDeleteIcon: if self.hasDeleteIcon:
context_menu_action( create_widget_action(self.listView,
self.listView, u':/general/general_delete.png', text=self.plugin.getString(StringContent.Delete)[u'title'],
self.plugin.getString(StringContent.Delete)[u'title'], icon=u':/general/general_delete.png',
self.onDeleteClick, [QtCore.Qt.Key_Delete]) shortcuts=[QtCore.Qt.Key_Delete], triggers=self.onDeleteClick)
context_menu_separator(self.listView) create_widget_action(self.listView, separator=True)
context_menu_action( create_widget_action(self.listView,
self.listView, u':/general/general_preview.png', text=self.plugin.getString(StringContent.Preview)[u'title'],
self.plugin.getString(StringContent.Preview)[u'title'], icon=u':/general/general_preview.png',
self.onPreviewClick, [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]) shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
context_menu_action( triggers=self.onPreviewClick)
self.listView, u':/general/general_live.png', create_widget_action(self.listView,
self.plugin.getString(StringContent.Live)[u'title'], text=self.plugin.getString(StringContent.Live)[u'title'],
self.onLiveClick, [QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Enter, icon=u':/general/general_live.png',
QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Return]) shortcuts=[QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter,
context_menu_action( QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return],
self.listView, u':/general/general_add.png', triggers=self.onLiveClick)
self.plugin.getString(StringContent.Service)[u'title'], create_widget_action(self.listView,
self.onAddClick, [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal]) 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: if self.addToServiceItem:
context_menu_action( create_widget_action(self.listView, text=translate(
self.listView, u':/general/general_add.png', 'OpenLP.MediaManagerItem', '&Add to selected Service Item'),
translate('OpenLP.MediaManagerItem', icon=u':/general/general_add.png', triggers=self.onAddEditClick)
'&Add to selected Service Item'), self.onAddEditClick)
self.addCustomContextActions() self.addCustomContextActions()
# Create the context menu and add all actions from the listView. # Create the context menu and add all actions from the listView.
self.menu = QtGui.QMenu() self.menu = QtGui.QMenu()

View File

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

View File

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

View File

@ -31,7 +31,7 @@ import logging
from PyQt4 import QtCore, QtGui 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__) log = logging.getLogger(__name__)
@ -46,122 +46,41 @@ class OpenLPToolbar(QtGui.QToolBar):
""" """
QtGui.QToolBar.__init__(self, parent) QtGui.QToolBar.__init__(self, parent)
# useful to be able to reuse button icons... # useful to be able to reuse button icons...
self.icons = {}
self.setIconSize(QtCore.QSize(20, 20)) self.setIconSize(QtCore.QSize(20, 20))
self.actions = {} self.actions = {}
log.debug(u'Init done for %s' % parent.__class__.__name__) log.debug(u'Init done for %s' % parent.__class__.__name__)
def addToolbarButton(self, title, icon, tooltip=None, slot=None, def addToolbarAction(self, name, **kwargs):
checkable=False, shortcuts=None, context=QtCore.Qt.WidgetShortcut):
""" """
A method to help developers easily add a button to the toolbar. A method to help developers easily add a button to the toolbar.
A new QAction is created by calling ``create_action()``. The action is
``title`` added to the toolbar and the toolbar is set as parent.
The title of the button. For more details please look at openlp.core.lib.ui.create_action()
``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
""" """
if icon: action = create_widget_action(self, name, **kwargs)
actionIcon = build_icon(icon) self.actions[name] = action
if slot and not checkable: return action
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
def addToolbarSeparator(self, handle): def addToolbarWidget(self, widget):
""" """
Add a Separator bar to the toolbar and store it's Handle Add a widget and store it's handle under the widgets object name.
"""
action = self.addSeparator()
self.actions[handle] = action
def addToolbarWidget(self, handle, widget):
"""
Add a Widget to the toolbar and store it's Handle
""" """
action = self.addWidget(widget) 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, Set the visibitity for a widget or a list of widgets.
and return that icon.
``title`` ``widget``
The title of the icon to search for. A list of string with widget object names.
"""
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()
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

@ -93,6 +93,7 @@ class UiStrings(object):
self.New = translate('OpenLP.Ui', 'New') self.New = translate('OpenLP.Ui', 'New')
self.NewService = translate('OpenLP.Ui', 'New Service') self.NewService = translate('OpenLP.Ui', 'New Service')
self.NewTheme = translate('OpenLP.Ui', 'New Theme') self.NewTheme = translate('OpenLP.Ui', 'New Theme')
self.NextTrack = translate('OpenLP.Ui', 'Next Track')
self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular') self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular')
self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural') self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular') self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
@ -280,100 +281,102 @@ def create_up_down_push_button_set(parent):
QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked) QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked)
return up_button, down_button 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`` ``parent``
The category the action should be listed in the shortcut dialog. If you A QtCore.QObject for the actions parent (required).
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
def checkable_action(parent, name, checked=None, category=None): ``name``
""" A string which is set as object name (required).
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
``text`` ``text``
The text to display for this action A string for the action text.
``slot`` ``icon``
The code to run when this action is triggered 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`` ``shortcuts``
The action's shortcuts. A QList<QKeySequence> (or a list of strings) which are set as 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.
``context`` ``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) action = QtGui.QAction(parent)
if icon: action.setObjectName(name)
action.setIcon(build_icon(icon)) if kwargs.get(u'text'):
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), slot) action.setText(kwargs.pop(u'text'))
if shortcuts is not None: if kwargs.get(u'icon'):
action.setShortcuts(shortcuts) action.setIcon(build_icon(kwargs.pop(u'icon')))
action.setShortcutContext(context) 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 = ActionList.get_instance()
action_list.add_action(action) action_list.add_action(action, unicode(kwargs.pop(u'category')))
base.addAction(action) 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 return action
def context_menu(base, icon, text): def context_menu(base, icon, text):
@ -393,18 +396,6 @@ def context_menu(base, icon, text):
action.setIcon(build_icon(icon)) action.setIcon(build_icon(icon))
return action 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): def add_widget_completer(cache, widget):
""" """
Adds a text autocompleter to a widget. Adds a text autocompleter to a widget.

View File

@ -357,7 +357,7 @@ class AdvancedTab(SettingsTab):
translate('OpenLP.GeneralTab', '&Next Item')) translate('OpenLP.GeneralTab', '&Next Item'))
self.nextItemLabel.setText( self.nextItemLabel.setText(
translate('OpenLP.GeneralTab', 'Up and down arrow keys ' 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.')) 'top and bottom slides of each Service Item.'))
def load(self): def load(self):

View File

@ -150,7 +150,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
translate('OpenLP.ExceptionForm', translate('OpenLP.ExceptionForm',
'Text files (*.txt *.log *.text)')) 'Text files (*.txt *.log *.text)'))
if filename: 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( SettingsManager.set_last_dir(self.settingsSection, os.path.dirname(
filename)) filename))
report_text = report_text % self._createReport() report_text = report_text % self._createReport()

View File

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

View File

@ -175,6 +175,9 @@ class GeneralTab(SettingsTab):
self.startPausedCheckBox = QtGui.QCheckBox(self.audioGroupBox) self.startPausedCheckBox = QtGui.QCheckBox(self.audioGroupBox)
self.startPausedCheckBox.setObjectName(u'startPausedCheckBox') self.startPausedCheckBox.setObjectName(u'startPausedCheckBox')
self.audioLayout.addWidget(self.startPausedCheckBox) self.audioLayout.addWidget(self.startPausedCheckBox)
self.repeatListCheckBox = QtGui.QCheckBox(self.audioGroupBox)
self.repeatListCheckBox.setObjectName(u'repeatListCheckBox')
self.audioLayout.addWidget(self.repeatListCheckBox)
self.rightLayout.addWidget(self.audioGroupBox) self.rightLayout.addWidget(self.audioGroupBox)
self.rightLayout.addStretch() self.rightLayout.addStretch()
# Signals and slots # Signals and slots
@ -251,6 +254,8 @@ class GeneralTab(SettingsTab):
translate('OpenLP.GeneralTab', 'Background Audio')) translate('OpenLP.GeneralTab', 'Background Audio'))
self.startPausedCheckBox.setText( self.startPausedCheckBox.setText(
translate('OpenLP.GeneralTab', 'Start background audio paused')) translate('OpenLP.GeneralTab', 'Start background audio paused'))
self.repeatListCheckBox.setText(
translate('OpenLP.GeneralTab', 'Repeat track list'))
def load(self): def load(self):
""" """
@ -298,6 +303,8 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0]) QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0])
self.startPausedCheckBox.setChecked(settings.value( self.startPausedCheckBox.setChecked(settings.value(
u'audio start paused', QtCore.QVariant(True)).toBool()) u'audio start paused', QtCore.QVariant(True)).toBool())
self.repeatListCheckBox.setChecked(settings.value(
u'audio repeat list', QtCore.QVariant(False)).toBool())
settings.endGroup() settings.endGroup()
self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked()) self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
@ -350,6 +357,8 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(self.overrideCheckBox.isChecked())) QtCore.QVariant(self.overrideCheckBox.isChecked()))
settings.setValue(u'audio start paused', settings.setValue(u'audio start paused',
QtCore.QVariant(self.startPausedCheckBox.isChecked())) QtCore.QVariant(self.startPausedCheckBox.isChecked()))
settings.setValue(u'audio repeat list',
QtCore.QVariant(self.repeatListCheckBox.isChecked()))
settings.endGroup() settings.endGroup()
# On save update the screens as well # On save update the screens as well
self.postSetUp(True) self.postSetUp(True)

View File

@ -30,7 +30,6 @@ and play multimedia within OpenLP.
""" """
import cgi import cgi
import logging import logging
import os
import sys import sys
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
@ -38,6 +37,7 @@ from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, \ from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, \
translate, PluginManager, expand_tags translate, PluginManager, expand_tags
from openlp.core.lib.theme import BackgroundType
from openlp.core.ui import HideMode, ScreenList, AlertLocation from openlp.core.ui import HideMode, ScreenList, AlertLocation
@ -136,15 +136,15 @@ class MainDisplay(Display):
QtCore.Qt.WindowStaysOnTopHint QtCore.Qt.WindowStaysOnTopHint
if QtCore.QSettings().value(u'advanced/x11 bypass wm', if QtCore.QSettings().value(u'advanced/x11 bypass wm',
QtCore.QVariant(True)).toBool(): QtCore.QVariant(True)).toBool():
windowFlags = windowFlags | QtCore.Qt.X11BypassWindowManagerHint windowFlags |= QtCore.Qt.X11BypassWindowManagerHint
# FIXME: QtCore.Qt.SplashScreen is workaround to make display screen # FIXME: QtCore.Qt.SplashScreen is workaround to make display screen
# stay always on top on Mac OS X. For details see bug 906926. # stay always on top on Mac OS X. For details see bug 906926.
# It needs more investigation to fix it properly. # It needs more investigation to fix it properly.
if sys.platform == 'darwin': if sys.platform == 'darwin':
windowFlags = windowFlags | QtCore.Qt.SplashScreen windowFlags |= QtCore.Qt.SplashScreen
self.setWindowFlags(windowFlags) self.setWindowFlags(windowFlags)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setTransparency(True) self.setTransparency(False)
if self.isLive: if self.isLive:
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_display_hide'), self.hideDisplay) QtCore.SIGNAL(u'live_display_hide'), self.hideDisplay)
@ -388,6 +388,8 @@ class MainDisplay(Display):
# replace the background # replace the background
background = self.imageManager. \ background = self.imageManager. \
get_image_bytes(self.override[u'image']) 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: if self.serviceItem.themedata.background_filename:
self.serviceItem.bg_image_bytes = self.imageManager. \ self.serviceItem.bg_image_bytes = self.imageManager. \
get_image_bytes(self.serviceItem.themedata.theme_name) get_image_bytes(self.serviceItem.themedata.theme_name)
@ -493,11 +495,15 @@ class AudioPlayer(QtCore.QObject):
QtCore.QObject.__init__(self, parent) QtCore.QObject.__init__(self, parent)
self.currentIndex = -1 self.currentIndex = -1
self.playlist = [] self.playlist = []
self.repeat = False
self.mediaObject = Phonon.MediaObject() self.mediaObject = Phonon.MediaObject()
self.mediaObject.setTickInterval(100)
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory) self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self.audioObject) Phonon.createPath(self.mediaObject, self.audioObject)
QtCore.QObject.connect(self.mediaObject, QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish) QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'), self.onFinished)
def __del__(self): def __del__(self):
""" """
@ -516,6 +522,14 @@ class AudioPlayer(QtCore.QObject):
if len(self.playlist) > self.currentIndex: if len(self.playlist) > self.currentIndex:
self.mediaObject.enqueue(self.playlist[self.currentIndex]) self.mediaObject.enqueue(self.playlist[self.currentIndex])
def onFinished(self):
if self.repeat:
log.debug(u'Repeat is enabled... here we go again!')
self.mediaObject.clearQueue()
self.mediaObject.clear()
self.currentIndex = -1
self.play()
def connectVolumeSlider(self, slider): def connectVolumeSlider(self, slider):
slider.setAudioOutput(self.audioObject) slider.setAudioOutput(self.audioObject)
@ -563,3 +577,27 @@ class AudioPlayer(QtCore.QObject):
for filename in filenames: for filename in filenames:
self.playlist.append(Phonon.MediaSource(filename)) self.playlist.append(Phonon.MediaSource(filename))
def next(self):
if not self.repeat and self.currentIndex + 1 == len(self.playlist):
return
isPlaying = self.mediaObject.state() == Phonon.PlayingState
self.currentIndex += 1
if self.repeat and self.currentIndex == len(self.playlist):
self.currentIndex = 0
self.mediaObject.clearQueue()
self.mediaObject.clear()
self.mediaObject.enqueue(self.playlist[self.currentIndex])
if isPlaying:
self.mediaObject.play()
def goTo(self, index):
isPlaying = self.mediaObject.state() == Phonon.PlayingState
self.mediaObject.clearQueue()
self.mediaObject.clear()
self.currentIndex = index
self.mediaObject.enqueue(self.playlist[self.currentIndex])
if isPlaying:
self.mediaObject.play()
def connectSlot(self, signal, slot):
QtCore.QObject.connect(self.mediaObject, signal, slot)

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -33,8 +33,8 @@ from collections import deque
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \ from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \
translate, build_icon, ServiceItem, build_html, PluginManager, ServiceItem 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.lib import SlideLimits, ServiceItemAction
from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList
from openlp.core.utils.actions import ActionList, CategoryOrder from openlp.core.utils.actions import ActionList, CategoryOrder
@ -46,9 +46,10 @@ class SlideList(QtGui.QTableWidget):
Customised version of QTableWidget which can respond to keyboard Customised version of QTableWidget which can respond to keyboard
events. events.
""" """
def __init__(self, parent=None, name=None): def __init__(self, parent=None):
QtGui.QTableWidget.__init__(self, parent.controller) QtGui.QTableWidget.__init__(self, parent.controller)
class Controller(QtGui.QWidget): class Controller(QtGui.QWidget):
""" """
Controller is a general controller widget. Controller is a general controller widget.
@ -91,16 +92,14 @@ class SlideController(Controller):
self.imageManager = self.parent().imageManager self.imageManager = self.parent().imageManager
self.mediaController = self.parent().mediaController self.mediaController = self.parent().mediaController
self.loopList = [ self.loopList = [
u'Play Slides Menu', u'playSlidesMenu',
u'Loop Separator', u'loopSeparator',
u'Image SpinBox' u'delaySpinBox'
] ]
self.songEditList = [ self.audioList = [
u'Edit Song', u'songMenu',
] u'audioPauseItem',
self.nextPreviousList = [ u'audioTimeLabel'
u'Previous Slide',
u'Next Slide'
] ]
self.timer_id = 0 self.timer_id = 0
self.songEdit = False self.songEdit = False
@ -122,10 +121,14 @@ class SlideController(Controller):
self.typePrefix = u'live' self.typePrefix = u'live'
self.keypress_queue = deque() self.keypress_queue = deque()
self.keypress_loop = False self.keypress_loop = False
self.category = UiStrings().LiveToolbar
ActionList.get_instance().add_category(
unicode(self.category), CategoryOrder.standardToolbar)
else: else:
self.typeLabel.setText(UiStrings().Preview) self.typeLabel.setText(UiStrings().Preview)
self.split = 0 self.split = 0
self.typePrefix = u'preview' self.typePrefix = u'preview'
self.category = None
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;') self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
self.typeLabel.setAlignment(QtCore.Qt.AlignCenter) self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
self.panelLayout.addWidget(self.typeLabel) self.panelLayout.addWidget(self.typeLabel)
@ -168,72 +171,71 @@ class SlideController(Controller):
sizeToolbarPolicy.setHeightForWidth( sizeToolbarPolicy.setHeightForWidth(
self.toolbar.sizePolicy().hasHeightForWidth()) self.toolbar.sizePolicy().hasHeightForWidth())
self.toolbar.setSizePolicy(sizeToolbarPolicy) self.toolbar.setSizePolicy(sizeToolbarPolicy)
self.previousItem = self.toolbar.addToolbarButton( self.previousItem = create_action(self,
u'Previous Slide', u'previousItem_' + self.typePrefix,
u':/slides/slide_previous.png', text=translate('OpenLP.SlideController', 'Previous Slide'),
translate('OpenLP.SlideController', 'Move to previous.'), icon=u':/slides/slide_previous.png',
self.onSlideSelectedPrevious, tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp], shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp],
context=QtCore.Qt.WidgetWithChildrenShortcut) context=QtCore.Qt.WidgetWithChildrenShortcut,
self.nextItem = self.toolbar.addToolbarButton( category=self.category, triggers=self.onSlideSelectedPrevious)
u'Next Slide', self.toolbar.addAction(self.previousItem)
u':/slides/slide_next.png', self.nextItem = create_action(self, u'nextItem_' + self.typePrefix,
translate('OpenLP.SlideController', 'Move to next.'), text=translate('OpenLP.SlideController', 'Next Slide'),
self.onSlideSelectedNext, icon=u':/slides/slide_next.png',
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown], shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown],
context=QtCore.Qt.WidgetWithChildrenShortcut) context=QtCore.Qt.WidgetWithChildrenShortcut,
self.toolbar.addToolbarSeparator(u'Close Separator') category=self.category, triggers=self.onSlideSelectedNext)
self.toolbar.addAction(self.nextItem)
self.toolbar.addSeparator()
if self.isLive: if self.isLive:
# Hide Menu # Hide Menu
self.hideMenu = QtGui.QToolButton(self.toolbar) self.hideMenu = QtGui.QToolButton(self.toolbar)
self.hideMenu.setObjectName(u'hideMenu')
self.hideMenu.setText(translate('OpenLP.SlideController', 'Hide')) self.hideMenu.setText(translate('OpenLP.SlideController', 'Hide'))
self.hideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup) self.hideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.toolbar.addToolbarWidget(u'Hide Menu', self.hideMenu)
self.hideMenu.setMenu(QtGui.QMenu( self.hideMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Hide'), self.toolbar)) translate('OpenLP.SlideController', 'Hide'), self.toolbar))
self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen', self.toolbar.addToolbarWidget(self.hideMenu)
[QtCore.Qt.Key_Period], self.onBlankDisplay, self.blankScreen = create_action(self, u'blankScreen',
u':/slides/slide_blank.png', False, text=translate('OpenLP.SlideController', 'Blank Screen'),
unicode(UiStrings().LiveToolbar)) icon=u':/slides/slide_blank.png', checked=False,
self.blankScreen.setText( shortcuts=[QtCore.Qt.Key_Period],
translate('OpenLP.SlideController', 'Blank Screen')) category=self.category, triggers=self.onBlankDisplay)
self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen', self.themeScreen = create_action(self, u'themeScreen',
[QtGui.QKeySequence(u'T')], self.onThemeDisplay, text=translate('OpenLP.SlideController', 'Blank to Theme'),
u':/slides/slide_theme.png', False, icon=u':/slides/slide_theme.png', checked=False,
unicode(UiStrings().LiveToolbar)) shortcuts=[QtGui.QKeySequence(u'T')],
self.themeScreen.setText( category=self.category, triggers=self.onThemeDisplay)
translate('OpenLP.SlideController', 'Blank to Theme')) self.desktopScreen = create_action(self, u'desktopScreen',
self.desktopScreen = shortcut_action(self.hideMenu, text=translate('OpenLP.SlideController', 'Show Desktop'),
u'desktopScreen', [QtGui.QKeySequence(u'D')], icon=u':/slides/slide_desktop.png', checked=False,
self.onHideDisplay, u':/slides/slide_desktop.png', False, shortcuts=[QtGui.QKeySequence(u'D')],
unicode(UiStrings().LiveToolbar)) category=self.category, triggers=self.onHideDisplay)
self.desktopScreen.setText(
translate('OpenLP.SlideController', 'Show Desktop'))
self.hideMenu.setDefaultAction(self.blankScreen) self.hideMenu.setDefaultAction(self.blankScreen)
self.hideMenu.menu().addAction(self.blankScreen) self.hideMenu.menu().addAction(self.blankScreen)
self.hideMenu.menu().addAction(self.themeScreen) self.hideMenu.menu().addAction(self.themeScreen)
self.hideMenu.menu().addAction(self.desktopScreen) self.hideMenu.menu().addAction(self.desktopScreen)
self.toolbar.addToolbarSeparator(u'Loop Separator') self.toolbar.addToolbarAction(u'loopSeparator', separator=True)
# Play Slides Menu # Play Slides Menu
self.playSlidesMenu = QtGui.QToolButton(self.toolbar) self.playSlidesMenu = QtGui.QToolButton(self.toolbar)
self.playSlidesMenu.setObjectName(u'playSlidesMenu')
self.playSlidesMenu.setText(translate('OpenLP.SlideController', self.playSlidesMenu.setText(translate('OpenLP.SlideController',
'Play Slides')) 'Play Slides'))
self.playSlidesMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup) self.playSlidesMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.toolbar.addToolbarWidget(u'Play Slides Menu',
self.playSlidesMenu)
self.playSlidesMenu.setMenu(QtGui.QMenu( self.playSlidesMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Play Slides'), translate('OpenLP.SlideController', 'Play Slides'),
self.toolbar)) self.toolbar))
self.playSlidesLoop = shortcut_action(self.playSlidesMenu, self.toolbar.addToolbarWidget(self.playSlidesMenu)
u'playSlidesLoop', [], self.onPlaySlidesLoop, self.playSlidesLoop = create_action(self, u'playSlidesLoop',
u':/media/media_time.png', False, text=UiStrings().PlaySlidesInLoop,
unicode(UiStrings().LiveToolbar)) icon=u':/media/media_time.png', checked=False, shortcuts=[],
self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop) category=self.category, triggers=self.onPlaySlidesLoop)
self.playSlidesOnce = shortcut_action(self.playSlidesMenu, self.playSlidesOnce = create_action(self, u'playSlidesOnce',
u'playSlidesOnce', [], self.onPlaySlidesOnce, text=UiStrings().PlaySlidesToEnd,
u':/media/media_time.png', False, icon=u':/media/media_time.png', checked=False, shortcuts=[],
unicode(UiStrings().LiveToolbar)) category=self.category, triggers=self.onPlaySlidesOnce)
self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
if QtCore.QSettings().value(self.parent().generalSettingsSection + if QtCore.QSettings().value(self.parent().generalSettingsSection +
u'/enable slide loop', QtCore.QVariant(True)).toBool(): u'/enable slide loop', QtCore.QVariant(True)).toBool():
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop) self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
@ -243,47 +245,75 @@ class SlideController(Controller):
self.playSlidesMenu.menu().addAction(self.playSlidesOnce) self.playSlidesMenu.menu().addAction(self.playSlidesOnce)
# Loop Delay Spinbox # Loop Delay Spinbox
self.delaySpinBox = QtGui.QSpinBox() self.delaySpinBox = QtGui.QSpinBox()
self.delaySpinBox.setObjectName(u'delaySpinBox')
self.delaySpinBox.setRange(1, 180) self.delaySpinBox.setRange(1, 180)
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
self.delaySpinBox.setSuffix(UiStrings().Seconds) self.delaySpinBox.setSuffix(UiStrings().Seconds)
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController', self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
'Delay between slides in seconds.')) 'Delay between slides in seconds.'))
self.toolbar.addToolbarWidget(self.delaySpinBox)
else: else:
self.toolbar.addToolbarButton( self.toolbar.addToolbarAction(u'goLive',
# Does not need translating - control string. icon=u':/general/general_live.png',
u'Go Live', u':/general/general_live.png', tooltip=translate('OpenLP.SlideController', 'Move to live.'),
translate('OpenLP.SlideController', 'Move to live.'), triggers=self.onGoLive)
self.onGoLive) self.toolbar.addToolbarAction(u'addToService',
self.toolbar.addToolbarButton( icon=u':/general/general_add.png',
# Does not need translating - control string. tooltip=translate('OpenLP.SlideController', 'Add to Service.'),
u'Add to Service', u':/general/general_add.png', triggers=self.onPreviewAddToService)
translate('OpenLP.SlideController', 'Add to Service.'), self.toolbar.addSeparator()
self.onPreviewAddToService) self.toolbar.addToolbarAction(u'editSong',
self.toolbar.addToolbarSeparator(u'Close Separator') icon=u':/general/general_edit.png',
self.toolbar.addToolbarButton( tooltip=translate('OpenLP.SlideController',
# Does not need translating - control string. 'Edit and reload song preview.'), triggers=self.onEditSong)
u'Edit Song', u':/general/general_edit.png',
translate('OpenLP.SlideController',
'Edit and reload song preview.'),
self.onEditSong)
self.controllerLayout.addWidget(self.toolbar) self.controllerLayout.addWidget(self.toolbar)
# Build the Media Toolbar # Build the Media Toolbar
self.mediaController.add_controller_items(self, self.controllerLayout) self.mediaController.add_controller_items(self, self.controllerLayout)
if self.isLive: if self.isLive:
# Build the Song Toolbar # Build the Song Toolbar
self.songMenu = QtGui.QToolButton(self.toolbar) self.songMenu = QtGui.QToolButton(self.toolbar)
self.songMenu.setObjectName(u'songMenu')
self.songMenu.setText(translate('OpenLP.SlideController', 'Go To')) self.songMenu.setText(translate('OpenLP.SlideController', 'Go To'))
self.songMenu.setPopupMode(QtGui.QToolButton.InstantPopup) self.songMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
self.toolbar.addToolbarWidget(u'Song Menu', self.songMenu)
self.songMenu.setMenu(QtGui.QMenu( self.songMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Go To'), self.toolbar)) translate('OpenLP.SlideController', 'Go To'), self.toolbar))
self.toolbar.makeWidgetsInvisible([u'Song Menu']) self.toolbar.addToolbarWidget(self.songMenu)
# Stuff for items with background audio. # Stuff for items with background audio.
self.audioPauseItem = self.toolbar.addToolbarButton( self.audioPauseItem = self.toolbar.addToolbarAction(
u'Pause Audio', u':/slides/media_playback_pause.png', u'audioPauseItem', icon=u':/slides/media_playback_pause.png',
translate('OpenLP.SlideController', 'Pause audio.'), text=translate('OpenLP.SlideController', 'Pause Audio'),
self.onAudioPauseClicked, True) tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
self.audioPauseItem.setVisible(False) checked=False, visible=False, category=self.category,
triggers=self.onAudioPauseClicked)
self.audioMenu = QtGui.QMenu(
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.audioTimeLabel = QtGui.QLabel(u' 00:00 ', self.toolbar)
self.audioTimeLabel.setAlignment(
QtCore.Qt.AlignCenter|QtCore.Qt.AlignHCenter)
self.audioTimeLabel.setStyleSheet(
u'background-color: palette(background); '
u'border-top-color: palette(shadow); '
u'border-left-color: palette(shadow); '
u'border-bottom-color: palette(light); '
u'border-right-color: palette(light); '
u'border-radius: 3px; border-style: inset; '
u'border-width: 1; font-family: monospace; margin: 2px;'
)
self.audioTimeLabel.setObjectName(u'audioTimeLabel')
self.toolbar.addToolbarWidget(self.audioTimeLabel)
self.toolbar.setWidgetVisible(self.audioList, False)
# Screen preview area # Screen preview area
self.previewFrame = QtGui.QFrame(self.splitter) self.previewFrame = QtGui.QFrame(self.splitter)
self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio)) self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio))
@ -328,89 +358,31 @@ class SlideController(Controller):
self.shortcutTimer = QtCore.QTimer() self.shortcutTimer = QtCore.QTimer()
self.shortcutTimer.setObjectName(u'shortcutTimer') self.shortcutTimer.setObjectName(u'shortcutTimer')
self.shortcutTimer.setSingleShot(True) self.shortcutTimer.setSingleShot(True)
self.verseShortcut = shortcut_action(self, u'verseShortcut', shortcuts = [{u'key': u'V', u'configurable': True,
[QtGui.QKeySequence(u'V')], self.slideShortcutActivated, u'text': translate('OpenLP.SlideController', 'Go to "Verse"')},
category=unicode(UiStrings().LiveToolbar), {u'key': u'C', u'configurable': True,
context=QtCore.Qt.WidgetWithChildrenShortcut) u'text': translate('OpenLP.SlideController', 'Go to "Chorus"')},
self.verseShortcut.setText(translate( {u'key': u'B', u'configurable': True,
'OpenLP.SlideController', 'Go to "Verse"')) u'text': translate('OpenLP.SlideController', 'Go to "Bridge"')},
self.shortcut0 = shortcut_action(self, u'0', {u'key': u'P', u'configurable': True,
[QtGui.QKeySequence(u'0')], self.slideShortcutActivated, u'text': translate('OpenLP.SlideController',
context=QtCore.Qt.WidgetWithChildrenShortcut) 'Go to "Pre-Chorus"')},
self.shortcut1 = shortcut_action(self, u'1', {u'key': u'I', u'configurable': True,
[QtGui.QKeySequence(u'1')], self.slideShortcutActivated, u'text': translate('OpenLP.SlideController', 'Go to "Intro"')},
context=QtCore.Qt.WidgetWithChildrenShortcut) {u'key': u'E', u'configurable': True,
self.shortcut2 = shortcut_action(self, u'2', u'text': translate('OpenLP.SlideController', 'Go to "Ending"')},
[QtGui.QKeySequence(u'2')], self.slideShortcutActivated, {u'key': u'O', u'configurable': True,
context=QtCore.Qt.WidgetWithChildrenShortcut) u'text': translate('OpenLP.SlideController', 'Go to "Other"')}]
self.shortcut3 = shortcut_action(self, u'3', shortcuts += [{u'key': unicode(number)} for number in range(0, 10)]
[QtGui.QKeySequence(u'3')], self.slideShortcutActivated, self.previewListWidget.addActions([create_action(self,
context=QtCore.Qt.WidgetWithChildrenShortcut) u'shortcutAction_%s' % s[u'key'], text=s.get(u'text'),
self.shortcut4 = shortcut_action(self, u'4', shortcuts=[QtGui.QKeySequence(s[u'key'])],
[QtGui.QKeySequence(u'4')], self.slideShortcutActivated, context=QtCore.Qt.WidgetWithChildrenShortcut,
context=QtCore.Qt.WidgetWithChildrenShortcut) category=self.category if s.get(u'configurable') else None,
self.shortcut5 = shortcut_action(self, u'5', triggers=self._slideShortcutActivated) for s in shortcuts])
[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
])
QtCore.QObject.connect( QtCore.QObject.connect(
self.shortcutTimer, QtCore.SIGNAL(u'timeout()'), self.shortcutTimer, QtCore.SIGNAL(u'timeout()'),
self.slideShortcutActivated) self._slideShortcutActivated)
# Signals # Signals
QtCore.QObject.connect(self.previewListWidget, QtCore.QObject.connect(self.previewListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected) QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
@ -421,20 +393,18 @@ class SlideController(Controller):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_toggle_display'), QtCore.SIGNAL(u'slidecontroller_toggle_display'),
self.toggleDisplay) self.toggleDisplay)
self.toolbar.makeWidgetsInvisible(self.loopList) self.toolbar.setWidgetVisible(self.loopList, False)
else: else:
QtCore.QObject.connect(self.previewListWidget, QtCore.QObject.connect(self.previewListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onGoLiveClick) self.onGoLiveClick)
self.toolbar.makeWidgetsInvisible(self.songEditList) self.toolbar.setWidgetVisible([u'editSong'], False)
if self.isLive: if self.isLive:
self.setLiveHotkeys(self) self.setLiveHotkeys(self)
self.__addActionsToWidget(self.previewListWidget) self.__addActionsToWidget(self.previewListWidget)
else: else:
self.setPreviewHotkeys()
self.previewListWidget.addActions( self.previewListWidget.addActions(
[self.nextItem, [self.nextItem, self.previousItem])
self.previousItem])
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix), QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix),
self.onStopLoop) self.onStopLoop)
@ -460,7 +430,7 @@ class SlideController(Controller):
QtCore.SIGNAL(u'slidecontroller_update_slide_limits'), QtCore.SIGNAL(u'slidecontroller_update_slide_limits'),
self.updateSlideLimits) self.updateSlideLimits)
def slideShortcutActivated(self): def _slideShortcutActivated(self):
""" """
Called, when a shortcut has been activated to jump to a chorus, verse, Called, when a shortcut has been activated to jump to a chorus, verse,
etc. etc.
@ -476,52 +446,38 @@ class SlideController(Controller):
SONGS_PLUGIN_AVAILABLE = True SONGS_PLUGIN_AVAILABLE = True
except ImportError: except ImportError:
SONGS_PLUGIN_AVAILABLE = False SONGS_PLUGIN_AVAILABLE = False
verse_type = unicode(self.sender().objectName()) sender_name = unicode(self.sender().objectName())
if verse_type.startswith(u'verseShortcut'): verse_type = sender_name[15:] \
if sender_name[:15] == u'shortcutAction_' else u''
if SONGS_PLUGIN_AVAILABLE: if SONGS_PLUGIN_AVAILABLE:
if verse_type == u'V':
self.current_shortcut = \ self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Verse] VerseType.TranslatedTags[VerseType.Verse]
else: elif verse_type == u'C':
self.current_shortcut = u'V'
elif verse_type.startswith(u'chorusShortcut'):
if SONGS_PLUGIN_AVAILABLE:
self.current_shortcut = \ self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Chorus] VerseType.TranslatedTags[VerseType.Chorus]
else: elif verse_type == u'B':
self.current_shortcut = u'C'
elif verse_type.startswith(u'bridgeShortcut'):
if SONGS_PLUGIN_AVAILABLE:
self.current_shortcut = \ self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Bridge] VerseType.TranslatedTags[VerseType.Bridge]
else: elif verse_type == u'P':
self.current_shortcut = u'B'
elif verse_type.startswith(u'preChorusShortcut'):
if SONGS_PLUGIN_AVAILABLE:
self.current_shortcut = \ self.current_shortcut = \
VerseType.TranslatedTags[VerseType.PreChorus] VerseType.TranslatedTags[VerseType.PreChorus]
else: elif verse_type == u'I':
self.current_shortcut = u'P'
elif verse_type.startswith(u'introShortcut'):
if SONGS_PLUGIN_AVAILABLE:
self.current_shortcut = \ self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Intro] VerseType.TranslatedTags[VerseType.Intro]
else: elif verse_type == u'E':
self.current_shortcut = u'I'
elif verse_type.startswith(u'endingShortcut'):
if SONGS_PLUGIN_AVAILABLE:
self.current_shortcut = \ self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Ending] VerseType.TranslatedTags[VerseType.Ending]
else: elif verse_type == u'O':
self.current_shortcut = u'E'
elif verse_type.startswith(u'otherShortcut'):
if SONGS_PLUGIN_AVAILABLE:
self.current_shortcut = \ self.current_shortcut = \
VerseType.TranslatedTags[VerseType.Other] VerseType.TranslatedTags[VerseType.Other]
else:
self.current_shortcut = u'O'
elif verse_type.isnumeric(): elif verse_type.isnumeric():
self.current_shortcut += verse_type self.current_shortcut += verse_type
self.current_shortcut = self.current_shortcut.upper() self.current_shortcut = self.current_shortcut.upper()
elif verse_type.isnumeric():
self.current_shortcut += verse_type
elif verse_type:
self.current_shortcut = verse_type
keys = self.slideList.keys() keys = self.slideList.keys()
matches = [match for match in keys matches = [match for match in keys
if match.startswith(self.current_shortcut)] if match.startswith(self.current_shortcut)]
@ -530,7 +486,7 @@ class SlideController(Controller):
self.current_shortcut = u'' self.current_shortcut = u''
self.__checkUpdateSelectedSlide(self.slideList[matches[0]]) self.__checkUpdateSelectedSlide(self.slideList[matches[0]])
self.slideSelected() self.slideSelected()
elif verse_type != u'shortcutTimer': elif sender_name != u'shortcutTimer':
# Start the time as we did not have any match. # Start the time as we did not have any match.
self.shortcutTimer.start(350) self.shortcutTimer.start(350)
else: else:
@ -544,39 +500,22 @@ class SlideController(Controller):
# Reset the shortcut. # Reset the shortcut.
self.current_shortcut = u'' self.current_shortcut = u''
def setPreviewHotkeys(self, parent=None):
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): def setLiveHotkeys(self, parent=None):
self.previousItem.setObjectName(u'previousItemLive') self.previousService = create_action(parent, u'previousService',
self.nextItem.setObjectName(u'nextItemLive') text=translate('OpenLP.SlideController', 'Previous Service'),
action_list = ActionList.get_instance() shortcuts=[QtCore.Qt.Key_Left],
action_list.add_category( context=QtCore.Qt.WidgetWithChildrenShortcut,
unicode(UiStrings().LiveToolbar), CategoryOrder.standardToolbar) category=self.category, triggers=self.servicePrevious)
action_list.add_action(self.previousItem) self.nextService = create_action(parent, 'nextService',
action_list.add_action(self.nextItem) text=translate('OpenLP.SlideController', 'Next Service'),
self.previousService = shortcut_action(parent, u'previousService', shortcuts=[QtCore.Qt.Key_Right],
[QtCore.Qt.Key_Left], self.servicePrevious, context=QtCore.Qt.WidgetWithChildrenShortcut,
category=unicode(UiStrings().LiveToolbar), category=self.category, triggers=self.serviceNext)
context=QtCore.Qt.WidgetWithChildrenShortcut) self.escapeItem = create_action(parent, 'escapeItem',
self.previousService.setText( text=translate('OpenLP.SlideController', 'Escape Item'),
translate('OpenLP.SlideController', 'Previous Service')) shortcuts=[QtCore.Qt.Key_Escape],
self.nextService = shortcut_action(parent, 'nextService', context=QtCore.Qt.WidgetWithChildrenShortcut,
[QtCore.Qt.Key_Right], self.serviceNext, category=self.category, triggers=self.liveEscape)
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'))
def liveEscape(self): def liveEscape(self):
self.display.setVisible(False) self.display.setVisible(False)
@ -621,7 +560,7 @@ class SlideController(Controller):
self.keypress_loop = True self.keypress_loop = True
keypressCommand = self.keypress_queue.popleft() keypressCommand = self.keypress_queue.popleft()
if keypressCommand == ServiceItemAction.Previous: if keypressCommand == ServiceItemAction.Previous:
Receiver.send_message('servicemanager_previous_item', None) Receiver.send_message('servicemanager_previous_item')
elif keypressCommand == ServiceItemAction.PreviousLastSlide: elif keypressCommand == ServiceItemAction.PreviousLastSlide:
# Go to the last slide of the previous item # Go to the last slide of the previous item
Receiver.send_message('servicemanager_previous_item', u'last slide') Receiver.send_message('servicemanager_previous_item', u'last slide')
@ -642,6 +581,8 @@ class SlideController(Controller):
self.display.setup() self.display.setup()
if self.isLive: if self.isLive:
self.__addActionsToWidget(self.display) self.__addActionsToWidget(self.display)
self.display.audioPlayer.connectSlot(
QtCore.SIGNAL(u'tick(qint64)'), self.onAudioTimeRemaining)
# The SlidePreview's ratio. # The SlidePreview's ratio.
try: try:
self.ratio = float(self.screens.current[u'size'].width()) / \ self.ratio = float(self.screens.current[u'size'].width()) / \
@ -653,7 +594,7 @@ class SlideController(Controller):
self.previewDisplay.setup() self.previewDisplay.setup()
serviceItem = ServiceItem() serviceItem = ServiceItem()
self.previewDisplay.webView.setHtml(build_html(serviceItem, self.previewDisplay.webView.setHtml(build_html(serviceItem,
self.previewDisplay.screen, None, self.isLive, None, self.previewDisplay.screen, None, self.isLive,
plugins=PluginManager.get_instance().plugins)) plugins=PluginManager.get_instance().plugins))
self.mediaController.setup_display(self.previewDisplay) self.mediaController.setup_display(self.previewDisplay)
if self.serviceItem: if self.serviceItem:
@ -741,9 +682,9 @@ class SlideController(Controller):
# Work-around for OS X, hide and then show the toolbar # Work-around for OS X, hide and then show the toolbar
# See bug #791050 # See bug #791050
self.toolbar.hide() self.toolbar.hide()
self.mediabar.setVisible(False) self.mediabar.hide()
self.toolbar.makeWidgetsInvisible([u'Song Menu']) self.songMenu.hide()
self.toolbar.makeWidgetsInvisible(self.loopList) self.toolbar.setWidgetVisible(self.loopList, False)
# Reset the button # Reset the button
self.playSlidesOnce.setChecked(False) self.playSlidesOnce.setChecked(False)
self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png')) self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png'))
@ -753,17 +694,16 @@ class SlideController(Controller):
if QtCore.QSettings().value( if QtCore.QSettings().value(
self.parent().songsSettingsSection + u'/display songbar', self.parent().songsSettingsSection + u'/display songbar',
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0: 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 \ if item.is_capable(ItemCapabilities.CanLoop) and \
len(item.get_frames()) > 1: len(item.get_frames()) > 1:
self.toolbar.makeWidgetsVisible(self.loopList) self.toolbar.setWidgetVisible(self.loopList)
if item.is_media(): if item.is_media():
self.mediabar.setVisible(True) self.mediabar.show()
self.toolbar.makeWidgetsInvisible(self.nextPreviousList) self.previousItem.setVisible(not item.is_media())
else: self.nextItem.setVisible(not item.is_media())
# Work-around for OS X, hide and then show the toolbar # Work-around for OS X, hide and then show the toolbar
# See bug #791050 # See bug #791050
self.toolbar.makeWidgetsVisible(self.nextPreviousList)
self.toolbar.show() self.toolbar.show()
def enablePreviewToolBar(self, item): def enablePreviewToolBar(self, item):
@ -773,17 +713,16 @@ class SlideController(Controller):
# Work-around for OS X, hide and then show the toolbar # Work-around for OS X, hide and then show the toolbar
# See bug #791050 # See bug #791050
self.toolbar.hide() self.toolbar.hide()
self.mediabar.setVisible(False) self.mediabar.hide()
self.toolbar.makeWidgetsInvisible(self.songEditList) self.toolbar.setWidgetVisible([u'editSong'], False)
if item.is_capable(ItemCapabilities.CanEdit) and item.from_plugin: if item.is_capable(ItemCapabilities.CanEdit) and item.from_plugin:
self.toolbar.makeWidgetsVisible(self.songEditList) self.toolbar.setWidgetVisible([u'editSong'])
elif item.is_media(): elif item.is_media():
self.mediabar.setVisible(True) self.mediabar.show()
self.toolbar.makeWidgetsInvisible(self.nextPreviousList) self.previousItem.setVisible(not item.is_media())
if not item.is_media(): self.nextItem.setVisible(not item.is_media())
# Work-around for OS X, hide and then show the toolbar # Work-around for OS X, hide and then show the toolbar
# See bug #791050 # See bug #791050
self.toolbar.makeWidgetsVisible(self.nextPreviousList)
self.toolbar.show() self.toolbar.show()
def refreshServiceItem(self): def refreshServiceItem(self):
@ -860,10 +799,23 @@ class SlideController(Controller):
self.display.audioPlayer.reset() self.display.audioPlayer.reset()
self.setAudioItemsVisibility(False) self.setAudioItemsVisibility(False)
self.audioPauseItem.setChecked(False) self.audioPauseItem.setChecked(False)
# If the current item has background audio
if self.serviceItem.is_capable(ItemCapabilities.HasBackgroundAudio): if self.serviceItem.is_capable(ItemCapabilities.HasBackgroundAudio):
log.debug(u'Starting to play...') log.debug(u'Starting to play...')
self.display.audioPlayer.addToPlaylist( self.display.audioPlayer.addToPlaylist(
self.serviceItem.background_audio) self.serviceItem.background_audio)
self.trackMenu.clear()
for counter in range(len(self.serviceItem.background_audio)):
action = self.trackMenu.addAction(os.path.basename(
self.serviceItem.background_audio[counter]))
action.setData(counter)
QtCore.QObject.connect(action,
QtCore.SIGNAL(u'triggered(bool)'),
self.onTrackTriggered)
self.display.audioPlayer.repeat = QtCore.QSettings().value(
self.parent().generalSettingsSection + \
u'/audio repeat list',
QtCore.QVariant(False)).toBool()
if QtCore.QSettings().value( if QtCore.QSettings().value(
self.parent().generalSettingsSection + \ self.parent().generalSettingsSection + \
u'/audio start paused', u'/audio start paused',
@ -915,7 +867,7 @@ class SlideController(Controller):
self.slideList[unicode(row)] = row - 1 self.slideList[unicode(row)] = row - 1
text.append(unicode(row)) text.append(unicode(row))
self.previewListWidget.setItem(framenumber, 0, item) self.previewListWidget.setItem(framenumber, 0, item)
if slideHeight != 0: if slideHeight:
self.previewListWidget.setRowHeight(framenumber, slideHeight) self.previewListWidget.setRowHeight(framenumber, slideHeight)
self.previewListWidget.setVerticalHeaderLabels(text) self.previewListWidget.setVerticalHeaderLabels(text)
if self.serviceItem.is_text(): if self.serviceItem.is_text():
@ -1117,7 +1069,7 @@ class SlideController(Controller):
else: else:
Receiver.send_message(u'live_display_show') Receiver.send_message(u'live_display_show')
def onSlideSelected(self, start=False): def onSlideSelected(self):
""" """
Slide selected in controller Slide selected in controller
""" """
@ -1130,7 +1082,7 @@ class SlideController(Controller):
""" """
row = self.previewListWidget.currentRow() row = self.previewListWidget.currentRow()
self.selectedRow = 0 self.selectedRow = 0
if row > -1 and row < self.previewListWidget.rowCount(): if -1 < row < self.previewListWidget.rowCount():
if self.serviceItem.is_command(): if self.serviceItem.is_command():
if self.isLive and not start: if self.isLive and not start:
Receiver.send_message( Receiver.send_message(
@ -1266,7 +1218,7 @@ class SlideController(Controller):
""" """
Stop the timer loop running Stop the timer loop running
""" """
if self.timer_id != 0: if self.timer_id:
self.killTimer(self.timer_id) self.killTimer(self.timer_id)
self.timer_id = 0 self.timer_id = 0
@ -1313,7 +1265,7 @@ class SlideController(Controller):
self.onToggleLoop() self.onToggleLoop()
def setAudioItemsVisibility(self, visible): def setAudioItemsVisibility(self, visible):
self.audioPauseItem.setVisible(visible) self.toolbar.setWidgetVisible(self.audioList, visible)
def onAudioPauseClicked(self, checked): def onAudioPauseClicked(self, checked):
if not self.audioPauseItem.isVisible(): if not self.audioPauseItem.isVisible():
@ -1367,7 +1319,7 @@ class SlideController(Controller):
If preview copy slide item to live If preview copy slide item to live
""" """
row = self.previewListWidget.currentRow() row = self.previewListWidget.currentRow()
if row > -1 and row < self.previewListWidget.rowCount(): if -1 < row < self.previewListWidget.rowCount():
if self.serviceItem.from_service: if self.serviceItem.from_service:
Receiver.send_message('servicemanager_preview_live', Receiver.send_message('servicemanager_preview_live',
u'%s:%s' % (self.serviceItem._uuid, row)) u'%s:%s' % (self.serviceItem._uuid, row))
@ -1424,3 +1376,17 @@ class SlideController(Controller):
return HideMode.Screen return HideMode.Screen
else: else:
return None return None
def onNextTrackClicked(self):
self.display.audioPlayer.next()
def onAudioTimeRemaining(self, time):
seconds = self.display.audioPlayer.mediaObject.remainingTime() // 1000
minutes = seconds // 60
seconds %= 60
self.audioTimeLabel.setText(u' %02d:%02d ' % (minutes, seconds))
def onTrackTriggered(self):
action = self.sender()
index = action.data().toInt()[0]
self.display.audioPlayer.goTo(index)

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, \ from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \
BackgroundGradientType BackgroundGradientType
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \ 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.theme import Theme
from openlp.core.ui import FileRenameForm, ThemeForm from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding 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.setMargin(0)
self.layout.setObjectName(u'layout') self.layout.setObjectName(u'layout')
self.toolbar = OpenLPToolbar(self) 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.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.layout.addWidget(self.toolbar)
self.themeWidget = QtGui.QWidgetAction(self.toolbar) self.themeWidget = QtGui.QWidgetAction(self.toolbar)
self.themeWidget.setObjectName(u'themeWidget') self.themeWidget.setObjectName(u'themeWidget')
@ -105,29 +105,26 @@ class ThemeManager(QtGui.QWidget):
self.contextMenu) self.contextMenu)
# build the context menu # build the context menu
self.menu = QtGui.QMenu() self.menu = QtGui.QMenu()
self.editAction = context_menu_action( self.editAction = create_widget_action(self.menu,
self.menu, u':/themes/theme_edit.png', text=translate('OpenLP.ThemeManager', '&Edit Theme'),
translate('OpenLP.ThemeManager', '&Edit Theme'), self.onEditTheme) icon=u':/themes/theme_edit.png', triggers=self.onEditTheme)
self.copyAction = context_menu_action( self.copyAction = create_widget_action(self.menu,
self.menu, u':/themes/theme_edit.png', text=translate('OpenLP.ThemeManager', '&Copy Theme'),
translate('OpenLP.ThemeManager', '&Copy Theme'), self.onCopyTheme) icon=u':/themes/theme_edit.png', triggers=self.onCopyTheme)
self.renameAction = context_menu_action( self.renameAction = create_widget_action(self.menu,
self.menu, u':/themes/theme_edit.png', text=translate('OpenLP.ThemeManager', '&Rename Theme'),
translate('OpenLP.ThemeManager', '&Rename Theme'), icon=u':/themes/theme_edit.png', triggers=self.onRenameTheme)
self.onRenameTheme) self.deleteAction = create_widget_action(self.menu,
self.deleteAction = context_menu_action( text=translate('OpenLP.ThemeManager', '&Delete Theme'),
self.menu, u':/general/general_delete.png', icon=u':/general/general_delete.png', triggers=self.onDeleteTheme)
translate('OpenLP.ThemeManager', '&Delete Theme'), self.menu.addSeparator()
self.onDeleteTheme) self.globalAction = create_widget_action(self.menu,
context_menu_separator(self.menu) text=translate('OpenLP.ThemeManager', 'Set As &Global Default'),
self.globalAction = context_menu_action( icon=u':/general/general_export.png',
self.menu, u':/general/general_export.png', triggers=self.changeGlobalFromScreen)
translate('OpenLP.ThemeManager', 'Set As &Global Default'), self.exportAction = create_widget_action(self.menu,
self.changeGlobalFromScreen) text=translate('OpenLP.ThemeManager', '&Export Theme'),
self.exportAction = context_menu_action( icon=u':/general/general_export.png', triggers=self.onExportTheme)
self.menu, u':/general/general_export.png',
translate('OpenLP.ThemeManager', '&Export Theme'),
self.onExportTheme)
# Signals # Signals
QtCore.QObject.connect(self.themeListWidget, QtCore.QObject.connect(self.themeListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
@ -159,7 +156,7 @@ class ThemeManager(QtGui.QWidget):
encoding = get_filesystem_encoding() encoding = get_filesystem_encoding()
files = SettingsManager.get_files(self.settingsSection, u'.otz') files = SettingsManager.get_files(self.settingsSection, u'.otz')
for file in files: 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) self.unzipTheme(file, self.path)
delete_file(file) delete_file(file)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
@ -544,7 +541,7 @@ class ThemeManager(QtGui.QWidget):
log.exception(u'Theme file contains non utf-8 filename' log.exception(u'Theme file contains non utf-8 filename'
u' "%s"' % name.decode(u'utf-8', u'replace')) u' "%s"' % name.decode(u'utf-8', u'replace'))
raise Exception(u'validation') raise Exception(u'validation')
uname = unicode(QtCore.QDir.toNativeSeparators(uname)) uname = uname.replace(u'/', os.path.sep)
splitname = uname.split(os.path.sep) splitname = uname.split(os.path.sep)
if splitname[-1] == u'' or len(splitname) == 1: if splitname[-1] == u'' or len(splitname) == 1:
# is directory or preview file # is directory or preview file

View File

@ -400,7 +400,7 @@ def clean_filename(filename):
""" """
if not isinstance(filename, unicode): if not isinstance(filename, unicode):
filename = unicode(filename, u'utf-8') 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): def delete_file(file_path_name):
""" """

View File

@ -281,7 +281,7 @@ class ActionList(object):
return return
self.categories[category].actions.remove(action) self.categories[category].actions.remove(action)
# Remove empty categories. # Remove empty categories.
if len(self.categories[category].actions) == 0: if not self.categories[category].actions:
self.categories.remove(category) self.categories.remove(category)
shortcuts = map(unicode, shortcuts = map(unicode,
map(QtGui.QKeySequence.toString, action.shortcuts())) map(QtGui.QKeySequence.toString, action.shortcuts()))
@ -354,19 +354,32 @@ class ActionList(object):
``action`` ``action``
The action which wants to use a particular shortcut. 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: for existing_action in existing_actions:
if action is existing_action: if action is existing_action:
continue continue
if existing_action.parent() is action.parent(): if not local or existing_action in affected_actions:
return False return False
if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, if existing_action.shortcutContext() \
QtCore.Qt.ApplicationShortcut]: in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
return False return False
if action.shortcutContext() in [QtCore.Qt.WindowShortcut, elif action in self.getAllChildObjects(existing_action.parent()):
QtCore.Qt.ApplicationShortcut]:
return False return False
return True 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): 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 import Plugin, StringContent, build_icon, translate
from openlp.core.lib.db import Manager 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.lib.theme import VerticalType
from openlp.core.utils.actions import ActionList from openlp.core.utils.actions import ActionList
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
@ -133,16 +133,12 @@ class AlertsPlugin(Plugin):
use it as their parent. use it as their parent.
""" """
log.info(u'add tools menu') log.info(u'add tools menu')
self.toolsAlertItem = icon_action(tools_menu, u'toolsAlertItem', self.toolsAlertItem = create_action(tools_menu, u'toolsAlertItem',
u':/plugins/plugin_alerts.png') text=translate('AlertsPlugin', '&Alert'),
self.toolsAlertItem.setText(translate('AlertsPlugin', '&Alert')) icon=u':/plugins/plugin_alerts.png',
self.toolsAlertItem.setStatusTip( statustip=translate('AlertsPlugin', 'Show an alert message.'),
translate('AlertsPlugin', 'Show an alert message.')) visible=False, shortcuts=[u'F7'], triggers=self.onAlertsTrigger)
self.toolsAlertItem.setShortcut(u'F7')
self.serviceManager.mainwindow.toolsMenu.addAction(self.toolsAlertItem) 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): def initialise(self):
log.info(u'Alerts Initialising') log.info(u'Alerts Initialising')

View File

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

View File

@ -972,7 +972,6 @@ class BibleMediaItem(MediaManagerItem):
The verse number (int). The verse number (int).
""" """
verse_separator = get_reference_separator(u'sep_v_display') verse_separator = get_reference_separator(u'sep_v_display')
if not self.settings.show_new_chapters or old_chapter != chapter:
verse_text = unicode(chapter) + verse_separator + unicode(verse) verse_text = unicode(chapter) + verse_separator + unicode(verse)
else: else:
verse_text = unicode(verse) verse_text = unicode(verse)

View File

@ -53,6 +53,7 @@ class OSISBible(BibleDB):
self.filename = kwargs[u'filename'] self.filename = kwargs[u'filename']
fbibles = None fbibles = None
self.books = {} self.books = {}
self.language_regex = re.compile(r'<language.*>(.*?)</language>')
self.verse_regex = re.compile( self.verse_regex = re.compile(
r'<verse osisID="([a-zA-Z0-9 ]*).([0-9]*).([0-9]*)">(.*?)</verse>') r'<verse osisID="([a-zA-Z0-9 ]*).([0-9]*).([0-9]*)">(.*?)</verse>')
self.note_regex = re.compile(r'<note(.*?)>(.*?)</note>') self.note_regex = re.compile(r'<note(.*?)>(.*?)</note>')
@ -107,19 +108,32 @@ class OSISBible(BibleDB):
finally: finally:
if detect_file: if detect_file:
detect_file.close() detect_file.close()
# Set meta language_id
language_id = self.get_language(bible_name)
if not language_id:
log.exception(u'Importing books from "%s" failed' % self.filename)
return False
try: try:
osis = codecs.open(self.filename, u'r', details['encoding']) osis = codecs.open(self.filename, u'r', details['encoding'])
repl = replacement repl = replacement
language_id = False
for file_record in osis: for file_record in osis:
if self.stop_import_flag: if self.stop_import_flag:
break break
# Try to find the bible language
if not language_id:
language_match = self.language_regex.search(file_record)
if language_match:
language = BiblesResourcesDB.get_language(
language_match.group(1))
if language:
language_id = language[u'id']
self.create_meta(u'language_id', language_id)
continue
match = self.verse_regex.search(file_record) match = self.verse_regex.search(file_record)
if match: if match:
# Set meta language_id if not detected till now
if not language_id:
language_id = self.get_language(bible_name)
if not language_id:
log.exception(u'Importing books from "%s" failed'
% self.filename)
return False
match_count += 1 match_count += 1
book = match.group(1) book = match.group(1)
chapter = int(match.group(2)) chapter = int(match.group(2))

View File

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

View File

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

View File

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

View File

@ -28,7 +28,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate, Receiver 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 MediaTab(SettingsTab): class MediaTab(SettingsTab):
""" """
@ -57,7 +57,7 @@ class MediaTab(SettingsTab):
self.leftLayout.addWidget(self.mediaPlayerGroupBox) self.leftLayout.addWidget(self.mediaPlayerGroupBox)
self.playerOrderGroupBox = QtGui.QGroupBox(self.leftColumn) self.playerOrderGroupBox = QtGui.QGroupBox(self.leftColumn)
self.playerOrderGroupBox.setObjectName(u'playerOrderGroupBox') self.playerOrderGroupBox.setObjectName(u'playerOrderGroupBox')
self.playerOrderLayout = QtGui.QVBoxLayout(self.playerOrderGroupBox) self.playerOrderLayout = QtGui.QHBoxLayout(self.playerOrderGroupBox)
self.playerOrderLayout.setObjectName(u'playerOrderLayout') self.playerOrderLayout.setObjectName(u'playerOrderLayout')
self.playerOrderlistWidget = QtGui.QListWidget( \ self.playerOrderlistWidget = QtGui.QListWidget( \
self.playerOrderGroupBox) self.playerOrderGroupBox)
@ -76,18 +76,15 @@ class MediaTab(SettingsTab):
QtGui.QAbstractItemView.NoEditTriggers) QtGui.QAbstractItemView.NoEditTriggers)
self.playerOrderlistWidget.setObjectName(u'playerOrderlistWidget') self.playerOrderlistWidget.setObjectName(u'playerOrderlistWidget')
self.playerOrderLayout.addWidget(self.playerOrderlistWidget) self.playerOrderLayout.addWidget(self.playerOrderlistWidget)
self.orderingButtonsWidget = QtGui.QWidget(self.playerOrderGroupBox) self.orderingButtonLayout = QtGui.QVBoxLayout()
self.orderingButtonsWidget.setObjectName(u'orderingButtonsWidget')
self.orderingButtonLayout = QtGui.QHBoxLayout( \
self.orderingButtonsWidget)
self.orderingButtonLayout.setObjectName(u'orderingButtonLayout') self.orderingButtonLayout.setObjectName(u'orderingButtonLayout')
self.orderingDownButton = QtGui.QPushButton(self.orderingButtonsWidget) self.orderingButtonLayout.addStretch(1)
self.orderingDownButton.setObjectName(u'orderingDownButton') self.orderingUpButton, self.orderingDownButton = \
self.orderingButtonLayout.addWidget(self.orderingDownButton) create_up_down_push_button_set(self)
self.orderingUpButton = QtGui.QPushButton(self.playerOrderGroupBox)
self.orderingUpButton.setObjectName(u'orderingUpButton')
self.orderingButtonLayout.addWidget(self.orderingUpButton) 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.leftLayout.addWidget(self.playerOrderGroupBox)
self.advancedGroupBox = QtGui.QGroupBox(self.leftColumn) self.advancedGroupBox = QtGui.QGroupBox(self.leftColumn)
self.advancedGroupBox.setObjectName(u'advancedGroupBox') self.advancedGroupBox.setObjectName(u'advancedGroupBox')
@ -105,10 +102,6 @@ class MediaTab(SettingsTab):
QtCore.QObject.connect(checkbox, QtCore.QObject.connect(checkbox,
QtCore.SIGNAL(u'stateChanged(int)'), QtCore.SIGNAL(u'stateChanged(int)'),
self.onPlayerCheckBoxChanged) 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): def retranslateUi(self):
self.mediaPlayerGroupBox.setTitle( self.mediaPlayerGroupBox.setTitle(
@ -124,14 +117,10 @@ class MediaTab(SettingsTab):
'%s (unavailable)')) % player.name) '%s (unavailable)')) % player.name)
self.playerOrderGroupBox.setTitle( self.playerOrderGroupBox.setTitle(
translate('MediaPlugin.MediaTab', 'Player Order')) translate('MediaPlugin.MediaTab', 'Player Order'))
self.orderingDownButton.setText(
translate('MediaPlugin.MediaTab', 'Down'))
self.orderingUpButton.setText(
translate('MediaPlugin.MediaTab', 'Up'))
self.advancedGroupBox.setTitle(UiStrings().Advanced) self.advancedGroupBox.setTitle(UiStrings().Advanced)
self.overridePlayerCheckBox.setText( self.overridePlayerCheckBox.setText(
translate('MediaPlugin.MediaTab', translate('MediaPlugin.MediaTab',
'Allow media player to be overriden')) 'Allow media player to be overridden'))
def onPlayerCheckBoxChanged(self, check_state): def onPlayerCheckBoxChanged(self, check_state):
player = self.sender().text() player = self.sender().text()
@ -154,21 +143,23 @@ class MediaTab(SettingsTab):
self.playerCheckBoxes[u'%s' % player].setEnabled(True) self.playerCheckBoxes[u'%s' % player].setEnabled(True)
self.playerOrderlistWidget.addItem(player) self.playerOrderlistWidget.addItem(player)
def onOrderingUpButtonPressed(self): def onUpButtonClicked(self):
currentRow = self.playerOrderlistWidget.currentRow() row = self.playerOrderlistWidget.currentRow()
if currentRow > 0: if row <= 0:
item = self.playerOrderlistWidget.takeItem(currentRow) return
self.playerOrderlistWidget.insertItem(currentRow - 1, item) item = self.playerOrderlistWidget.takeItem(row)
self.playerOrderlistWidget.setCurrentRow(currentRow - 1) self.playerOrderlistWidget.insertItem(row - 1, item)
self.usedPlayers.move(currentRow, currentRow - 1) self.playerOrderlistWidget.setCurrentRow(row - 1)
self.usedPlayers.move(row, row - 1)
def onOrderingDownButtonPressed(self): def onDownButtonClicked(self):
currentRow = self.playerOrderlistWidget.currentRow() row = self.playerOrderlistWidget.currentRow()
if currentRow < self.playerOrderlistWidget.count() - 1: if row == -1 or row > self.playerOrderlistWidget.count() - 1:
item = self.playerOrderlistWidget.takeItem(currentRow) return
self.playerOrderlistWidget.insertItem(currentRow + 1, item) item = self.playerOrderlistWidget.takeItem(row)
self.playerOrderlistWidget.setCurrentRow(currentRow + 1) self.playerOrderlistWidget.insertItem(row + 1, item)
self.usedPlayers.move(currentRow, currentRow + 1) self.playerOrderlistWidget.setCurrentRow(row + 1)
self.usedPlayers.move(row, row + 1)
def load(self): def load(self):
if self.savedUsedPlayers: if self.savedUsedPlayers:

View File

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

View File

@ -27,6 +27,7 @@
--> -->
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1" />
<title>${app_title}</title> <title>${app_title}</title>
<link rel="stylesheet" href="/files/jquery.mobile.css" /> <link rel="stylesheet" href="/files/jquery.mobile.css" />
<link rel="stylesheet" href="/files/openlp.css" /> <link rel="stylesheet" href="/files/openlp.css" />

View File

@ -36,14 +36,13 @@ from sqlalchemy.sql import or_
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
translate, check_item_selected, PluginStatus, create_separated_list translate, check_item_selected, PluginStatus, create_separated_list
from openlp.core.lib.ui import UiStrings, context_menu_action, \ from openlp.core.lib.ui import UiStrings, create_action, create_widget_action
context_menu_separator
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm, SongExportForm SongImportForm, SongExportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \ from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \
clean_string clean_string
from openlp.plugins.songs.lib.db import Author, Song, MediaFile from openlp.plugins.songs.lib.db import Author, Song, Book, MediaFile
from openlp.plugins.songs.lib.ui import SongStrings from openlp.plugins.songs.lib.ui import SongStrings
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -56,7 +55,8 @@ class SongSearch(object):
Titles = 2 Titles = 2
Lyrics = 3 Lyrics = 3
Authors = 4 Authors = 4
Themes = 5 Books = 5
Themes = 6
class SongMediaItem(MediaManagerItem): class SongMediaItem(MediaManagerItem):
@ -98,10 +98,11 @@ class SongMediaItem(MediaManagerItem):
self.plugin.manager.save_object(song, True) self.plugin.manager.save_object(song, True)
def addEndHeaderBar(self): def addEndHeaderBar(self):
self.addToolbarSeparator() self.toolbar.addSeparator()
## Song Maintenance Button ## ## Song Maintenance Button ##
self.maintenanceAction = self.addToolbarButton(u'', u'', self.maintenanceAction = self.toolbar.addToolbarAction(
':/songs/song_maintenance.png', self.onSongMaintenanceClick) u'maintenanceAction', icon=':/songs/song_maintenance.png',
triggers=self.onSongMaintenanceClick)
self.addSearchToToolBar() self.addSearchToToolBar()
# Signals and slots # Signals and slots
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -121,11 +122,10 @@ class SongMediaItem(MediaManagerItem):
self.onSearchTextButtonClick) self.onSearchTextButtonClick)
def addCustomContextActions(self): def addCustomContextActions(self):
context_menu_separator(self.listView) create_widget_action(self.listView, separator=True)
context_menu_action( create_widget_action(self.listView,
self.listView, u':/general/general_clone.png', text=translate('OpenLP.MediaManagerItem', '&Clone'),
translate('OpenLP.MediaManagerItem', icon=u':/general/general_clone.png', triggers=self.onCloneClick)
'&Clone'), self.onCloneClick)
def onFocus(self): def onFocus(self):
self.searchTextEdit.setFocus() self.searchTextEdit.setFocus()
@ -158,6 +158,8 @@ class SongMediaItem(MediaManagerItem):
translate('SongsPlugin.MediaItem', 'Lyrics')), translate('SongsPlugin.MediaItem', 'Lyrics')),
(SongSearch.Authors, u':/songs/song_search_author.png', (SongSearch.Authors, u':/songs/song_search_author.png',
SongStrings.Authors), SongStrings.Authors),
(SongSearch.Books, u':/songs/song_book_edit.png',
SongStrings.SongBooks),
(SongSearch.Themes, u':/slides/slide_theme.png', UiStrings().Themes) (SongSearch.Themes, u':/slides/slide_theme.png', UiStrings().Themes)
]) ])
self.searchTextEdit.setCurrentSearchType(QtCore.QSettings().value( self.searchTextEdit.setCurrentSearchType(QtCore.QSettings().value(
@ -196,6 +198,19 @@ class SongMediaItem(MediaManagerItem):
Author.display_name.like(u'%' + search_keywords + u'%'), Author.display_name.like(u'%' + search_keywords + u'%'),
Author.display_name.asc()) Author.display_name.asc())
self.displayResultsAuthor(search_results) self.displayResultsAuthor(search_results)
elif search_type == SongSearch.Books:
log.debug(u'Books Search')
search_results = self.plugin.manager.get_all_objects(Book,
Book.name.like(u'%' + search_keywords + u'%'),
Book.name.asc())
song_number = False
if not search_results:
search_keywords = search_keywords.rpartition(' ')
search_results = self.plugin.manager.get_all_objects(Book,
Book.name.like(u'%' + search_keywords[0] + u'%'),
Book.name.asc())
song_number = re.sub(r'[^0-9]', u'', search_keywords[2])
self.displayResultsBook(search_results, song_number)
elif search_type == SongSearch.Themes: elif search_type == SongSearch.Themes:
log.debug(u'Theme Search') log.debug(u'Theme Search')
search_results = self.plugin.manager.get_all_objects(Song, search_results = self.plugin.manager.get_all_objects(Song,
@ -270,6 +285,25 @@ class SongMediaItem(MediaManagerItem):
song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id)) song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id))
self.listView.addItem(song_name) self.listView.addItem(song_name)
def displayResultsBook(self, searchresults, song_number=False):
log.debug(u'display results Book')
self.listView.clear()
for book in searchresults:
songs = sorted(book.songs, key=lambda song: int(
re.sub(r'[^0-9]', u' ', song.song_number).partition(' ')[0])
if len(re.sub(r'[^\w]', ' ', song.song_number)) else 0)
for song in songs:
# Do not display temporary songs
if song.temporary:
continue
if song_number and not song_number in song.song_number:
continue
song_detail = u'%s - %s (%s)' % (book.name, song.song_number,
song.title)
song_name = QtGui.QListWidgetItem(song_detail)
song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id))
self.listView.addItem(song_name)
def onClearTextButtonClick(self): def onClearTextButtonClick(self):
""" """
Clear the search text. Clear the search text.

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.songimport import SongImport
from openlp.plugins.songs.lib.ui import SongStrings from openlp.plugins.songs.lib.ui import SongStrings
from openlp.plugins.songs.lib import OpenLyrics from openlp.plugins.songs.lib import OpenLyrics
from openlp.plugins.songs.lib.xml import OpenLyricsError
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -73,3 +74,7 @@ class OpenLyricsImport(SongImport):
except etree.XMLSyntaxError: except etree.XMLSyntaxError:
log.exception(u'XML syntax error in file %s' % file_path) log.exception(u'XML syntax error in file %s' % file_path)
self.logError(file_path, SongStrings.XMLSyntaxError) 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

@ -33,56 +33,56 @@ class SongsTab(SettingsTab):
""" """
SongsTab is the Songs settings tab in the settings dialog. SongsTab is the Songs settings tab in the settings dialog.
""" """
def __init__(self, parent, title, visible_title, icon_path):
SettingsTab.__init__(self, parent, title, visible_title, icon_path)
def setupUi(self): def setupUi(self):
"""
Set up the configuration tab UI.
"""
self.setObjectName(u'SongsTab') self.setObjectName(u'SongsTab')
SettingsTab.setupUi(self) SettingsTab.setupUi(self)
self.SongsModeGroupBox = QtGui.QGroupBox(self.leftColumn) self.modeGroupBox = QtGui.QGroupBox(self.leftColumn)
self.SongsModeGroupBox.setObjectName(u'SongsModeGroupBox') self.modeGroupBox.setObjectName(u'modeGroupBox')
self.SongsModeLayout = QtGui.QVBoxLayout(self.SongsModeGroupBox) self.modeLayout = QtGui.QVBoxLayout(self.modeGroupBox)
self.SongsModeLayout.setObjectName(u'SongsModeLayout') self.modeLayout.setObjectName(u'modeLayout')
self.SearchAsTypeCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox) self.searchAsTypeCheckBox = QtGui.QCheckBox(self.modeGroupBox)
self.SearchAsTypeCheckBox.setObjectName(u'SearchAsTypeCheckBox') self.searchAsTypeCheckBox.setObjectName(u'SearchAsTypeCheckBox')
self.SongsModeLayout.addWidget(self.SearchAsTypeCheckBox) self.modeLayout.addWidget(self.searchAsTypeCheckBox)
self.SongBarActiveCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox) self.toolBarActiveCheckBox = QtGui.QCheckBox(self.modeGroupBox)
self.SongBarActiveCheckBox.setObjectName(u'SongBarActiveCheckBox') self.toolBarActiveCheckBox.setObjectName(u'toolBarActiveCheckBox')
self.SongsModeLayout.addWidget(self.SongBarActiveCheckBox) self.modeLayout.addWidget(self.toolBarActiveCheckBox)
self.SongUpdateOnEditCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox) self.updateOnEditCheckBox = QtGui.QCheckBox(self.modeGroupBox)
self.SongUpdateOnEditCheckBox.setObjectName(u'SongUpdateOnEditCheckBox') self.updateOnEditCheckBox.setObjectName(u'updateOnEditCheckBox')
self.SongsModeLayout.addWidget(self.SongUpdateOnEditCheckBox) self.modeLayout.addWidget(self.updateOnEditCheckBox)
self.SongAddFromServiceCheckBox = QtGui.QCheckBox( self.addFromServiceCheckBox = QtGui.QCheckBox(
self.SongsModeGroupBox) self.modeGroupBox)
self.SongAddFromServiceCheckBox.setObjectName( self.addFromServiceCheckBox.setObjectName(
u'SongAddFromServiceCheckBox') u'addFromServiceCheckBox')
self.SongsModeLayout.addWidget(self.SongAddFromServiceCheckBox) self.modeLayout.addWidget(self.addFromServiceCheckBox)
self.leftLayout.addWidget(self.SongsModeGroupBox) self.leftLayout.addWidget(self.modeGroupBox)
self.leftLayout.addStretch() self.leftLayout.addStretch()
self.rightLayout.addStretch() self.rightLayout.addStretch()
QtCore.QObject.connect(self.SearchAsTypeCheckBox, QtCore.QObject.connect(self.searchAsTypeCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), QtCore.SIGNAL(u'stateChanged(int)'),
self.onSearchAsTypeCheckBoxChanged) self.onSearchAsTypeCheckBoxChanged)
QtCore.QObject.connect(self.SongBarActiveCheckBox, QtCore.QObject.connect(self.toolBarActiveCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), QtCore.SIGNAL(u'stateChanged(int)'),
self.onSongBarActiveCheckBoxChanged) self.onToolBarActiveCheckBoxChanged)
QtCore.QObject.connect(self.SongUpdateOnEditCheckBox, QtCore.QObject.connect(self.updateOnEditCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), QtCore.SIGNAL(u'stateChanged(int)'),
self.onSongUpdateOnEditCheckBoxChanged) self.onUpdateOnEditCheckBoxChanged)
QtCore.QObject.connect(self.SongAddFromServiceCheckBox, QtCore.QObject.connect(self.addFromServiceCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), QtCore.SIGNAL(u'stateChanged(int)'),
self.onSongAddFromServiceCheckBoxChanged) self.onAddFromServiceCheckBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.SongsModeGroupBox.setTitle( self.modeGroupBox.setTitle(
translate('SongsPlugin.SongsTab', 'Songs Mode')) translate('SongsPlugin.SongsTab', 'Songs Mode'))
self.SearchAsTypeCheckBox.setText( self.searchAsTypeCheckBox.setText(
translate('SongsPlugin.SongsTab', 'Enable search as you type')) translate('SongsPlugin.SongsTab', 'Enable search as you type'))
self.SongBarActiveCheckBox.setText(translate('SongsPlugin.SongsTab', self.toolBarActiveCheckBox.setText(translate('SongsPlugin.SongsTab',
'Display verses on live tool bar')) 'Display verses on live tool bar'))
self.SongUpdateOnEditCheckBox.setText( self.updateOnEditCheckBox.setText(
translate('SongsPlugin.SongsTab', 'Update service from song edit')) translate('SongsPlugin.SongsTab', 'Update service from song edit'))
self.SongAddFromServiceCheckBox.setText( self.addFromServiceCheckBox.setText(
translate('SongsPlugin.SongsTab', translate('SongsPlugin.SongsTab',
'Add missing songs when opening service')) 'Add missing songs when opening service'))
@ -92,19 +92,19 @@ class SongsTab(SettingsTab):
if check_state == QtCore.Qt.Checked: if check_state == QtCore.Qt.Checked:
self.song_search = True self.song_search = True
def onSongBarActiveCheckBoxChanged(self, check_state): def onToolBarActiveCheckBoxChanged(self, check_state):
self.song_bar = False self.tool_bar = False
# we have a set value convert to True/False # we have a set value convert to True/False
if check_state == QtCore.Qt.Checked: if check_state == QtCore.Qt.Checked:
self.song_bar = True self.tool_bar = True
def onSongUpdateOnEditCheckBoxChanged(self, check_state): def onUpdateOnEditCheckBoxChanged(self, check_state):
self.update_edit = False self.update_edit = False
# we have a set value convert to True/False # we have a set value convert to True/False
if check_state == QtCore.Qt.Checked: if check_state == QtCore.Qt.Checked:
self.update_edit = True self.update_edit = True
def onSongAddFromServiceCheckBoxChanged(self, check_state): def onAddFromServiceCheckBoxChanged(self, check_state):
self.update_load = False self.update_load = False
# we have a set value convert to True/False # we have a set value convert to True/False
if check_state == QtCore.Qt.Checked: if check_state == QtCore.Qt.Checked:
@ -115,23 +115,23 @@ class SongsTab(SettingsTab):
settings.beginGroup(self.settingsSection) settings.beginGroup(self.settingsSection)
self.song_search = settings.value( self.song_search = settings.value(
u'search as type', QtCore.QVariant(False)).toBool() u'search as type', QtCore.QVariant(False)).toBool()
self.song_bar = settings.value( self.tool_bar = settings.value(
u'display songbar', QtCore.QVariant(True)).toBool() u'display songbar', QtCore.QVariant(True)).toBool()
self.update_edit = settings.value( self.update_edit = settings.value(
u'update service on edit', QtCore.QVariant(False)).toBool() u'update service on edit', QtCore.QVariant(False)).toBool()
self.update_load = settings.value( self.update_load = settings.value(
u'add song from service', QtCore.QVariant(True)).toBool() u'add song from service', QtCore.QVariant(True)).toBool()
self.SearchAsTypeCheckBox.setChecked(self.song_search) self.searchAsTypeCheckBox.setChecked(self.song_search)
self.SongBarActiveCheckBox.setChecked(self.song_bar) self.toolBarActiveCheckBox.setChecked(self.tool_bar)
self.SongUpdateOnEditCheckBox.setChecked(self.update_edit) self.updateOnEditCheckBox.setChecked(self.update_edit)
self.SongAddFromServiceCheckBox.setChecked(self.update_load) self.addFromServiceCheckBox.setChecked(self.update_load)
settings.endGroup() settings.endGroup()
def save(self): def save(self):
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection) settings.beginGroup(self.settingsSection)
settings.setValue(u'search as type', QtCore.QVariant(self.song_search)) settings.setValue(u'search as type', QtCore.QVariant(self.song_search))
settings.setValue(u'display songbar', QtCore.QVariant(self.song_bar)) settings.setValue(u'display songbar', QtCore.QVariant(self.tool_bar))
settings.setValue(u'update service on edit', settings.setValue(u'update service on edit',
QtCore.QVariant(self.update_edit)) QtCore.QVariant(self.update_edit))
settings.setValue(u'add song from service', settings.setValue(u'add song from service',

View File

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

View File

@ -66,7 +66,7 @@ import re
from lxml import etree, objectify 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 import clean_song, VerseType
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic from openlp.plugins.songs.lib.db import Author, Book, Song, Topic
from openlp.core.utils import get_application_version from openlp.core.utils import get_application_version
@ -673,9 +673,22 @@ class OpenLyrics(object):
sxml = SongXML() sxml = SongXML()
verses = {} verses = {}
verse_def_list = [] verse_def_list = []
try:
lyrics = song_xml.lyrics lyrics = song_xml.lyrics
except AttributeError:
raise OpenLyricsError(OpenLyricsError.LyricsError,
'<lyrics> tag is missing.',
unicode(translate('OpenLP.OpenLyricsImportError',
'<lyrics> tag is missing.')))
try:
verses = 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. # Loop over the "verse" elements.
for verse in lyrics.verse: for verse in verses:
text = u'' text = u''
# Loop over the "lines" elements. # Loop over the "lines" elements.
for lines in verse.lines: for lines in verse.lines:
@ -791,3 +804,15 @@ class OpenLyrics(object):
""" """
return etree.tostring(xml, encoding=u'UTF-8', return etree.tostring(xml, encoding=u'UTF-8',
xml_declaration=True, pretty_print=True) 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, \ from openlp.core.lib import Plugin, StringContent, build_icon, translate, \
Receiver Receiver
from openlp.core.lib.db import Manager 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.core.utils.actions import ActionList
from openlp.plugins.songs.lib import clean_song, upgrade, SongMediaItem, \ from openlp.plugins.songs.lib import clean_song, upgrade, SongMediaItem, \
SongsTab SongsTab
@ -93,14 +93,12 @@ class SongsPlugin(Plugin):
use it as their parent. use it as their parent.
""" """
# Main song import menu item - will eventually be the only one # Main song import menu item - will eventually be the only one
self.songImportItem = base_action(import_menu, u'songImportItem') self.songImportItem = create_action(import_menu, u'songImportItem',
self.songImportItem.setText(translate('SongsPlugin', '&Song')) text=translate('SongsPlugin', '&Song'),
self.songImportItem.setToolTip(translate('SongsPlugin', tooltip=translate('SongsPlugin',
'Import songs using the import wizard.')) 'Import songs using the import wizard.'),
triggers=self.onSongImportItemClicked)
import_menu.addAction(self.songImportItem) import_menu.addAction(self.songImportItem)
# Signals and slots
QtCore.QObject.connect(self.songImportItem,
QtCore.SIGNAL(u'triggered()'), self.onSongImportItemClicked)
def addExportMenuItem(self, export_menu): def addExportMenuItem(self, export_menu):
""" """
@ -112,14 +110,12 @@ class SongsPlugin(Plugin):
use it as their parent. use it as their parent.
""" """
# Main song import menu item - will eventually be the only one # Main song import menu item - will eventually be the only one
self.songExportItem = base_action(export_menu, u'songExportItem') self.songExportItem = create_action(export_menu, u'songExportItem',
self.songExportItem.setText(translate('SongsPlugin', '&Song')) text=translate('SongsPlugin', '&Song'),
self.songExportItem.setToolTip(translate('SongsPlugin', tooltip=translate('SongsPlugin',
'Exports songs using the export wizard.')) 'Exports songs using the export wizard.'),
triggers=self.onSongExportItemClicked)
export_menu.addAction(self.songExportItem) export_menu.addAction(self.songExportItem)
# Signals and slots
QtCore.QObject.connect(self.songExportItem,
QtCore.SIGNAL(u'triggered()'), self.onSongExportItemClicked)
def addToolsMenuItem(self, tools_menu): def addToolsMenuItem(self, tools_menu):
""" """
@ -131,17 +127,13 @@ class SongsPlugin(Plugin):
use it as their parent. use it as their parent.
""" """
log.info(u'add tools menu') log.info(u'add tools menu')
self.toolsReindexItem = icon_action(tools_menu, u'toolsReindexItem', self.toolsReindexItem = create_action(tools_menu, u'toolsReindexItem',
u':/plugins/plugin_songs.png') text=translate('SongsPlugin', '&Re-index Songs'),
self.toolsReindexItem.setText( icon=u':/plugins/plugin_songs.png',
translate('SongsPlugin', '&Re-index Songs')) statustip=translate('SongsPlugin',
self.toolsReindexItem.setStatusTip( 'Re-index the songs database to improve searching and ordering.'),
translate('SongsPlugin', 'Re-index the songs database to improve ' visible=False, triggers=self.onToolsReindexItemTriggered)
'searching and ordering.'))
tools_menu.addAction(self.toolsReindexItem) tools_menu.addAction(self.toolsReindexItem)
QtCore.QObject.connect(self.toolsReindexItem,
QtCore.SIGNAL(u'triggered()'), self.onToolsReindexItemTriggered)
self.toolsReindexItem.setVisible(False)
def onToolsReindexItemTriggered(self): def onToolsReindexItemTriggered(self):
""" """

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

View File

@ -68,6 +68,7 @@
<file>media_playback_start.png</file> <file>media_playback_start.png</file>
<file>media_playback_stop.png</file> <file>media_playback_stop.png</file>
<file>media_playback_pause.png</file> <file>media_playback_pause.png</file>
<file>media_playback_next.png</file>
</qresource> </qresource>
<qresource prefix="icon"> <qresource prefix="icon">
<file>openlp-logo-16x16.png</file> <file>openlp-logo-16x16.png</file>

View File

@ -12,12 +12,12 @@
+############################################################################### +###############################################################################
+# OpenLP - Open Source Lyrics Projection # +# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- # +# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman # +# Copyright (c) 2008-2012 Raoul Snyman #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # +# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
+# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, # +# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
+# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, # +# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
+# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode # +# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
+# Woldsund # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
+# --------------------------------------------------------------------------- # +# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it # +# This program is free software; you can redistribute it and/or modify it #
+# under the terms of the GNU General Public License as published by the Free # +# under the terms of the GNU General Public License as published by the Free #

View File

@ -5,12 +5,12 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman # # Copyright (c) 2008-2012 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # # Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, # # Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, # # Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode # # Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Woldsund # # Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it # # This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free # # under the terms of the GNU General Public License as published by the Free #