diff --git a/documentation/manual/source/songs.rst b/documentation/manual/source/songs.rst
index 56928d831..23f054127 100644
--- a/documentation/manual/source/songs.rst
+++ b/documentation/manual/source/songs.rst
@@ -99,4 +99,131 @@ completed.
Press :guilabel:`Finish` and OpenLP will be ready to use your songs imported
from CCLI SongSelect.
+Creating or editing a song slide
+================================
+If you want to create a new song slide or, once you have a song imported, you
+can edit and rearrange the Title & Lyrics, Author, Topics & Song Book,
+assign a Theme, or edit *Copyright Info & Comments* as needed. This is done
+through the `Song Editor`. To use the `Song Editor` to edit an existing song you
+can click on a song in the `Media Manager` and then click the button to
+:guilabel:`Edit the selected song` or right click a song from either the
+`Media Manager` or from the `Service Manager` and click :guilabel:`Edit item`.
+If you are adding a new song click :guilabel:`Add a new Song` in the
+`Media Manager`.
+
+.. image:: pics/song_edit_lyrics.png
+
+**Title:** This is where you would name your song or edit a song name.
+
+**Alternate title:** You can add a name in this box that will bring up the song
+in Titles search. **Example:** You could use an alternate title of "hymn" on all
+your hymn song titles for grouping. When you search "hymn" it will show all the
+hymns that have "hymn" for the Alternate title.
+
+**Lyrics:** The *Lyrics* window shows all lyrics imported or added. On the left
+side of the lyrics you will see a capital letter followed by a number. A V1
+would represent verse 1, C1 would be Chorus 1. You will use these letters and
+numbers for the order to display the lyrics.
+
+**Verse Order:** After you entered or edited your song, you will want OpenLP to
+display the verses in the correct order you want them displayed. On the left side
+of your lyrics you will see C1, V1, V2 etc. the way they were imported or added.
+To put your lyrics in the correct order is as simple as typing in the
+:guilabel:`Verse order box` at the bottom, the correct order you want them
+displayed, with only a blank space in between each entry. The correct format will
+look like this: V1 C1 V2 C1 V3 C1. If you forget to put a space in between the
+order, or if you do not have the corresponding verse number, OpenLP will politely
+tell you with a pop-up error message what is wrong so you can correct your
+mistake and save it.
+
+.. image:: pics/song_edit_verse_error.png
+
+Adding or editing the lyrics
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+**Add:** To Add a new verse, click on :guilabel:`Add`. The main window is where
+you will type your lyrics. OpenLP is packaged with a spell checker for most
+languages. If you misspell a word it will be underlined. Right click the
+underlined word and left click *Spelling Suggestions* or you can ignore it and
+continue typing. You also have the ability to format the font using *Formatting
+Tags*. Highlight the word/words you want to format and right click the highlight.
+Left click *Formatting Tags* and choose the format you want to apply to the font
+and the format tags will be entered with your lyrics. These tags are not visible
+when displayed. To remove the format, delete the tag on each end of the word or
+sentence.
+
+**Edit:** To edit an existing verse, click on the verse you wish to *Edit* then click on
+:guilabel:`Edit`, make your changes and click :guilabel:`Save`.
+
+**Edit All:** To edit the whole song at once, click on :guilabel:`Edit All`.
+
+**Delete:** To delete a verse, click on the verse you want to delete and it will
+highlight, click on the :guilabel:`Delete` button and it will be deleted.
+**Warning:**, once you click the :guilabel:`Delete` button, you will not be
+asked again, it will be deleted immediately.
+
+.. image:: pics/song_edit_verse_type.png
+
+**Verse type:** gives you 7 ways to classify your lyrics. Verse, Chorus, Bridge,
+Pre-Chorus, Intro, Ending, Other.
+
+If you have more than one verse, you would number them Verse 1, 2, 3 as needed.
+If you find the verse has too many lines for your screen, you can edit and
+shorten the verse and :guilabel:`Add` another slide.
+
+Authors, Topics & Song Book
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Once your *Title & Lyrics* are added or edited the way you want them you must
+add or enter the author or authors of the song. OpenLP requires all songs to
+have an author entered. You can add a blank space for the author name.
+
+.. image:: pics/song_edit_authors.png
+
+**Authors:** Click the drop down arrow to view all authors or start typing a name
+in the box and a list will appear. If the authors name has not been added, type
+the authors name in the box and click :guilabel:`Add to Song`. The authors name
+will appear below and will also be added to your database. If you accidently add
+the wrong author you can click on the authors name and click :guilabel:`Remove`.
+
+:guilabel:`Manage Authors, Topics, Song Books:` Clicking this button will bring
+up your complete list of authors.
+
+.. image:: pics/song_edit_maintenance.png
+
+**Add:** Clicking the :guilabel:`Add` button will bring up a box where you will
+add the Authors First name, Last name and Display name. Click :guilabel:`Save`
+when you are finished.
+
+.. image:: pics/song_edit_author_maintenance.png
+
+**Edit:** The :guilabel:`Edit` button will bring up window where you can edit
+the info that is already there.
+
+**Delete:** The :guilabel:`Delete` button will remove the author you have
+highlighted. Note: You cannot delete an author that is assigned to a song.
+Authors names are displayed in the footer.
+
+Theme, Copyright info & Comments
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+On this tab you can assign a *Theme* to a song, enter the *Copyright information*
+and add the *CCLI number*. If you imported a song from SongSelect this
+information will usually be entered.
+
+.. image:: pics/song_edit_theme_copyright.png
+
+**Theme:** Click the drop down arrow to display your list of themes or start
+typing a theme name in the box and the list will appear. You can also create a
+new theme by clicking the :guilabel:`New Theme` button.
+
+**Copyright information:** Add or edit the copyright information in this box. If
+you would like to use the © symbol click "guilabel:`©` button. This information
+is displayed in the footer.
+
+**CCLI number:** Enter the CCLI number in this box. Note: this is the CCLI number
+of the song, not your contract number. This number is not displayed in the footer
+
+**Comments:** You can add comments in this box. This information is not
+dispayed in the footer.
diff --git a/openlp.pyw b/openlp.pyw
index 57dbcb698..5c3b8ca77 100755
--- a/openlp.pyw
+++ b/openlp.pyw
@@ -116,7 +116,7 @@ class OpenLP(QtGui.QApplication):
self.processEvents()
# start the main app window
self.mainWindow = MainWindow(screens, self.clipboard(),
- self.arguments())
+ self.arguments())
self.mainWindow.show()
if show_splash:
# now kill the splashscreen
diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py
index e62cb3e44..491f3e652 100644
--- a/openlp/core/lib/__init__.py
+++ b/openlp/core/lib/__init__.py
@@ -166,58 +166,6 @@ def build_icon(icon):
QtGui.QIcon.Normal, QtGui.QIcon.Off)
return button_icon
-def context_menu_action(base, icon, text, slot, shortcuts=None):
- """
- Utility method to help build context menus for plugins
-
- ``base``
- The parent menu to add this menu item to
-
- ``icon``
- An icon for this action
-
- ``text``
- The text to display for this action
-
- ``slot``
- The code to run when this action is triggered
- """
- action = QtGui.QAction(text, base)
- if icon:
- action.setIcon(build_icon(icon))
- QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), slot)
- if shortcuts:
- action.setShortcuts(shortcuts)
- return action
-
-def context_menu(base, icon, text):
- """
- Utility method to help build context menus for plugins
-
- ``base``
- The parent object to add this menu to
-
- ``icon``
- An icon for this menu
-
- ``text``
- The text to display for this menu
- """
- action = QtGui.QMenu(text, base)
- action.setIcon(build_icon(icon))
- return action
-
-def context_menu_separator(base):
- """
- Add a separator to a context menu
-
- ``base``
- The menu object to add the separator to
- """
- action = QtGui.QAction(u'', base)
- action.setSeparator(True)
- return action
-
def image_to_byte(image):
"""
Resize an image to fit on the current screen for the web and returns
@@ -343,3 +291,4 @@ from dockwidget import OpenLPDockWidget
from renderer import Renderer
from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem
+from openlp.core.utils.actions import ActionList
diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py
index c4361a421..a80fedd06 100644
--- a/openlp/core/lib/htmlbuilder.py
+++ b/openlp/core/lib/htmlbuilder.py
@@ -452,7 +452,7 @@ def build_lyrics_css(item, webkitvers):
.lyricsshadow {
%s
}
- """
+ """
theme = item.themedata
lyricstable = u''
lyrics = u''
@@ -460,8 +460,7 @@ def build_lyrics_css(item, webkitvers):
outline = u''
shadow = u''
if theme and item.main:
- lyricstable = u'left: %spx; top: %spx;' % \
- (item.main.x(), item.main.y())
+ lyricstable = u'left: %spx; top: %spx;' % (item.main.x(), item.main.y())
lyrics = build_lyrics_format_css(theme, item.main.width(),
item.main.height())
# For performance reasons we want to show as few DIV's as possible,
diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py
index 63132b141..7671064df 100644
--- a/openlp/core/lib/mediamanageritem.py
+++ b/openlp/core/lib/mediamanageritem.py
@@ -31,10 +31,10 @@ import os
from PyQt4 import QtCore, QtGui
-from openlp.core.lib import context_menu_action, context_menu_separator, \
- SettingsManager, OpenLPToolbar, ServiceItem, StringContent, build_icon, \
- translate, Receiver, ListWidgetWithDnD
-from openlp.core.lib.ui import UiStrings
+from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \
+ StringContent, build_icon, translate, Receiver, ListWidgetWithDnD
+from openlp.core.lib.ui import UiStrings, context_menu_action, \
+ context_menu_separator
log = logging.getLogger(__name__)
@@ -260,39 +260,42 @@ class MediaManagerItem(QtGui.QWidget):
context_menu_action(
self.listView, u':/general/general_edit.png',
self.plugin.getString(StringContent.Edit)[u'title'],
- self.onEditClick))
+ self.onEditClick, context=QtCore.Qt.WidgetShortcut))
self.listView.addAction(context_menu_separator(self.listView))
if self.hasDeleteIcon:
self.listView.addAction(
context_menu_action(
self.listView, u':/general/general_delete.png',
self.plugin.getString(StringContent.Delete)[u'title'],
- self.onDeleteClick, [QtCore.Qt.Key_Delete]))
+ self.onDeleteClick, [QtCore.Qt.Key_Delete],
+ context=QtCore.Qt.WidgetShortcut))
self.listView.addAction(context_menu_separator(self.listView))
self.listView.addAction(
context_menu_action(
self.listView, u':/general/general_preview.png',
self.plugin.getString(StringContent.Preview)[u'title'],
- self.onPreviewClick, [QtCore.Qt.Key_Enter]))
+ self.onPreviewClick, [QtCore.Qt.Key_Enter,
+ QtCore.Qt.Key_Return], context=QtCore.Qt.WidgetShortcut))
self.listView.addAction(
context_menu_action(
self.listView, u':/general/general_live.png',
self.plugin.getString(StringContent.Live)[u'title'],
self.onLiveClick, [QtCore.Qt.ShiftModifier + \
QtCore.Qt.Key_Enter, QtCore.Qt.ShiftModifier + \
- QtCore.Qt.Key_Return]))
+ QtCore.Qt.Key_Return], context=QtCore.Qt.WidgetShortcut))
self.listView.addAction(
context_menu_action(
self.listView, u':/general/general_add.png',
self.plugin.getString(StringContent.Service)[u'title'],
- self.onAddClick, [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal]))
+ self.onAddClick, [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal],
+ context=QtCore.Qt.WidgetShortcut))
if self.addToServiceItem:
self.listView.addAction(
context_menu_action(
self.listView, u':/general/general_add.png',
translate('OpenLP.MediaManagerItem',
'&Add to selected Service Item'),
- self.onAddEditClick))
+ self.onAddEditClick, context=QtCore.Qt.WidgetShortcut))
QtCore.QObject.connect(self.listView,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onClickPressed)
diff --git a/openlp/core/lib/searchedit.py b/openlp/core/lib/searchedit.py
index 4841d76dc..d32961ef9 100644
--- a/openlp/core/lib/searchedit.py
+++ b/openlp/core/lib/searchedit.py
@@ -29,6 +29,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon
+from openlp.core.lib.ui import icon_action
log = logging.getLogger(__name__)
@@ -132,7 +133,8 @@ class SearchEdit(QtGui.QLineEdit):
menu = QtGui.QMenu(self)
first = None
for identifier, icon, title in items:
- action = QtGui.QAction(build_icon(icon), title, menu)
+ action = icon_action(menu, u'', icon)
+ action.setText(title)
action.setData(QtCore.QVariant(identifier))
menu.addAction(action)
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'),
diff --git a/openlp/core/lib/toolbar.py b/openlp/core/lib/toolbar.py
index d5d2fa4f8..d2b37df51 100644
--- a/openlp/core/lib/toolbar.py
+++ b/openlp/core/lib/toolbar.py
@@ -51,8 +51,7 @@ class OpenLPToolbar(QtGui.QToolBar):
log.debug(u'Init done for %s' % parent.__class__.__name__)
def addToolbarButton(self, title, icon, tooltip=None, slot=None,
- checkable=False, shortcut=0, alternate=0,
- context=QtCore.Qt.WidgetShortcut):
+ checkable=False, shortcuts=None, context=QtCore.Qt.WidgetShortcut):
"""
A method to help developers easily add a button to the toolbar.
@@ -74,16 +73,12 @@ class OpenLPToolbar(QtGui.QToolBar):
If *True* the button has two, *off* and *on*, states. Default is
*False*, which means the buttons has only one state.
- ``shortcut``
- The primary shortcut for this action
-
- ``alternate``
- The alternate shortcut for this action
+ ``shortcuts``
+ The list of shortcuts for this action
``context``
Specify the context in which this shortcut is valid
"""
- newAction = None
if icon:
actionIcon = build_icon(icon)
if slot and not checkable:
@@ -92,7 +87,7 @@ class OpenLPToolbar(QtGui.QToolBar):
newAction = self.addAction(actionIcon, title)
self.icons[title] = actionIcon
else:
- newAction = QtGui.QAction(title, newAction)
+ newAction = QtGui.QAction(title, self)
self.addAction(newAction)
QtCore.QObject.connect(newAction,
QtCore.SIGNAL(u'triggered()'), slot)
@@ -103,8 +98,9 @@ class OpenLPToolbar(QtGui.QToolBar):
QtCore.QObject.connect(newAction,
QtCore.SIGNAL(u'toggled(bool)'), slot)
self.actions[title] = newAction
- newAction.setShortcuts([shortcut, alternate])
- newAction.setShortcutContext(context)
+ if shortcuts is not None:
+ newAction.setShortcuts(shortcuts)
+ newAction.setShortcutContext(context)
return newAction
def addToolbarSeparator(self, handle):
diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py
index c1a9f8b35..3365b32a0 100644
--- a/openlp/core/lib/ui.py
+++ b/openlp/core/lib/ui.py
@@ -31,6 +31,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, Receiver, translate
+from openlp.core.utils.actions import ActionList
log = logging.getLogger(__name__)
@@ -49,14 +50,18 @@ class UiStrings(object):
Cancel = translate('OpenLP.Ui', 'Cancel')
CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:')
CreateService = translate('OpenLP.Ui', 'Create a new service.')
+ Continuous = translate('OpenLP.Ui', 'Continuous')
Default = unicode(translate('OpenLP.Ui', 'Default'))
Delete = translate('OpenLP.Ui', '&Delete')
+ DisplayStyle = translate('OpenLP.Ui', 'Display style:')
Edit = translate('OpenLP.Ui', '&Edit')
EmptyField = translate('OpenLP.Ui', 'Empty Field')
Error = translate('OpenLP.Ui', 'Error')
Export = translate('OpenLP.Ui', 'Export')
+ File = translate('OpenLP.Ui', 'File')
FontSizePtUnit = translate('OpenLP.Ui', 'pt',
'Abbreviated font pointsize unit')
+ Help = translate('OpenLP.Ui', 'Help')
Hours = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours')
Image = translate('OpenLP.Ui', 'Image')
Import = translate('OpenLP.Ui', 'Import')
@@ -64,6 +69,7 @@ class UiStrings(object):
Live = translate('OpenLP.Ui', 'Live')
LiveBGError = translate('OpenLP.Ui', 'Live Background Error')
LivePanel = translate('OpenLP.Ui', 'Live Panel')
+ LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar')
Load = translate('OpenLP.Ui', 'Load')
Minutes = translate('OpenLP.Ui', 'm', 'The abbreviated unit for minutes')
Middle = translate('OpenLP.Ui', 'Middle')
@@ -81,6 +87,7 @@ class UiStrings(object):
OpenService = translate('OpenLP.Ui', 'Open Service')
Preview = translate('OpenLP.Ui', 'Preview')
PreviewPanel = translate('OpenLP.Ui', 'Preview Panel')
+ PreviewToolbar = translate('OpenLP.Ui', 'Preview Toolbar')
PrintServiceOrder = translate('OpenLP.Ui', 'Print Service Order')
ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background')
@@ -91,13 +98,19 @@ class UiStrings(object):
Search = translate('OpenLP.Ui', 'Search')
SelectDelete = translate('OpenLP.Ui', 'You must select an item to delete.')
SelectEdit = translate('OpenLP.Ui', 'You must select an item to edit.')
+ Settings = translate('OpenLP.Ui', 'Settings')
SaveService = translate('OpenLP.Ui', 'Save Service')
Service = translate('OpenLP.Ui', 'Service')
StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s'))
Theme = translate('OpenLP.Ui', 'Theme', 'Singular')
Themes = translate('OpenLP.Ui', 'Themes', 'Plural')
+ Tools = translate('OpenLP.Ui', 'Tools')
Top = translate('OpenLP.Ui', 'Top')
+ VersePerSlide = translate('OpenLP.Ui', 'Verse Per Slide')
+ VersePerLine = translate('OpenLP.Ui', 'Verse Per Line')
Version = translate('OpenLP.Ui', 'Version')
+ View = translate('OpenLP.Ui', 'View')
+ ViewMode = translate('OpenLP.Ui', 'View Model')
def add_welcome_page(parent, image):
"""
@@ -238,45 +251,128 @@ def create_up_down_push_button_set(parent):
QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked)
return up_button, down_button
-def base_action(parent, name):
+def base_action(parent, name, category=None):
"""
Return the most basic action with the object name set.
+
+ ``category``
+ The category the action should be listed in the shortcut dialog. If you
+ not wish, that this action is added to the shortcut dialog, then do not
+ state any.
"""
action = QtGui.QAction(parent)
action.setObjectName(name)
+ if category is not None:
+ action_list = ActionList.get_instance()
+ action_list.add_action(action, category)
return action
-def checkable_action(parent, name, checked=None):
+def checkable_action(parent, name, checked=None, category=None):
"""
Return a standard action with the checkable attribute set.
"""
- action = base_action(parent, name)
+ 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):
+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)
+ action = checkable_action(parent, name, checked, category)
else:
- action = base_action(parent, name)
+ action = base_action(parent, name, category)
action.setIcon(build_icon(icon))
return action
-def shortcut_action(parent, text, shortcuts, function):
+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(text, parent)
+ 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)
action.setShortcuts(shortcuts)
- action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
+ action.setShortcutContext(context)
+ action_list = ActionList.get_instance()
+ action_list.add_action(action, category)
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), function)
return action
+def context_menu_action(base, icon, text, slot, shortcuts=None, category=None,
+ context=QtCore.Qt.WindowShortcut):
+ """
+ Utility method to help build context menus for plugins
+
+ ``base``
+ The parent menu to add this menu item to
+
+ ``icon``
+ An icon for this action
+
+ ``text``
+ The text to display for this action
+
+ ``slot``
+ The code to run when this action is triggered
+
+ ``shortcuts``
+ The action's shortcuts.
+
+ ``category``
+ The category the shortcut should be listed in the shortcut dialog. If
+ left to None, then the action will be hidden in the shortcut dialog.
+
+ ``context``
+ The context the shortcut is valid.
+ """
+ action = QtGui.QAction(text, base)
+ if icon:
+ action.setIcon(build_icon(icon))
+ QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), slot)
+ if shortcuts is not None:
+ action.setShortcuts(shortcuts)
+ action.setShortcutContext(context)
+ action_list = ActionList.get_instance()
+ action_list.add_action(action)
+ return action
+
+def context_menu(base, icon, text):
+ """
+ Utility method to help build context menus for plugins
+
+ ``base``
+ The parent object to add this menu to
+
+ ``icon``
+ An icon for this menu
+
+ ``text``
+ The text to display for this menu
+ """
+ action = QtGui.QMenu(text, base)
+ action.setIcon(build_icon(icon))
+ return action
+
+def context_menu_separator(base):
+ """
+ Add a separator to a context menu
+
+ ``base``
+ The menu object to add the separator to
+ """
+ action = QtGui.QAction(u'', base)
+ action.setSeparator(True)
+ return action
+
def add_widget_completer(cache, widget):
"""
Adds a text autocompleter to a widget.
@@ -315,3 +411,20 @@ def create_valign_combo(form, parent, layout):
form.verticalComboBox.addItem(UiStrings.Bottom)
verticalLabel.setBuddy(form.verticalComboBox)
layout.addRow(verticalLabel, form.verticalComboBox)
+
+def find_and_set_in_combo_box(combo_box, value_to_find):
+ """
+ Find a string in a combo box and set it as the selected item if present
+
+ ``combo_box``
+ The combo box to check for selected items
+
+ ``value_to_find``
+ The value to find
+ """
+ index = combo_box.findText(value_to_find,
+ QtCore.Qt.MatchExactly)
+ if index == -1:
+ # Not Found.
+ index = 0
+ combo_box.setCurrentIndex(index)
\ No newline at end of file
diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py
index 38775d68e..2038e1972 100644
--- a/openlp/core/ui/mainwindow.py
+++ b/openlp/core/ui/mainwindow.py
@@ -33,12 +33,13 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
- icon_action
+ icon_action, shortcut_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ThemeManager, SlideController, PluginForm, MediaDockManager, \
ShortcutListForm, DisplayTagForm
from openlp.core.utils import AppLocation, add_actions, LanguageManager, \
- ActionList, get_application_version
+ get_application_version
+from openlp.core.utils.actions import ActionList, CategoryOrder
log = logging.getLogger(__name__)
@@ -161,74 +162,86 @@ class Ui_MainWindow(object):
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self.themeManagerDock)
# Create the menu items
- self.FileNewItem = icon_action(mainWindow, u'FileNewItem',
- u':/general/general_new.png')
- mainWindow.actionList.add_action(self.FileNewItem, u'File')
- self.FileOpenItem = icon_action(mainWindow, u'FileOpenItem',
- u':/general/general_open.png')
- mainWindow.actionList.add_action(self.FileOpenItem, u'File')
- self.FileSaveItem = icon_action(mainWindow, u'FileSaveItem',
- u':/general/general_save.png')
- mainWindow.actionList.add_action(self.FileSaveItem, u'File')
- self.FileSaveAsItem = base_action(mainWindow, u'FileSaveAsItem')
- mainWindow.actionList.add_action(self.FileSaveAsItem, u'File')
- self.printServiceOrderItem = base_action(
- mainWindow, u'printServiceItem')
- mainWindow.actionList.add_action(
- self.printServiceOrderItem, u'Print Service Order')
- self.FileExitItem = icon_action(mainWindow, u'FileExitItem',
- u':/system/system_exit.png')
- mainWindow.actionList.add_action(self.FileExitItem, u'File')
- self.ImportThemeItem = base_action(mainWindow, u'ImportThemeItem')
- mainWindow.actionList.add_action(self.ImportThemeItem, u'Import')
- self.ImportLanguageItem = base_action(mainWindow, u'ImportLanguageItem')
- mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import')
- self.ExportThemeItem = base_action(mainWindow, u'ExportThemeItem')
- mainWindow.actionList.add_action(self.ExportThemeItem, u'Export')
- self.ExportLanguageItem = base_action(mainWindow, u'ExportLanguageItem')
- mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export')
- self.ViewMediaManagerItem = icon_action(mainWindow,
- u'ViewMediaManagerItem', u':/system/system_mediamanager.png',
- self.mediaManagerDock.isVisible())
- self.ViewThemeManagerItem = icon_action(mainWindow,
- u'ViewThemeManagerItem', u':/system/system_thememanager.png',
- self.themeManagerDock.isVisible())
- mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View')
- self.ViewServiceManagerItem = icon_action(mainWindow,
- u'ViewServiceManagerItem', u':/system/system_servicemanager.png',
- self.serviceManagerDock.isVisible())
- mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View')
- self.ViewPreviewPanel = checkable_action(mainWindow,
- u'ViewPreviewPanel', previewVisible)
- mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View')
- self.ViewLivePanel = checkable_action(mainWindow, u'ViewLivePanel',
- liveVisible)
- mainWindow.actionList.add_action(self.ViewLivePanel, u'View')
- self.ModeDefaultItem = checkable_action(mainWindow, u'ModeDefaultItem')
- mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode')
- self.ModeSetupItem = checkable_action(mainWindow, u'ModeLiveItem')
- mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode')
- self.ModeLiveItem = checkable_action(mainWindow, u'ModeLiveItem', True)
- mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode')
+ action_list = ActionList.get_instance()
+ action_list.add_category(UiStrings.File, CategoryOrder.standardMenu)
+ self.FileNewItem = shortcut_action(mainWindow, u'FileNewItem',
+ [QtGui.QKeySequence(u'Ctrl+N')],
+ self.ServiceManagerContents.onNewServiceClicked,
+ u':/general/general_new.png', category=UiStrings.File)
+ self.FileOpenItem = shortcut_action(mainWindow, u'FileOpenItem',
+ [QtGui.QKeySequence(u'Ctrl+O')],
+ self.ServiceManagerContents.onLoadServiceClicked,
+ u':/general/general_open.png', category=UiStrings.File)
+ self.FileSaveItem = shortcut_action(mainWindow, u'FileSaveItem',
+ [QtGui.QKeySequence(u'Ctrl+S')],
+ self.ServiceManagerContents.saveFile,
+ u':/general/general_save.png', category=UiStrings.File)
+ self.FileSaveAsItem = shortcut_action(mainWindow, u'FileSaveAsItem',
+ [QtGui.QKeySequence(u'Ctrl+Shift+S')],
+ self.ServiceManagerContents.saveFileAs, category=UiStrings.File)
+ self.printServiceOrderItem = shortcut_action(mainWindow,
+ u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')],
+ self.ServiceManagerContents.printServiceOrder,
+ category=UiStrings.File)
+ self.FileExitItem = shortcut_action(mainWindow, u'FileExitItem',
+ [QtGui.QKeySequence(u'Alt+F4')], mainWindow.close,
+ u':/system/system_exit.png', category=UiStrings.File)
+ action_list.add_category(UiStrings.Import, CategoryOrder.standardMenu)
+ self.ImportThemeItem = base_action(
+ mainWindow, u'ImportThemeItem', UiStrings.Import)
+ self.ImportLanguageItem = base_action(
+ mainWindow, u'ImportLanguageItem')#, UiStrings.Import)
+ action_list.add_category(UiStrings.Export, CategoryOrder.standardMenu)
+ self.ExportThemeItem = base_action(
+ mainWindow, u'ExportThemeItem', UiStrings.Export)
+ self.ExportLanguageItem = base_action(
+ mainWindow, u'ExportLanguageItem')#, UiStrings.Export)
+ action_list.add_category(UiStrings.View, CategoryOrder.standardMenu)
+ self.ViewMediaManagerItem = shortcut_action(mainWindow,
+ u'ViewMediaManagerItem', [QtGui.QKeySequence(u'F8')],
+ self.toggleMediaManager, u':/system/system_mediamanager.png',
+ self.mediaManagerDock.isVisible(), UiStrings.View)
+ self.ViewThemeManagerItem = shortcut_action(mainWindow,
+ u'ViewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
+ self.toggleThemeManager, u':/system/system_thememanager.png',
+ self.themeManagerDock.isVisible(), UiStrings.View)
+ self.ViewServiceManagerItem = shortcut_action(mainWindow,
+ u'ViewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
+ self.toggleServiceManager, u':/system/system_servicemanager.png',
+ self.serviceManagerDock.isVisible(), UiStrings.View)
+ self.ViewPreviewPanel = shortcut_action(mainWindow,
+ u'ViewPreviewPanel', [QtGui.QKeySequence(u'F11')],
+ self.setPreviewPanelVisibility, checked=previewVisible,
+ category=UiStrings.View)
+ self.ViewLivePanel = shortcut_action(mainWindow, u'ViewLivePanel',
+ [QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility,
+ checked=liveVisible, category=UiStrings.View)
+ action_list.add_category(UiStrings.ViewMode, CategoryOrder.standardMenu)
+ self.ModeDefaultItem = checkable_action(
+ mainWindow, u'ModeDefaultItem', category=UiStrings.ViewMode)
+ self.ModeSetupItem = checkable_action(
+ mainWindow, u'ModeLiveItem', category=UiStrings.ViewMode)
+ self.ModeLiveItem = checkable_action(
+ mainWindow, u'ModeLiveItem', True, UiStrings.ViewMode)
self.ModeGroup = QtGui.QActionGroup(mainWindow)
self.ModeGroup.addAction(self.ModeDefaultItem)
self.ModeGroup.addAction(self.ModeSetupItem)
self.ModeGroup.addAction(self.ModeLiveItem)
self.ModeDefaultItem.setChecked(True)
+ action_list.add_category(UiStrings.Tools, CategoryOrder.standardMenu)
self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
- u':/tools/tools_add.png')
- mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools')
+ u':/tools/tools_add.png', category=UiStrings.Tools)
self.ToolsOpenDataFolder = icon_action(mainWindow,
- u'ToolsOpenDataFolder', u':/general/general_open.png')
- mainWindow.actionList.add_action(self.ToolsOpenDataFolder, u'Tools')
- self.settingsPluginListItem = icon_action(mainWindow,
- u'settingsPluginListItem', u':/system/settings_plugin_list.png')
- mainWindow.actionList.add_action(self.settingsPluginListItem,
- u'Settings')
+ u'ToolsOpenDataFolder', u':/general/general_open.png',
+ category=UiStrings.Tools)
+ action_list.add_category(UiStrings.Settings, CategoryOrder.standardMenu)
+ self.settingsPluginListItem = shortcut_action(mainWindow,
+ u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')],
+ self.onPluginItemClicked, u':/system/settings_plugin_list.png',
+ category=UiStrings.Settings)
# i18n Language Items
self.AutoLanguageItem = checkable_action(mainWindow,
u'AutoLanguageItem', LanguageManager.auto_language)
- mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings')
self.LanguageGroup = QtGui.QActionGroup(mainWindow)
self.LanguageGroup.setExclusive(True)
self.LanguageGroup.setObjectName(u'LanguageGroup')
@@ -241,24 +254,26 @@ class Ui_MainWindow(object):
add_actions(self.LanguageGroup, [languageItem])
self.SettingsShortcutsItem = icon_action(mainWindow,
u'SettingsShortcutsItem',
- u':/system/system_configure_shortcuts.png')
+ u':/system/system_configure_shortcuts.png',
+ category=UiStrings.Settings)
self.DisplayTagItem = icon_action(mainWindow,
- u'DisplayTagItem', u':/system/tag_editor.png')
+ u'DisplayTagItem', u':/system/tag_editor.png',
+ category=UiStrings.Settings)
self.SettingsConfigureItem = icon_action(mainWindow,
- u'SettingsConfigureItem', u':/system/system_settings.png')
- mainWindow.actionList.add_action(self.SettingsShortcutsItem,
- u'Settings')
+ u'SettingsConfigureItem', u':/system/system_settings.png',
+ category=UiStrings.Settings)
+ action_list.add_category(UiStrings.Help, CategoryOrder.standardMenu)
self.HelpDocumentationItem = icon_action(mainWindow,
- u'HelpDocumentationItem', u':/system/system_help_contents.png')
+ u'HelpDocumentationItem', u':/system/system_help_contents.png',
+ category=None)#UiStrings.Help)
self.HelpDocumentationItem.setEnabled(False)
- mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help')
- self.HelpAboutItem = icon_action(mainWindow, u'HelpAboutItem',
- u':/system/system_about.png')
- mainWindow.actionList.add_action(self.HelpAboutItem, u'Help')
- self.HelpOnlineHelpItem = base_action(mainWindow, u'HelpOnlineHelpItem')
- mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help')
- self.helpWebSiteItem = base_action(mainWindow, u'helpWebSiteItem')
- mainWindow.actionList.add_action(self.helpWebSiteItem, u'Help')
+ self.HelpAboutItem = shortcut_action(mainWindow, u'HelpAboutItem',
+ [QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked,
+ u':/system/system_about.png', category=UiStrings.Help)
+ self.HelpOnlineHelpItem = base_action(
+ mainWindow, u'HelpOnlineHelpItem', category=UiStrings.Help)
+ self.helpWebSiteItem = base_action(
+ mainWindow, u'helpWebSiteItem', category=UiStrings.Help)
add_actions(self.FileImportMenu,
(self.ImportThemeItem, self.ImportLanguageItem))
add_actions(self.FileExportMenu,
@@ -294,14 +309,11 @@ class Ui_MainWindow(object):
# Connect up some signals and slots
QtCore.QObject.connect(self.FileMenu,
QtCore.SIGNAL(u'aboutToShow()'), self.updateFileMenu)
- QtCore.QObject.connect(self.FileExitItem,
- QtCore.SIGNAL(u'triggered()'), mainWindow.close)
QtCore.QMetaObject.connectSlotsByName(mainWindow)
# Hide the entry, as it does not have any functionality yet.
self.ToolsAddToolItem.setVisible(False)
self.ImportLanguageItem.setVisible(False)
self.ExportLanguageItem.setVisible(False)
- self.SettingsShortcutsItem.setVisible(False)
self.HelpDocumentationItem.setVisible(False)
def retranslateUi(self, mainWindow):
@@ -329,36 +341,27 @@ class Ui_MainWindow(object):
self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New'))
self.FileNewItem.setToolTip(UiStrings.NewService)
self.FileNewItem.setStatusTip(UiStrings.CreateService)
- self.FileNewItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+N'))
self.FileOpenItem.setText(translate('OpenLP.MainWindow', '&Open'))
self.FileOpenItem.setToolTip(UiStrings.OpenService)
self.FileOpenItem.setStatusTip(
translate('OpenLP.MainWindow', 'Open an existing service.'))
- self.FileOpenItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+O'))
self.FileSaveItem.setText(translate('OpenLP.MainWindow', '&Save'))
self.FileSaveItem.setToolTip(UiStrings.SaveService)
self.FileSaveItem.setStatusTip(
translate('OpenLP.MainWindow', 'Save the current service to disk.'))
- self.FileSaveItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+S'))
self.FileSaveAsItem.setText(
translate('OpenLP.MainWindow', 'Save &As...'))
self.FileSaveAsItem.setToolTip(
translate('OpenLP.MainWindow', 'Save Service As'))
self.FileSaveAsItem.setStatusTip(translate('OpenLP.MainWindow',
'Save the current service under a new name.'))
- self.FileSaveAsItem.setShortcut(
- translate('OpenLP.MainWindow', 'Ctrl+Shift+S'))
self.printServiceOrderItem.setText(UiStrings.PrintServiceOrder)
self.printServiceOrderItem.setStatusTip(translate('OpenLP.MainWindow',
'Print the current Service Order.'))
- self.printServiceOrderItem.setShortcut(
- translate('OpenLP.MainWindow', 'Ctrl+P'))
self.FileExitItem.setText(
translate('OpenLP.MainWindow', 'E&xit'))
self.FileExitItem.setStatusTip(
translate('OpenLP.MainWindow', 'Quit OpenLP'))
- self.FileExitItem.setShortcut(
- translate('OpenLP.MainWindow', 'Alt+F4'))
self.ImportThemeItem.setText(
translate('OpenLP.MainWindow', '&Theme'))
self.ImportLanguageItem.setText(
@@ -379,53 +382,39 @@ class Ui_MainWindow(object):
translate('OpenLP.MainWindow', 'Toggle Media Manager'))
self.ViewMediaManagerItem.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the media manager.'))
- self.ViewMediaManagerItem.setShortcut(
- translate('OpenLP.MainWindow', 'F8'))
self.ViewThemeManagerItem.setText(
translate('OpenLP.MainWindow', '&Theme Manager'))
self.ViewThemeManagerItem.setToolTip(
translate('OpenLP.MainWindow', 'Toggle Theme Manager'))
self.ViewThemeManagerItem.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the theme manager.'))
- self.ViewThemeManagerItem.setShortcut(
- translate('OpenLP.MainWindow', 'F10'))
self.ViewServiceManagerItem.setText(
translate('OpenLP.MainWindow', '&Service Manager'))
self.ViewServiceManagerItem.setToolTip(
translate('OpenLP.MainWindow', 'Toggle Service Manager'))
self.ViewServiceManagerItem.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the service manager.'))
- self.ViewServiceManagerItem.setShortcut(
- translate('OpenLP.MainWindow', 'F9'))
self.ViewPreviewPanel.setText(
translate('OpenLP.MainWindow', '&Preview Panel'))
self.ViewPreviewPanel.setToolTip(
translate('OpenLP.MainWindow', 'Toggle Preview Panel'))
self.ViewPreviewPanel.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the preview panel.'))
- self.ViewPreviewPanel.setShortcut(
- translate('OpenLP.MainWindow', 'F11'))
self.ViewLivePanel.setText(
translate('OpenLP.MainWindow', '&Live Panel'))
self.ViewLivePanel.setToolTip(
translate('OpenLP.MainWindow', 'Toggle Live Panel'))
self.ViewLivePanel.setStatusTip(translate('OpenLP.MainWindow',
'Toggle the visibility of the live panel.'))
- self.ViewLivePanel.setShortcut(
- translate('OpenLP.MainWindow', 'F12'))
self.settingsPluginListItem.setText(translate('OpenLP.MainWindow',
'&Plugin List'))
self.settingsPluginListItem.setStatusTip(
translate('OpenLP.MainWindow', 'List the Plugins'))
- self.settingsPluginListItem.setShortcut(
- translate('OpenLP.MainWindow', 'Alt+F7'))
self.HelpDocumentationItem.setText(
translate('OpenLP.MainWindow', '&User Guide'))
self.HelpAboutItem.setText(translate('OpenLP.MainWindow', '&About'))
self.HelpAboutItem.setStatusTip(
translate('OpenLP.MainWindow', 'More information about OpenLP'))
- self.HelpAboutItem.setShortcut(
- translate('OpenLP.MainWindow', 'Ctrl+F1'))
self.HelpOnlineHelpItem.setText(
translate('OpenLP.MainWindow', '&Online Help'))
# Uncomment after 1.9.5 beta string freeze
@@ -467,8 +456,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
log.info(u'MainWindow loaded')
- actionList = ActionList()
-
def __init__(self, screens, clipboard, arguments):
"""
This constructor sets up the interface, the various managers, and the
@@ -485,7 +472,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.serviceSettingsSection = u'servicemanager'
self.songsSettingsSection = u'songs'
self.serviceNotSaved = False
- self.actionList = ActionList()
self.settingsmanager = SettingsManager(screens)
self.aboutForm = AboutForm(self)
self.settingsForm = SettingsForm(self.screens, self, self)
@@ -510,16 +496,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.ExportThemeItem,
QtCore.SIGNAL(u'triggered()'),
self.themeManagerContents.onExportTheme)
- QtCore.QObject.connect(self.ViewMediaManagerItem,
- QtCore.SIGNAL(u'triggered(bool)'), self.toggleMediaManager)
- QtCore.QObject.connect(self.ViewServiceManagerItem,
- QtCore.SIGNAL(u'triggered(bool)'), self.toggleServiceManager)
- QtCore.QObject.connect(self.ViewThemeManagerItem,
- QtCore.SIGNAL(u'triggered(bool)'), self.toggleThemeManager)
- QtCore.QObject.connect(self.ViewPreviewPanel,
- QtCore.SIGNAL(u'toggled(bool)'), self.setPreviewPanelVisibility)
- QtCore.QObject.connect(self.ViewLivePanel,
- QtCore.SIGNAL(u'toggled(bool)'), self.setLivePanelVisibility)
QtCore.QObject.connect(self.mediaManagerDock,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.ViewMediaManagerItem.setChecked)
@@ -533,32 +509,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
QtCore.QObject.connect(self.HelpOnlineHelpItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpOnLineHelpClicked)
- QtCore.QObject.connect(self.HelpAboutItem,
- QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked)
QtCore.QObject.connect(self.ToolsOpenDataFolder,
QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked)
- QtCore.QObject.connect(self.settingsPluginListItem,
- QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked)
QtCore.QObject.connect(self.DisplayTagItem,
QtCore.SIGNAL(u'triggered()'), self.onDisplayTagItemClicked)
QtCore.QObject.connect(self.SettingsConfigureItem,
QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
QtCore.QObject.connect(self.SettingsShortcutsItem,
QtCore.SIGNAL(u'triggered()'), self.onSettingsShortcutsItemClicked)
- QtCore.QObject.connect(self.FileNewItem, QtCore.SIGNAL(u'triggered()'),
- self.ServiceManagerContents.onNewServiceClicked)
- QtCore.QObject.connect(self.FileOpenItem,
- QtCore.SIGNAL(u'triggered()'),
- self.ServiceManagerContents.onLoadServiceClicked)
- QtCore.QObject.connect(self.FileSaveItem,
- QtCore.SIGNAL(u'triggered()'),
- self.ServiceManagerContents.saveFile)
- QtCore.QObject.connect(self.FileSaveAsItem,
- QtCore.SIGNAL(u'triggered()'),
- self.ServiceManagerContents.saveFileAs)
- QtCore.QObject.connect(self.printServiceOrderItem,
- QtCore.SIGNAL(u'triggered()'),
- self.ServiceManagerContents.printServiceOrder)
# i18n set signals for languages
self.LanguageGroup.triggered.connect(LanguageManager.set_language)
QtCore.QObject.connect(self.ModeDefaultItem,
@@ -781,7 +739,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
Show the shortcuts dialog
"""
- self.shortcutForm.exec_(self.actionList)
+ if self.shortcutForm.exec_():
+ self.shortcutForm.save()
def onModeDefaultItemClicked(self):
"""
@@ -928,19 +887,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
unicode(translate('OpenLP.MainWindow', 'Default Theme: %s')) %
theme)
- def toggleMediaManager(self, visible):
- if self.mediaManagerDock.isVisible() != visible:
- self.mediaManagerDock.setVisible(visible)
+ def toggleMediaManager(self):
+ self.mediaManagerDock.setVisible(not self.mediaManagerDock.isVisible())
- def toggleServiceManager(self, visible):
- if self.serviceManagerDock.isVisible() != visible:
- self.serviceManagerDock.setVisible(visible)
+ def toggleServiceManager(self):
+ self.serviceManagerDock.setVisible(not self.serviceManagerDock.isVisible())
- def toggleThemeManager(self, visible):
- if self.themeManagerDock.isVisible() != visible:
- self.themeManagerDock.setVisible(visible)
+ def toggleThemeManager(self):
+ self.themeManagerDock.setVisible(not self.themeManagerDock.isVisible())
- def setPreviewPanelVisibility(self, visible):
+ def setPreviewPanelVisibility(self, visible=None):
"""
Sets the visibility of the preview panel including saving the setting
and updating the menu.
@@ -950,12 +906,14 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
True - Visible
False - Hidden
"""
+ if visible is None:
+ visible = self.ViewPreviewPanel.isVisible()
self.previewController.panel.setVisible(visible)
QtCore.QSettings().setValue(u'user interface/preview panel',
QtCore.QVariant(visible))
self.ViewPreviewPanel.setChecked(visible)
- def setLivePanelVisibility(self, visible):
+ def setLivePanelVisibility(self, visible=None):
"""
Sets the visibility of the live panel including saving the setting and
updating the menu.
@@ -965,6 +923,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
True - Visible
False - Hidden
"""
+ if visible is None:
+ visible = self.ViewLivePanel.isVisible()
self.liveController.panel.setVisible(visible)
QtCore.QSettings().setValue(u'user interface/live panel',
QtCore.QVariant(visible))
@@ -1022,8 +982,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.FileMenu.addSeparator()
for fileId, filename in enumerate(recentFilesToDisplay):
log.debug('Recent file name: %s', filename)
- action = QtGui.QAction(u'&%d %s' % (fileId + 1,
- QtCore.QFileInfo(filename).fileName()), self)
+ action = base_action(self, u'')
+ action.setText(u'&%d %s' %
+ (fileId + 1, QtCore.QFileInfo(filename).fileName()))
action.setData(QtCore.QVariant(filename))
self.connect(action, QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onRecentServiceClicked)
diff --git a/openlp/core/ui/printservicedialog.py b/openlp/core/ui/printservicedialog.py
index 97f4b4060..9593e9ec4 100644
--- a/openlp/core/ui/printservicedialog.py
+++ b/openlp/core/ui/printservicedialog.py
@@ -132,6 +132,8 @@ class Ui_PrintServiceDialog(object):
self.groupLayout = QtGui.QVBoxLayout()
self.slideTextCheckBox = QtGui.QCheckBox()
self.groupLayout.addWidget(self.slideTextCheckBox)
+ self.pageBreakAfterText = QtGui.QCheckBox()
+ self.groupLayout.addWidget(self.pageBreakAfterText)
self.notesCheckBox = QtGui.QCheckBox()
self.groupLayout.addWidget(self.notesCheckBox)
self.metaDataCheckBox = QtGui.QCheckBox()
@@ -149,6 +151,8 @@ class Ui_PrintServiceDialog(object):
printServiceDialog.setWindowTitle(UiStrings.PrintServiceOrder)
self.slideTextCheckBox.setText(translate('OpenLP.PrintServiceForm',
'Include slide text if available'))
+ self.pageBreakAfterText.setText(translate('OpenLP.PrintServiceForm',
+ 'Add page break before each text item.'))
self.notesCheckBox.setText(translate('OpenLP.PrintServiceForm',
'Include service item notes'))
self.metaDataCheckBox.setText(translate('OpenLP.PrintServiceForm',
diff --git a/openlp/core/ui/printserviceform.py b/openlp/core/ui/printserviceform.py
index 4e0f018a4..01b937d61 100644
--- a/openlp/core/ui/printserviceform.py
+++ b/openlp/core/ui/printserviceform.py
@@ -24,12 +24,65 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import datetime
+import os
from PyQt4 import QtCore, QtGui
+from lxml import html
-from openlp.core.lib import translate
+from openlp.core.lib import translate, get_text_file_string
from openlp.core.lib.ui import UiStrings
from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize
+from openlp.core.utils import AppLocation
+
+DEFAULT_CSS = """/*
+Edit this file to customize the service order print. Note, that not all CSS
+properties are supported. See:
+http://doc.trolltech.com/4.7/richtext-html-subset.html#css-properties
+*/
+
+.serviceTitle {
+ font-weight:600;
+ font-size:x-large;
+ color:black;
+}
+
+.itemTitle {
+ font-weight:600;
+ font-size:large;
+ color:black;
+}
+
+.itemText {
+ color:black;
+}
+
+.itemFooter {
+ font-size:8px;
+ color:black;
+}
+
+.itemNotesTitle {
+ font-weight:bold;
+ font-size:12px;
+ color:black;
+}
+
+.itemNotesText {
+ font-size:11px;
+ color:black;
+}
+
+.customNotesTitle {
+ font-weight:bold;
+ font-size:11px;
+ color:black;
+}
+
+.customNotesText {
+ font-size:11px;
+ color:black;
+}
+"""
class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
@@ -50,6 +103,10 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
settings.beginGroup(u'advanced')
self.slideTextCheckBox.setChecked(settings.value(
u'print slide text', QtCore.QVariant(False)).toBool())
+ self.pageBreakAfterText.setChecked(settings.value(
+ u'add page break', QtCore.QVariant(False)).toBool())
+ if not self.slideTextCheckBox.isChecked():
+ self.pageBreakAfterText.setDisabled(True)
self.metaDataCheckBox.setChecked(settings.value(
u'print file meta data', QtCore.QVariant(False)).toBool())
self.notesCheckBox.setChecked(settings.value(
@@ -76,6 +133,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
QtCore.SIGNAL(u'triggered()'), self.copyText)
QtCore.QObject.connect(self.htmlCopy,
QtCore.SIGNAL(u'triggered()'), self.copyHtmlText)
+ QtCore.QObject.connect(self.slideTextCheckBox,
+ QtCore.SIGNAL(u'stateChanged(int)'),
+ self.onSlideTextCheckBoxChanged)
self.updatePreviewText()
def toggleOptions(self, checked):
@@ -93,59 +153,124 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
"""
Creates the html text and updates the html of *self.document*.
"""
- text = u''
- if self.titleLineEdit.text():
- text += u'
%s
' % unicode(self.titleLineEdit.text())
- for item in self.serviceManager.serviceItems:
+ html_data = html.fromstring(
+ u'%s' % unicode(self.titleLineEdit.text()))
+ css_path = os.path.join(
+ AppLocation.get_data_path(), u'servicePrint.css')
+ if not os.path.isfile(css_path):
+ # Create default css file.
+ css_file = open(css_path, u'w')
+ css_file.write(DEFAULT_CSS)
+ css_file.close()
+ custom_css = get_text_file_string(css_path)
+ self._addChildToParent(
+ u'style', custom_css, html_data.head, u'type', u'text/css')
+ self._addChildToParent(u'body', parent=html_data)
+ self._addChildToParent(u'span', unicode(self.titleLineEdit.text()),
+ html_data.body, u'class', u'serviceTitle')
+ for index, item in enumerate(self.serviceManager.serviceItems):
item = item[u'service_item']
+ div = self._addChildToParent(u'div', parent=html_data.body)
# Add the title of the service item.
- text += u' %s
' % (item.icon,
- item.get_display_title())
- # Add slide text of the service item.
+ item_title = self._addChildToParent(
+ u'h2', parent=div, attribute=u'class', value=u'itemTitle')
+ self._addChildToParent(
+ u'img', parent=item_title, attribute=u'src', value=item.icon)
+ self._fromstring(
+ u' %s' % item.get_display_title(), item_title)
if self.slideTextCheckBox.isChecked():
+ # Add the text of the service item.
if item.is_text():
- # Add the text of the service item.
- verse = None
+ verse_def = None
for slide in item.get_frames():
- if not verse:
- text += u'' + slide[u'html']
- verse = slide[u'verseTag']
- elif verse != slide[u'verseTag']:
- text += u'<\p>
' + slide[u'html']
- verse = slide[u'verseTag']
+ if not verse_def or verse_def != slide[u'verseTag']:
+ p = self._addChildToParent(u'p', parent=div,
+ attribute=u'class', value=u'itemText')
else:
- text += u'
' + slide[u'html']
- text += u'
'
+ self._addChildToParent(u'br', parent=p)
+ self._fromstring(u'%s' % slide[u'html'], p)
+ verse_def = slide[u'verseTag']
+ # Break the page before the div element.
+ if index != 0 and self.pageBreakAfterText.isChecked():
+ div.set(u'style', u'page-break-before:always')
+ # Add the image names of the service item.
elif item.is_image():
- # Add the image names of the service item.
- text += u''
+ ol = self._addChildToParent(u'ol', parent=div)
for slide in range(len(item.get_frames())):
- text += u'%s
' % \
- item.get_frame_title(slide)
- text += u'
'
+ self._addChildToParent(u'li', item.get_frame_title(slide), ol)
+ # add footer
if item.foot_text:
- # add footer
- text += u'%s
' % item.foot_text
+ self._fromstring(
+ item.foot_text, div, u'class', u'itemFooter')
# Add service items' notes.
if self.notesCheckBox.isChecked():
if item.notes:
- text += u'%s
%s' % (translate(
- 'OpenLP.ServiceManager', 'Notes:'),
- item.notes.replace(u'\n', u'
'))
+ p = self._addChildToParent(u'p', parent=div)
+ self._addChildToParent(u'span', unicode(
+ translate('OpenLP.ServiceManager', 'Notes:')), p,
+ u'class', u'itemNotesTitle')
+ self._fromstring(u' %s' % item.notes.replace(
+ u'\n', u'
'), p, u'class', u'itemNotesText')
# Add play length of media files.
if item.is_media() and self.metaDataCheckBox.isChecked():
tme = item.media_length
if item.end_time > 0:
tme = item.end_time - item.start_time
- text += u'%s %s
' % (translate(
- 'OpenLP.ServiceManager', u'Playing time:'),
- unicode(datetime.timedelta(seconds=tme)))
+ title = self._fromstring(u'%s
' %
+ translate('OpenLP.ServiceManager', 'Playing time:'), div)
+ self._fromstring(u'%s' %
+ unicode(datetime.timedelta(seconds=tme)), title)
+ # Add the custom service notes:
if self.footerTextEdit.toPlainText():
- text += u'%s
%s' % (translate('OpenLP.ServiceManager',
- u'Custom Service Notes:'), self.footerTextEdit.toPlainText())
- self.document.setHtml(text)
+ self._addChildToParent(u'span', translate('OpenLP.ServiceManager',
+ u'Custom Service Notes:'), div, u'class', u'customNotesTitle')
+ self._addChildToParent(
+ u'span', u' %s' % self.footerTextEdit.toPlainText(), div,
+ u'class', u'customNotesText')
+ self.document.setHtml(html.tostring(html_data))
self.previewWidget.updatePreview()
+ def _addChildToParent(self, tag, text=None, parent=None, attribute=None,
+ value=None):
+ """
+ Creates a html element. If ``text`` is given, the element's text will
+ set and if a ``parent`` is given, the element is appended.
+
+ ``tag``
+ The html tag, e. g. ``u'span'``. Defaults to ``None``.
+
+ ``text``
+ The text for the tag. Defaults to ``None``.
+
+ ``parent``
+ The parent element. Defaults to ``None``.
+
+ ``attribute``
+ An optional attribute, for instance ``u'class``.
+
+ ``value``
+ The value for the given ``attribute``. It does not have a meaning,
+ if the attribute is left to its default.
+ """
+ element = html.Element(tag)
+ if text is not None:
+ element.text = unicode(text)
+ if parent is not None:
+ parent.append(element)
+ if attribute is not None:
+ element.set(attribute, value if value is not None else u'')
+ return element
+
+ def _fromstring(self, string, parent, attribute=None, value=None):
+ """
+ This is used to create a child html element from a string.
+ """
+ element = html.fromstring(string)
+ if attribute is not None:
+ element.set(attribute, value if value is not None else u'')
+ parent.append(element)
+ return element
+
def paintRequested(self, printer):
"""
Paint the preview of the *self.document*.
@@ -232,6 +357,13 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
else:
self.copyTextButton.setText(UiStrings.CopyToText)
+ def onSlideTextCheckBoxChanged(self, state):
+ """
+ Disable or enable the ``pageBreakAfterText`` checkbox as it should only
+ be enabled, when the ``slideTextCheckBox`` is enabled.
+ """
+ self.pageBreakAfterText.setDisabled(state == QtCore.Qt.Unchecked)
+
def saveOptions(self):
"""
Save the settings and close the dialog.
@@ -241,6 +373,8 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
settings.beginGroup(u'advanced')
settings.setValue(u'print slide text',
QtCore.QVariant(self.slideTextCheckBox.isChecked()))
+ settings.setValue(u'add page break',
+ QtCore.QVariant(self.pageBreakAfterText.isChecked()))
settings.setValue(u'print file meta data',
QtCore.QVariant(self.metaDataCheckBox.isChecked()))
settings.setValue(u'print notes',
diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py
index 9c1c63917..ba9ca718a 100644
--- a/openlp/core/ui/servicemanager.py
+++ b/openlp/core/ui/servicemanager.py
@@ -32,14 +32,16 @@ log = logging.getLogger(__name__)
from PyQt4 import QtCore, QtGui
-from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
- Receiver, build_icon, ItemCapabilities, SettingsManager, translate
+from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
+ ItemCapabilities, SettingsManager, translate
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, find_and_set_in_combo_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.ui.printserviceform import PrintServiceForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
split_filename
+from openlp.core.utils.actions import ActionList, CategoryOrder
class ServiceManagerList(QtGui.QTreeWidget):
"""
@@ -164,38 +166,55 @@ class ServiceManager(QtGui.QWidget):
u':/services/service_top.png',
translate('OpenLP.ServiceManager',
'Move item to the top of the service.'),
- self.onServiceTop, shortcut=QtCore.Qt.Key_Home)
+ self.onServiceTop, shortcuts=[QtCore.Qt.Key_Home])
+ self.serviceManagerList.moveTop.setObjectName(u'moveTop')
+ action_list = ActionList.get_instance()
+ action_list.add_category(UiStrings.Service, CategoryOrder.standardToolbar)
+ action_list.add_action(
+ self.serviceManagerList.moveTop, UiStrings.Service)
self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &up'),
u':/services/service_up.png',
translate('OpenLP.ServiceManager',
'Move item up one position in the service.'),
- self.onServiceUp, shortcut=QtCore.Qt.Key_PageUp)
+ self.onServiceUp, shortcuts=[QtCore.Qt.Key_PageUp])
+ self.serviceManagerList.moveUp.setObjectName(u'moveUp')
+ action_list.add_action(self.serviceManagerList.moveUp, UiStrings.Service)
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &down'),
u':/services/service_down.png',
translate('OpenLP.ServiceManager',
'Move item down one position in the service.'),
- self.onServiceDown, shortcut=QtCore.Qt.Key_PageDown)
+ self.onServiceDown, shortcuts=[QtCore.Qt.Key_PageDown])
+ self.serviceManagerList.moveDown.setObjectName(u'moveDown')
+ action_list.add_action(
+ self.serviceManagerList.moveDown, UiStrings.Service)
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move to &bottom'),
u':/services/service_bottom.png',
translate('OpenLP.ServiceManager',
'Move item to the end of the service.'),
- self.onServiceEnd, shortcut=QtCore.Qt.Key_End)
+ self.onServiceEnd, shortcuts=[QtCore.Qt.Key_End])
+ self.serviceManagerList.moveBottom.setObjectName(u'moveBottom')
+ action_list.add_action(
+ self.serviceManagerList.moveBottom, UiStrings.Service)
self.serviceManagerList.down = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &down'),
None,
translate('OpenLP.ServiceManager',
'Moves the selection down the window.'),
- self.onMoveSelectionDown, shortcut=QtCore.Qt.Key_Down)
+ self.onMoveSelectionDown, shortcuts=[QtCore.Qt.Key_Down])
+ self.serviceManagerList.down.setObjectName(u'down')
+ action_list.add_action(self.serviceManagerList.down)
self.serviceManagerList.down.setVisible(False)
self.serviceManagerList.up = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move up'),
None,
translate('OpenLP.ServiceManager',
'Moves the selection up the window.'),
- self.onMoveSelectionUp, shortcut=QtCore.Qt.Key_Up)
+ self.onMoveSelectionUp, shortcuts=[QtCore.Qt.Key_Up])
+ self.serviceManagerList.up.setObjectName(u'up')
+ action_list.add_action(self.serviceManagerList.up)
self.serviceManagerList.up.setVisible(False)
self.orderToolbar.addSeparator()
self.serviceManagerList.delete = self.orderToolbar.addToolbarButton(
@@ -210,22 +229,28 @@ class ServiceManager(QtGui.QWidget):
u':/services/service_expand_all.png',
translate('OpenLP.ServiceManager',
'Expand all the service items.'),
- self.onExpandAll, shortcut=QtCore.Qt.Key_Plus)
+ self.onExpandAll, shortcuts=[QtCore.Qt.Key_Plus])
+ self.serviceManagerList.expand.setObjectName(u'expand')
+ action_list.add_action(self.serviceManagerList.expand, UiStrings.Service)
self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Collapse all'),
u':/services/service_collapse_all.png',
translate('OpenLP.ServiceManager',
'Collapse all the service items.'),
- self.onCollapseAll, shortcut=QtCore.Qt.Key_Minus)
+ self.onCollapseAll, shortcuts=[QtCore.Qt.Key_Minus])
+ self.serviceManagerList.collapse.setObjectName(u'collapse')
+ action_list.add_action(
+ self.serviceManagerList.collapse, UiStrings.Service)
self.orderToolbar.addSeparator()
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Go Live'),
u':/general/general_live.png',
translate('OpenLP.ServiceManager',
- 'Send the selected item to Live.'),
- self.makeLive, shortcut=QtCore.Qt.Key_Enter,
- alternate=QtCore.Qt.Key_Return)
- self.orderToolbar.setObjectName(u'orderToolbar')
+ 'Send the selected item to Live.'), self.makeLive,
+ shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
+ self.serviceManagerList.makeLive.setObjectName(u'orderToolbar')
+ action_list.add_action(
+ self.serviceManagerList.makeLive, UiStrings.Service)
self.layout.addWidget(self.orderToolbar)
# Connect up our signals and slots
QtCore.QObject.connect(self.themeComboBox,
@@ -300,7 +325,6 @@ class ServiceManager(QtGui.QWidget):
self.themeMenu = QtGui.QMenu(
translate('OpenLP.ServiceManager', '&Change Item Theme'))
self.menu.addMenu(self.themeMenu)
- self.setServiceHotkeys()
self.serviceManagerList.addActions(
[self.serviceManagerList.moveDown,
self.serviceManagerList.moveUp,
@@ -314,19 +338,6 @@ class ServiceManager(QtGui.QWidget):
])
self.configUpdated()
- def setServiceHotkeys(self):
- actionList = self.mainwindow.actionList
- actionList.add_action(self.serviceManagerList.moveDown, u'Service')
- actionList.add_action(self.serviceManagerList.moveUp, u'Service')
- actionList.add_action(self.serviceManagerList.moveTop, u'Service')
- actionList.add_action(self.serviceManagerList.moveBottom, u'Service')
- actionList.add_action(self.serviceManagerList.makeLive, u'Service')
- actionList.add_action(self.serviceManagerList.up, u'Service')
- actionList.add_action(self.serviceManagerList.down, u'Service')
- actionList.add_action(self.serviceManagerList.expand, u'Service')
- actionList.add_action(self.serviceManagerList.collapse, u'Service')
-
-
def setModified(self, modified=True):
"""
Setter for property "modified". Sets whether or not the current service
@@ -691,9 +702,9 @@ class ServiceManager(QtGui.QWidget):
Called by the SlideController to request a preview item be made live
and allows the next preview to be updated if relevent.
"""
- id, row = message.split(u':')
+ uuid, row = message.split(u':')
for sitem in self.serviceItems:
- if sitem[u'service_item']._uuid == id:
+ if sitem[u'service_item']._uuid == uuid:
item = self.serviceManagerList.topLevelItem(sitem[u'order'] - 1)
self.serviceManagerList.setCurrentItem(item)
self.makeLive(int(row))
@@ -1021,7 +1032,7 @@ class ServiceManager(QtGui.QWidget):
editId, uuid = message.split(u':')
for item in self.serviceItems:
if item[u'service_item']._uuid == uuid:
- item[u'service_item'].edit_id = editId
+ item[u'service_item'].edit_id = int(editId)
self.setModified(True)
def replaceServiceItem(self, newItem):
@@ -1259,15 +1270,9 @@ class ServiceManager(QtGui.QWidget):
for theme in theme_list:
self.themeComboBox.addItem(theme)
action = context_menu_action(self.serviceManagerList, None, theme,
- self.onThemeChangeAction)
+ self.onThemeChangeAction, context=QtCore.Qt.WidgetShortcut)
self.themeMenu.addAction(action)
- index = self.themeComboBox.findText(self.service_theme,
- QtCore.Qt.MatchExactly)
- # Not Found
- if index == -1:
- index = 0
- self.service_theme = u''
- self.themeComboBox.setCurrentIndex(index)
+ find_and_set_in_combo_box(self.themeComboBox, self.service_theme)
self.mainwindow.renderManager.set_service_theme(self.service_theme)
self.regenerateServiceItems()
diff --git a/openlp/core/ui/shortcutlistdialog.py b/openlp/core/ui/shortcutlistdialog.py
index 4e5b9e270..288086cba 100644
--- a/openlp/core/ui/shortcutlistdialog.py
+++ b/openlp/core/ui/shortcutlistdialog.py
@@ -31,41 +31,72 @@ from openlp.core.lib import translate, build_icon
class Ui_ShortcutListDialog(object):
def setupUi(self, shortcutListDialog):
shortcutListDialog.setObjectName(u'shortcutListDialog')
- self.dialogLayout = QtGui.QVBoxLayout(shortcutListDialog)
- self.dialogLayout.setObjectName(u'dialogLayout')
+ shortcutListDialog.resize(500, 438)
+ self.shortcutListLayout = QtGui.QVBoxLayout(shortcutListDialog)
+ self.shortcutListLayout.setObjectName(u'shortcutListLayout')
+ self.descriptionLabel = QtGui.QLabel(shortcutListDialog)
+ self.descriptionLabel.setObjectName(u'descriptionLabel')
+ self.descriptionLabel.setWordWrap(True)
+ self.shortcutListLayout.addWidget(self.descriptionLabel)
self.treeWidget = QtGui.QTreeWidget(shortcutListDialog)
- self.treeWidget.setAlternatingRowColors(True)
self.treeWidget.setObjectName(u'treeWidget')
+ self.treeWidget.setAlternatingRowColors(True)
self.treeWidget.setColumnCount(3)
- self.dialogLayout.addWidget(self.treeWidget)
- self.defaultButton = QtGui.QRadioButton(shortcutListDialog)
- self.defaultButton.setChecked(True)
- self.defaultButton.setObjectName(u'defaultButton')
- self.dialogLayout.addWidget(self.defaultButton)
- self.customLayout = QtGui.QHBoxLayout()
- self.customLayout.setObjectName(u'customLayout')
- self.customButton = QtGui.QRadioButton(shortcutListDialog)
- self.customButton.setObjectName(u'customButton')
- self.customLayout.addWidget(self.customButton)
- self.shortcutButton = QtGui.QPushButton(shortcutListDialog)
- self.shortcutButton.setIcon(
+ self.treeWidget.setColumnWidth(0, 250)
+ self.shortcutListLayout.addWidget(self.treeWidget)
+ self.detailsLayout = QtGui.QGridLayout()
+ self.detailsLayout.setObjectName(u'detailsLayout')
+ self.detailsLayout.setContentsMargins(-1, 0, -1, -1)
+ self.defaultRadioButton = QtGui.QRadioButton(shortcutListDialog)
+ self.defaultRadioButton.setObjectName(u'defaultRadioButton')
+ self.defaultRadioButton.setChecked(True)
+ self.detailsLayout.addWidget(self.defaultRadioButton, 0, 0, 1, 1)
+ self.customRadioButton = QtGui.QRadioButton(shortcutListDialog)
+ self.customRadioButton.setObjectName(u'customRadioButton')
+ self.detailsLayout.addWidget(self.customRadioButton, 1, 0, 1, 1)
+ self.primaryLayout = QtGui.QHBoxLayout()
+ self.primaryLayout.setObjectName(u'primaryLayout')
+ self.primaryPushButton = QtGui.QPushButton(shortcutListDialog)
+ self.primaryPushButton.setObjectName(u'primaryPushButton')
+ self.primaryPushButton.setMinimumSize(QtCore.QSize(84, 0))
+ self.primaryPushButton.setIcon(
build_icon(u':/system/system_configure_shortcuts.png'))
- self.shortcutButton.setCheckable(True)
- self.shortcutButton.setObjectName(u'shortcutButton')
- self.customLayout.addWidget(self.shortcutButton)
- self.clearShortcutButton = QtGui.QToolButton(shortcutListDialog)
- self.clearShortcutButton.setIcon(
+ self.primaryPushButton.setCheckable(True)
+ self.primaryLayout.addWidget(self.primaryPushButton)
+ self.clearPrimaryButton = QtGui.QToolButton(shortcutListDialog)
+ self.clearPrimaryButton.setObjectName(u'clearPrimaryButton')
+ self.clearPrimaryButton.setMinimumSize(QtCore.QSize(0, 16))
+ self.clearPrimaryButton.setIcon(
build_icon(u':/system/clear_shortcut.png'))
- self.clearShortcutButton.setAutoRaise(True)
- self.clearShortcutButton.setObjectName(u'clearShortcutButton')
- self.customLayout.addWidget(self.clearShortcutButton)
- self.customLayout.addStretch()
- self.dialogLayout.addLayout(self.customLayout)
+ self.primaryLayout.addWidget(self.clearPrimaryButton)
+ self.detailsLayout.addLayout(self.primaryLayout, 1, 1, 1, 1)
+ self.alternateLayout = QtGui.QHBoxLayout()
+ self.alternateLayout.setObjectName(u'alternateLayout')
+ self.alternatePushButton = QtGui.QPushButton(shortcutListDialog)
+ self.alternatePushButton.setObjectName(u'alternatePushButton')
+ self.alternatePushButton.setCheckable(True)
+ self.alternatePushButton.setIcon(
+ build_icon(u':/system/system_configure_shortcuts.png'))
+ self.alternateLayout.addWidget(self.alternatePushButton)
+ self.clearAlternateButton = QtGui.QToolButton(shortcutListDialog)
+ self.clearAlternateButton.setObjectName(u'clearAlternateButton')
+ self.clearAlternateButton.setIcon(
+ build_icon(u':/system/clear_shortcut.png'))
+ self.alternateLayout.addWidget(self.clearAlternateButton)
+ self.detailsLayout.addLayout(self.alternateLayout, 1, 2, 1, 1)
+ self.primaryLabel = QtGui.QLabel(shortcutListDialog)
+ self.primaryLabel.setObjectName(u'primaryLabel')
+ self.detailsLayout.addWidget(self.primaryLabel, 0, 1, 1, 1)
+ self.alternateLabel = QtGui.QLabel(shortcutListDialog)
+ self.alternateLabel.setObjectName(u'alternateLabel')
+ self.detailsLayout.addWidget(self.alternateLabel, 0, 2, 1, 1)
+ self.shortcutListLayout.addLayout(self.detailsLayout)
self.buttonBox = QtGui.QDialogButtonBox(shortcutListDialog)
- self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
- QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Reset)
self.buttonBox.setObjectName(u'buttonBox')
- self.dialogLayout.addWidget(self.buttonBox)
+ self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
+ QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.RestoreDefaults)
+ self.shortcutListLayout.addWidget(self.buttonBox)
self.retranslateUi(shortcutListDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
shortcutListDialog.accept)
@@ -76,13 +107,24 @@ class Ui_ShortcutListDialog(object):
def retranslateUi(self, shortcutListDialog):
shortcutListDialog.setWindowTitle(
translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts'))
+ self.descriptionLabel.setText(translate('OpenLP.ShortcutListDialog',
+ 'Select an action and click one of the buttons below to start '
+ 'capturing a new primary or alternate shortcut, respectively.'))
self.treeWidget.setHeaderLabels([
translate('OpenLP.ShortcutListDialog', 'Action'),
translate('OpenLP.ShortcutListDialog', 'Shortcut'),
translate('OpenLP.ShortcutListDialog', 'Alternate')])
- self.defaultButton.setText(
- translate('OpenLP.ShortcutListDialog', 'Default: %s'))
- self.customButton.setText(
- translate('OpenLP.ShortcutListDialog', 'Custom:'))
- self.shortcutButton.setText(
- translate('OpenLP.ShortcutListDialog', 'None'))
+ self.defaultRadioButton.setText(
+ translate('OpenLP.ShortcutListDialog', 'Default'))
+ self.customRadioButton.setText(
+ translate('OpenLP.ShortcutListDialog', 'Custom'))
+ self.primaryPushButton.setToolTip(
+ translate('OpenLP.ShortcutListDialog', 'Capture shortcut.'))
+ self.alternatePushButton.setToolTip(
+ translate('OpenLP.ShortcutListDialog', 'Capture shortcut.'))
+ self.clearPrimaryButton.setToolTip(
+ translate('OpenLP.ShortcutListDialog',
+ 'Restore the default shortcut of this action.'))
+ self.clearAlternateButton.setToolTip(
+ translate('OpenLP.ShortcutListDialog',
+ 'Restore the default shortcut of this action.'))
diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py
index e87ba3ada..26bfddadd 100644
--- a/openlp/core/ui/shortcutlistform.py
+++ b/openlp/core/ui/shortcutlistform.py
@@ -30,6 +30,7 @@ import re
from PyQt4 import QtCore, QtGui
from openlp.core.utils import translate
+from openlp.core.utils.actions import ActionList
from shortcutlistdialog import Ui_ShortcutListDialog
REMOVE_AMPERSAND = re.compile(r'&{1}')
@@ -41,72 +42,391 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
The shortcut list dialog
"""
- def __init__(self, parent):
- """
- Do some initialisation stuff
- """
+ def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
- self.actionList = None
- self.captureShortcut = False
- QtCore.QObject.connect(self.shortcutButton,
- QtCore.SIGNAL(u'toggled(bool)'), self.onShortcutButtonClicked)
+ self.changedActions = {}
+ self.action_list = ActionList.get_instance()
+ QtCore.QObject.connect(self.primaryPushButton,
+ QtCore.SIGNAL(u'toggled(bool)'), self.onPrimaryPushButtonClicked)
+ QtCore.QObject.connect(self.alternatePushButton,
+ QtCore.SIGNAL(u'toggled(bool)'), self.onAlternatePushButtonClicked)
+ QtCore.QObject.connect(self.treeWidget, QtCore.SIGNAL(
+ u'currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)'),
+ self.onCurrentItemChanged)
+ QtCore.QObject.connect(self.treeWidget,
+ QtCore.SIGNAL(u'itemDoubleClicked(QTreeWidgetItem*, int)'),
+ self.onItemDoubleClicked)
+ QtCore.QObject.connect(self.clearPrimaryButton,
+ QtCore.SIGNAL(u'clicked(bool)'), self.onClearPrimaryButtonClicked)
+ QtCore.QObject.connect(self.clearAlternateButton,
+ QtCore.SIGNAL(u'clicked(bool)'), self.onClearAlternateButtonClicked)
+ QtCore.QObject.connect(self.buttonBox,
+ QtCore.SIGNAL(u'clicked(QAbstractButton*)'),
+ self.onRestoreDefaultsClicked)
+ QtCore.QObject.connect(self.defaultRadioButton,
+ QtCore.SIGNAL(u'clicked(bool)'), self.onDefaultRadioButtonClicked)
+ QtCore.QObject.connect(self.customRadioButton,
+ QtCore.SIGNAL(u'clicked(bool)'), self.onCustomRadioButtonClicked)
+
+ def keyPressEvent(self, event):
+ if self.primaryPushButton.isChecked() or \
+ self.alternatePushButton.isChecked():
+ event.ignore()
+ elif event.key() == QtCore.Qt.Key_Escape:
+ event.accept()
+ self.close()
def keyReleaseEvent(self, event):
- Qt = QtCore.Qt
- if not self.captureShortcut:
+ if not self.primaryPushButton.isChecked() and \
+ not self.alternatePushButton.isChecked():
return
key = event.key()
- if key == Qt.Key_Shift or key == Qt.Key_Control or \
- key == Qt.Key_Meta or key == Qt.Key_Alt:
+ if key == QtCore.Qt.Key_Shift or key == QtCore.Qt.Key_Control or \
+ key == QtCore.Qt.Key_Meta or key == QtCore.Qt.Key_Alt:
return
key_string = QtGui.QKeySequence(key).toString()
- if event.modifiers() & Qt.ControlModifier == Qt.ControlModifier:
+ if event.modifiers() & QtCore.Qt.ControlModifier == \
+ QtCore.Qt.ControlModifier:
key_string = u'Ctrl+' + key_string
- if event.modifiers() & Qt.AltModifier == Qt.AltModifier:
+ if event.modifiers() & QtCore.Qt.AltModifier == QtCore.Qt.AltModifier:
key_string = u'Alt+' + key_string
- if event.modifiers() & Qt.ShiftModifier == Qt.ShiftModifier:
+ if event.modifiers() & QtCore.Qt.ShiftModifier == \
+ QtCore.Qt.ShiftModifier:
key_string = u'Shift+' + key_string
key_sequence = QtGui.QKeySequence(key_string)
- existing_key = QtGui.QKeySequence(u'Ctrl+Shift+F8')
- if key_sequence == existing_key:
- QtGui.QMessageBox.warning(
- self,
+ # The action we are attempting to change.
+ changing_action = self._currentItemAction()
+ shortcut_valid = True
+ for category in self.action_list.categories:
+ for action in category.actions:
+ shortcuts = self._actionShortcuts(action)
+ if key_sequence not in shortcuts:
+ continue
+ if action is changing_action:
+ if self.primaryPushButton.isChecked() and \
+ shortcuts.index(key_sequence) == 0:
+ continue
+ if self.alternatePushButton.isChecked() and \
+ shortcuts.index(key_sequence) == 1:
+ continue
+ # Have the same parent, thus they cannot have the same shortcut.
+ if action.parent() is changing_action.parent():
+ shortcut_valid = False
+ # The new shortcut is already assigned, but if both shortcuts
+ # are only valid in a different widget the new shortcut is
+ # vaild, because they will not interfere.
+ if action.shortcutContext() in [QtCore.Qt.WindowShortcut,
+ QtCore.Qt.ApplicationShortcut]:
+ shortcut_valid = False
+ if changing_action.shortcutContext() in \
+ [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
+ shortcut_valid = False
+ if not shortcut_valid:
+ QtGui.QMessageBox.warning(self,
translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'),
unicode(translate('OpenLP.ShortcutListDialog', 'The shortcut '
- '"%s" is already assigned to another action, please '
- 'use a different shortcut.')) % key_sequence.toString(),
+ '"%s" is already assigned to another action, please '
+ 'use a different shortcut.')) % key_sequence.toString(),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok
)
else:
- self.shortcutButton.setText(key_sequence.toString())
- self.shortcutButton.setChecked(False)
- self.captureShortcut = False
+ if self.primaryPushButton.isChecked():
+ self._adjustButton(self.primaryPushButton,
+ False, text=key_sequence.toString())
+ elif self.alternatePushButton.isChecked():
+ self._adjustButton(self.alternatePushButton,
+ False, text=key_sequence.toString())
- def exec_(self, actionList):
- self.actionList = actionList
- self.refreshActions()
+ def exec_(self):
+ self.changedActions = {}
+ self.reloadShortcutList()
+ self._adjustButton(self.primaryPushButton, False, False, u'')
+ self._adjustButton(self.alternatePushButton, False, False, u'')
return QtGui.QDialog.exec_(self)
- def refreshActions(self):
+ def reloadShortcutList(self):
+ """
+ Reload the ``treeWidget`` list to add new and remove old actions.
+ """
self.treeWidget.clear()
- for category in self.actionList.categories:
+ for category in self.action_list.categories:
+ # Check if the category is for internal use only.
+ if category.name is None:
+ continue
item = QtGui.QTreeWidgetItem([category.name])
for action in category.actions:
actionText = REMOVE_AMPERSAND.sub('', unicode(action.text()))
- if (len(action.shortcuts()) == 2):
- shortcutText = action.shortcuts()[0].toString()
- alternateText = action.shortcuts()[1].toString()
- else:
- shortcutText = action.shortcut().toString()
- alternateText = u''
- actionItem = QtGui.QTreeWidgetItem(
- [actionText, shortcutText, alternateText])
+ actionItem = QtGui.QTreeWidgetItem([actionText])
actionItem.setIcon(0, action.icon())
+ actionItem.setData(0,
+ QtCore.Qt.UserRole, QtCore.QVariant(action))
item.addChild(actionItem)
- item.setExpanded(True)
self.treeWidget.addTopLevelItem(item)
+ item.setExpanded(True)
+ self.refreshShortcutList()
- def onShortcutButtonClicked(self, toggled):
- self.captureShortcut = toggled
+ def refreshShortcutList(self):
+ """
+ This refreshes the item's shortcuts shown in the list. Note, this
+ neither adds new actions nor removes old actions.
+ """
+ iterator = QtGui.QTreeWidgetItemIterator(self.treeWidget)
+ while iterator.value():
+ item = iterator.value()
+ iterator += 1
+ action = self._currentItemAction(item)
+ if action is None:
+ continue
+ shortcuts = self._actionShortcuts(action)
+ if len(shortcuts) == 0:
+ item.setText(1, u'')
+ item.setText(2, u'')
+ elif len(shortcuts) == 1:
+ item.setText(1, shortcuts[0].toString())
+ item.setText(2, u'')
+ else:
+ item.setText(1, shortcuts[0].toString())
+ item.setText(2, shortcuts[1].toString())
+ self.onCurrentItemChanged()
+
+ def onPrimaryPushButtonClicked(self, toggled):
+ """
+ Save the new primary shortcut.
+ """
+ self.customRadioButton.setChecked(True)
+ if toggled:
+ self.alternatePushButton.setChecked(False)
+ return
+ action = self._currentItemAction()
+ if action is None:
+ return
+ shortcuts = self._actionShortcuts(action)
+ new_shortcuts = [QtGui.QKeySequence(self.primaryPushButton.text())]
+ if len(shortcuts) == 2:
+ new_shortcuts.append(shortcuts[1])
+ self.changedActions[action] = new_shortcuts
+ self.refreshShortcutList()
+
+ def onAlternatePushButtonClicked(self, toggled):
+ """
+ Save the new alternate shortcut.
+ """
+ self.customRadioButton.setChecked(True)
+ if toggled:
+ self.primaryPushButton.setChecked(False)
+ return
+ action = self._currentItemAction()
+ if action is None:
+ return
+ shortcuts = self._actionShortcuts(action)
+ new_shortcuts = []
+ if len(shortcuts) != 0:
+ new_shortcuts.append(shortcuts[0])
+ new_shortcuts.append(
+ QtGui.QKeySequence(self.alternatePushButton.text()))
+ self.changedActions[action] = new_shortcuts
+ self.refreshShortcutList()
+
+ def onItemDoubleClicked(self, item, column):
+ """
+ A item has been double clicked. The ``primaryPushButton`` will be
+ checked and the item's shortcut will be displayed.
+ """
+ action = self._currentItemAction(item)
+ if action is None:
+ return
+ self.primaryPushButton.setChecked(column in [0, 1])
+ self.alternatePushButton.setChecked(column not in [0, 1])
+ if column in [0, 1]:
+ self.primaryPushButton.setFocus(QtCore.Qt.OtherFocusReason)
+ else:
+ self.alternatePushButton.setFocus(QtCore.Qt.OtherFocusReason)
+ self.onCurrentItemChanged(item)
+
+ def onCurrentItemChanged(self, item=None, previousItem=None):
+ """
+ A item has been pressed. We adjust the button's text to the action's
+ shortcut which is encapsulate in the item.
+ """
+ action = self._currentItemAction(item)
+ self.primaryPushButton.setEnabled(action is not None)
+ self.alternatePushButton.setEnabled(action is not None)
+ primary_text = u''
+ alternate_text = u''
+ primary_label_text = u''
+ alternate_label_text = u''
+ if action is None:
+ self.primaryPushButton.setChecked(False)
+ self.alternatePushButton.setChecked(False)
+ else:
+ if len(action.defaultShortcuts) != 0:
+ primary_label_text = action.defaultShortcuts[0].toString()
+ if len(action.defaultShortcuts) == 2:
+ alternate_label_text = action.defaultShortcuts[1].toString()
+ shortcuts = self._actionShortcuts(action)
+ # We do not want to loose pending changes, that is why we have to
+ # keep the text when, this function has not been triggered by a signal.
+ if item is None:
+ primary_text = self.primaryPushButton.text()
+ alternate_text = self.alternatePushButton.text()
+ elif len(shortcuts) == 1:
+ primary_text = shortcuts[0].toString()
+ elif len(shortcuts) == 2:
+ primary_text = shortcuts[0].toString()
+ alternate_text = shortcuts[1].toString()
+ self.primaryPushButton.setText(primary_text)
+ self.alternatePushButton.setText(alternate_text)
+ self.primaryLabel.setText(primary_label_text)
+ self.alternateLabel.setText(alternate_label_text)
+ # We do not want to toggle and radio button, as the function has not
+ # been triggered by a signal.
+ if item is None:
+ return
+ if primary_label_text == primary_text and \
+ alternate_label_text == alternate_text:
+ self.defaultRadioButton.toggle()
+ else:
+ self.customRadioButton.toggle()
+
+ def onRestoreDefaultsClicked(self, button):
+ """
+ Restores all default shortcuts.
+ """
+ if self.buttonBox.buttonRole(button) != QtGui.QDialogButtonBox.ResetRole:
+ return
+ if QtGui.QMessageBox.question(self,
+ translate('OpenLP.ShortcutListDialog', 'Restore Default Shortcuts'),
+ translate('OpenLP.ShortcutListDialog', 'Do you want to restore all '
+ 'shortcuts to their defaults?'), QtGui.QMessageBox.StandardButtons(
+ QtGui.QMessageBox.Yes |
+ QtGui.QMessageBox.No)) == QtGui.QMessageBox.No:
+ return
+ self._adjustButton(self.primaryPushButton, False, text=u'')
+ self._adjustButton(self.alternatePushButton, False, text=u'')
+ for category in self.action_list.categories:
+ for action in category.actions:
+ self.changedActions[action] = action.defaultShortcuts
+ self.refreshShortcutList()
+
+ def onDefaultRadioButtonClicked(self, toggled):
+ """
+ The default radio button has been clicked, which means we have to make
+ sure, that we use the default shortcuts for the action.
+ """
+ if not toggled:
+ return
+ action = self._currentItemAction()
+ if action is None:
+ return
+ temp_shortcuts = self._actionShortcuts(action)
+ self.changedActions[action] = action.defaultShortcuts
+ self.refreshShortcutList()
+ primary_button_text = u''
+ alternate_button_text = u''
+ if len(temp_shortcuts) != 0:
+ primary_button_text = temp_shortcuts[0].toString()
+ if len(temp_shortcuts) == 2:
+ alternate_button_text = temp_shortcuts[1].toString()
+ self.primaryPushButton.setText(primary_button_text)
+ self.alternatePushButton.setText(alternate_button_text)
+
+ def onCustomRadioButtonClicked(self, toggled):
+ """
+ The custom shortcut radio button was clicked, thus we have to restore
+ the custom shortcuts by calling those functions triggered by button
+ clicks.
+ """
+ if not toggled:
+ return
+ self.onPrimaryPushButtonClicked(False)
+ self.onAlternatePushButtonClicked(False)
+ self.refreshShortcutList()
+
+ def save(self):
+ """
+ Save the shortcuts. **Note**, that we do not have to load the shortcuts,
+ as they are loaded in :class:`~openlp.core.utils.ActionList`.
+ """
+ settings = QtCore.QSettings()
+ settings.beginGroup(u'shortcuts')
+ for category in self.action_list.categories:
+ # Check if the category is for internal use only.
+ if category.name is None:
+ continue
+ for action in category.actions:
+ if self.changedActions .has_key(action):
+ action.setShortcuts(self.changedActions[action])
+ settings.setValue(
+ action.objectName(), QtCore.QVariant(action.shortcuts()))
+ settings.endGroup()
+
+ def onClearPrimaryButtonClicked(self, toggled):
+ """
+ Restore the defaults of this action.
+ """
+ self.primaryPushButton.setChecked(False)
+ action = self._currentItemAction()
+ if action is None:
+ return
+ shortcuts = self._actionShortcuts(action)
+ new_shortcuts = []
+ if len(action.defaultShortcuts) != 0:
+ new_shortcuts.append(action.defaultShortcuts[0])
+ if len(shortcuts) == 2:
+ new_shortcuts.append(shortcuts[1])
+ self.changedActions[action] = new_shortcuts
+ self.refreshShortcutList()
+ self.onCurrentItemChanged(self.treeWidget.currentItem())
+
+ def onClearAlternateButtonClicked(self, toggled):
+ """
+ Restore the defaults of this action.
+ """
+ self.alternatePushButton.setChecked(False)
+ action = self._currentItemAction()
+ if action is None:
+ return
+ shortcuts = self._actionShortcuts(action)
+ new_shortcuts = []
+ if len(shortcuts) != 0:
+ new_shortcuts.append(shortcuts[0])
+ if len(action.defaultShortcuts) == 2:
+ new_shortcuts.append(action.defaultShortcuts[1])
+ self.changedActions[action] = new_shortcuts
+ self.refreshShortcutList()
+ self.onCurrentItemChanged(self.treeWidget.currentItem())
+
+ def _actionShortcuts(self, action):
+ """
+ This returns the shortcuts for the given ``action``, which also includes
+ those shortcuts which are not saved yet but already assigned (as changes
+ are applied when closing the dialog).
+ """
+ if self.changedActions.has_key(action):
+ return self.changedActions[action]
+ return action.shortcuts()
+
+ def _currentItemAction(self, item=None):
+ """
+ Returns the action of the given ``item``. If no item is given, we return
+ the action of the current item of the ``treeWidget``.
+ """
+ if item is None:
+ item = self.treeWidget.currentItem()
+ if item is None:
+ return
+ return item.data(0, QtCore.Qt.UserRole).toPyObject()
+
+ def _adjustButton(self, button, checked=None, enabled=None, text=None):
+ """
+ Can be called to adjust more properties of the given ``button`` at once.
+ """
+ # Set the text before checking the button, because this emits a signal.
+ if text is not None:
+ button.setText(text)
+ if checked is not None:
+ button.setChecked(checked)
+ if enabled is not None:
+ button.setEnabled(enabled)
diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py
index 232653326..4f5ed1ea7 100644
--- a/openlp/core/ui/slidecontroller.py
+++ b/openlp/core/ui/slidecontroller.py
@@ -32,8 +32,9 @@ from PyQt4.phonon import Phonon
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
ItemCapabilities, translate
-from openlp.core.lib.ui import icon_action, UiStrings, shortcut_action
+from openlp.core.lib.ui import UiStrings, shortcut_action
from openlp.core.ui import HideMode, MainDisplay
+from openlp.core.utils.actions import ActionList, CategoryOrder
log = logging.getLogger(__name__)
@@ -140,12 +141,16 @@ class SlideController(QtGui.QWidget):
translate('OpenLP.SlideController', 'Previous Slide'),
u':/slides/slide_previous.png',
translate('OpenLP.SlideController', 'Move to previous'),
- self.onSlideSelectedPrevious)
+ self.onSlideSelectedPrevious,
+ shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp],
+ context=QtCore.Qt.WidgetWithChildrenShortcut)
self.nextItem = self.toolbar.addToolbarButton(
translate('OpenLP.SlideController', 'Next Slide'),
u':/slides/slide_next.png',
translate('OpenLP.SlideController', 'Move to next'),
- self.onSlideSelectedNext)
+ self.onSlideSelectedNext,
+ shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown],
+ context=QtCore.Qt.WidgetWithChildrenShortcut)
self.toolbar.addToolbarSeparator(u'Close Separator')
if self.isLive:
self.hideMenu = QtGui.QToolButton(self.toolbar)
@@ -154,16 +159,20 @@ class SlideController(QtGui.QWidget):
self.toolbar.addToolbarWidget(u'Hide Menu', self.hideMenu)
self.hideMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Hide'), self.toolbar))
- self.blankScreen = icon_action(self.hideMenu, u'Blank Screen',
- u':/slides/slide_blank.png', False)
+ self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen',
+ [QtCore.Qt.Key_Period], self.onBlankDisplay,
+ u':/slides/slide_blank.png', False, UiStrings.LiveToolbar)
self.blankScreen.setText(
translate('OpenLP.SlideController', 'Blank Screen'))
- self.themeScreen = icon_action(self.hideMenu, u'Blank Theme',
- u':/slides/slide_theme.png', False)
+ self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen',
+ [QtGui.QKeySequence(u'T')], self.onThemeDisplay,
+ u':/slides/slide_theme.png', False, UiStrings.LiveToolbar)
self.themeScreen.setText(
translate('OpenLP.SlideController', 'Blank to Theme'))
- self.desktopScreen = icon_action(self.hideMenu, u'Desktop Screen',
- u':/slides/slide_desktop.png', False)
+ self.desktopScreen = shortcut_action(self.hideMenu,
+ u'desktopScreen', [QtGui.QKeySequence(u'D')],
+ self.onHideDisplay, u':/slides/slide_desktop.png', False,
+ UiStrings.LiveToolbar)
self.desktopScreen.setText(
translate('OpenLP.SlideController', 'Show Desktop'))
self.hideMenu.setDefaultAction(self.blankScreen)
@@ -291,12 +300,6 @@ class SlideController(QtGui.QWidget):
QtCore.QObject.connect(self.previewListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
if self.isLive:
- QtCore.QObject.connect(self.blankScreen,
- QtCore.SIGNAL(u'triggered(bool)'), self.onBlankDisplay)
- QtCore.QObject.connect(self.themeScreen,
- QtCore.SIGNAL(u'triggered(bool)'), self.onThemeDisplay)
- QtCore.QObject.connect(self.desktopScreen,
- QtCore.SIGNAL(u'triggered(bool)'), self.onHideDisplay)
QtCore.QObject.connect(self.volumeSlider,
QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume)
QtCore.QObject.connect(Receiver.get_receiver(),
@@ -362,33 +365,37 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'config_screen_changed'), self.screenSizeChanged)
def setPreviewHotkeys(self, parent=None):
- actionList = self.parent.actionList
- self.previousItem.setShortcuts([QtCore.Qt.Key_Up, 0])
- actionList.add_action(self.previousItem, u'Preview')
- self.nextItem.setShortcuts([QtCore.Qt.Key_Down, 0])
- actionList.add_action(self.nextItem, u'Preview')
+ self.previousItem.setObjectName(u'previousItemPreview')
+ self.nextItem.setObjectName(u'nextItemPreview')
+ action_list = ActionList.get_instance()
+ action_list.add_category(
+ UiStrings.PreviewToolbar, CategoryOrder.standardToolbar)
+ action_list.add_action(self.previousItem, UiStrings.PreviewToolbar)
+ action_list.add_action(self.nextItem, UiStrings.PreviewToolbar)
def setLiveHotkeys(self, parent=None):
- actionList = self.parent.actionList
- self.previousItem.setShortcuts([QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp])
- self.previousItem.setShortcutContext(
- QtCore.Qt.WidgetWithChildrenShortcut)
- actionList.add_action(self.previousItem, u'Live')
- self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown])
- self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
- actionList.add_action(self.nextItem, u'Live')
- self.previousService = shortcut_action(parent,
- translate('OpenLP.SlideController', 'Previous Service'),
- [QtCore.Qt.Key_Left, 0], self.servicePrevious)
- actionList.add_action(self.previousService, u'Live')
- self.nextService = shortcut_action(parent,
- translate('OpenLP.SlideController', 'Next Service'),
- [QtCore.Qt.Key_Right, 0], self.serviceNext)
- actionList.add_action(self.nextService, u'Live')
- self.escapeItem = shortcut_action(parent,
- translate('OpenLP.SlideController', 'Escape Item'),
- [QtCore.Qt.Key_Escape, 0], self.liveEscape)
- actionList.add_action(self.escapeItem, u'Live')
+ self.previousItem.setObjectName(u'previousItemLive')
+ self.nextItem.setObjectName(u'nextItemLive')
+ action_list = ActionList.get_instance()
+ action_list.add_category(
+ UiStrings.LiveToolbar, CategoryOrder.standardToolbar)
+ action_list.add_action(self.previousItem, UiStrings.LiveToolbar)
+ action_list.add_action(self.nextItem, UiStrings.LiveToolbar)
+ self.previousService = shortcut_action(parent, u'previousService',
+ [QtCore.Qt.Key_Left], self.servicePrevious, UiStrings.LiveToolbar)
+ self.previousService.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
+ self.previousService.setText(
+ translate('OpenLP.SlideController', 'Previous Service'))
+ self.nextService = shortcut_action(parent, 'nextService',
+ [QtCore.Qt.Key_Right], self.serviceNext, UiStrings.LiveToolbar)
+ self.nextService.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
+ self.nextService.setText(
+ translate('OpenLP.SlideController', 'Next Service'))
+ self.escapeItem = shortcut_action(parent, 'escapeItem',
+ [QtCore.Qt.Key_Escape], self.liveEscape, UiStrings.LiveToolbar)
+ self.escapeItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
+ self.escapeItem.setText(
+ translate('OpenLP.SlideController', 'Escape Item'))
def liveEscape(self):
self.display.setVisible(False)
@@ -741,10 +748,12 @@ class SlideController(QtGui.QWidget):
"""
self.onBlankDisplay(False)
- def onBlankDisplay(self, checked):
+ def onBlankDisplay(self, checked=None):
"""
Handle the blank screen button actions
"""
+ if checked is None:
+ checked = self.blankScreen.isChecked()
log.debug(u'onBlankDisplay %s' % checked)
self.hideMenu.setDefaultAction(self.blankScreen)
self.blankScreen.setChecked(checked)
@@ -762,10 +771,12 @@ class SlideController(QtGui.QWidget):
self.blankPlugin(checked)
self.updatePreview()
- def onThemeDisplay(self, checked):
+ def onThemeDisplay(self, checked=None):
"""
Handle the Theme screen button
"""
+ if checked is None:
+ checked = self.themeScreen.isChecked()
log.debug(u'onThemeDisplay %s' % checked)
self.hideMenu.setDefaultAction(self.themeScreen)
self.blankScreen.setChecked(False)
@@ -783,10 +794,12 @@ class SlideController(QtGui.QWidget):
self.blankPlugin(checked)
self.updatePreview()
- def onHideDisplay(self, checked):
+ def onHideDisplay(self, checked=None):
"""
Handle the Hide screen button
"""
+ if checked is None:
+ checked = self.desktopScreen.isChecked()
log.debug(u'onHideDisplay %s' % checked)
self.hideMenu.setDefaultAction(self.desktopScreen)
self.blankScreen.setChecked(False)
diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py
index 6653e7e1d..3a3b3bb61 100644
--- a/openlp/core/ui/themeform.py
+++ b/openlp/core/ui/themeform.py
@@ -63,26 +63,19 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onGradientComboBoxCurrentIndexChanged)
QtCore.QObject.connect(self.colorButton,
- QtCore.SIGNAL(u'clicked()'),
- self.onColorButtonClicked)
+ QtCore.SIGNAL(u'clicked()'), self.onColorButtonClicked)
QtCore.QObject.connect(self.gradientStartButton,
- QtCore.SIGNAL(u'clicked()'),
- self.onGradientStartButtonClicked)
+ QtCore.SIGNAL(u'clicked()'), self.onGradientStartButtonClicked)
QtCore.QObject.connect(self.gradientEndButton,
- QtCore.SIGNAL(u'clicked()'),
- self.onGradientEndButtonClicked)
+ QtCore.SIGNAL(u'clicked()'), self.onGradientEndButtonClicked)
QtCore.QObject.connect(self.imageBrowseButton,
- QtCore.SIGNAL(u'clicked()'),
- self.onImageBrowseButtonClicked)
+ QtCore.SIGNAL(u'clicked()'), self.onImageBrowseButtonClicked)
QtCore.QObject.connect(self.mainColorButton,
- QtCore.SIGNAL(u'clicked()'),
- self.onMainColorButtonClicked)
+ QtCore.SIGNAL(u'clicked()'), self.onMainColorButtonClicked)
QtCore.QObject.connect(self.outlineColorButton,
- QtCore.SIGNAL(u'clicked()'),
- self.onOutlineColorButtonClicked)
+ QtCore.SIGNAL(u'clicked()'), self.onOutlineColorButtonClicked)
QtCore.QObject.connect(self.shadowColorButton,
- QtCore.SIGNAL(u'clicked()'),
- self.onShadowColorButtonClicked)
+ QtCore.SIGNAL(u'clicked()'), self.onShadowColorButtonClicked)
QtCore.QObject.connect(self.outlineCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onOutlineCheckCheckBoxStateChanged)
@@ -90,8 +83,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
QtCore.SIGNAL(u'stateChanged(int)'),
self.onShadowCheckCheckBoxStateChanged)
QtCore.QObject.connect(self.footerColorButton,
- QtCore.SIGNAL(u'clicked()'),
- self.onFooterColorButtonClicked)
+ QtCore.SIGNAL(u'clicked()'), self.onFooterColorButtonClicked)
QtCore.QObject.connect(self.mainPositionCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onMainPositionCheckBoxStateChanged)
@@ -99,26 +91,23 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
QtCore.SIGNAL(u'stateChanged(int)'),
self.onFooterPositionCheckBoxStateChanged)
QtCore.QObject.connect(self,
- QtCore.SIGNAL(u'currentIdChanged(int)'),
- self.onCurrentIdChanged)
+ QtCore.SIGNAL(u'currentIdChanged(int)'), self.onCurrentIdChanged)
QtCore.QObject.connect(Receiver.get_receiver(),
- QtCore.SIGNAL(u'theme_line_count'),
- self.updateLinesText)
+ QtCore.SIGNAL(u'theme_line_count'), self.updateLinesText)
QtCore.QObject.connect(self.mainSizeSpinBox,
- QtCore.SIGNAL(u'valueChanged(int)'),
- self.calculateLines)
+ QtCore.SIGNAL(u'valueChanged(int)'), self.calculateLines)
QtCore.QObject.connect(self.lineSpacingSpinBox,
- QtCore.SIGNAL(u'valueChanged(int)'),
- self.calculateLines)
+ QtCore.SIGNAL(u'valueChanged(int)'), self.calculateLines)
QtCore.QObject.connect(self.outlineSizeSpinBox,
- QtCore.SIGNAL(u'valueChanged(int)'),
- self.calculateLines)
+ QtCore.SIGNAL(u'valueChanged(int)'), self.calculateLines)
QtCore.QObject.connect(self.shadowSizeSpinBox,
- QtCore.SIGNAL(u'valueChanged(int)'),
- self.calculateLines)
+ QtCore.SIGNAL(u'valueChanged(int)'), self.calculateLines)
QtCore.QObject.connect(self.mainFontComboBox,
- QtCore.SIGNAL(u'activated(int)'),
- self.calculateLines)
+ QtCore.SIGNAL(u'activated(int)'), self.calculateLines)
+ QtCore.QObject.connect(self.footerFontComboBox,
+ QtCore.SIGNAL(u'activated(int)'), self.updateTheme)
+ QtCore.QObject.connect(self.footerSizeSpinBox,
+ QtCore.SIGNAL(u'valueChanged(int)'), self.updateTheme)
def setDefaults(self):
"""
@@ -389,7 +378,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
Handle the display and state of the Footer Area page.
"""
self.footerFontComboBox.setCurrentFont(
- QtGui.QFont(self.theme.font_main_name))
+ QtGui.QFont(self.theme.font_footer_name))
self.footerColorButton.setStyleSheet(u'background-color: %s' %
self.theme.font_footer_color)
self.setField(u'footerSizeSpinBox',
diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py
index d033daeb3..81da6e021 100644
--- a/openlp/core/ui/thememanager.py
+++ b/openlp/core/ui/thememanager.py
@@ -445,6 +445,7 @@ class ThemeManager(QtGui.QWidget):
files = SettingsManager.get_files(self.settingsSection, u'.png')
if firstTime:
self.firstTime()
+ files = SettingsManager.get_files(self.settingsSection, u'.png')
# No themes have been found so create one
if len(files) == 0:
theme = ThemeXML()
diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py
index 1b76d2198..1415c6810 100644
--- a/openlp/core/ui/themestab.py
+++ b/openlp/core/ui/themestab.py
@@ -28,7 +28,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, Receiver, translate
from openlp.core.lib.theme import ThemeLevel
-from openlp.core.lib.ui import UiStrings
+from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box
class ThemesTab(SettingsTab):
"""
@@ -185,12 +185,7 @@ class ThemesTab(SettingsTab):
self.DefaultComboBox.clear()
for theme in theme_list:
self.DefaultComboBox.addItem(theme)
- id = self.DefaultComboBox.findText(
- self.global_theme, QtCore.Qt.MatchExactly)
- if id == -1:
- id = 0 # Not Found
- self.global_theme = u''
- self.DefaultComboBox.setCurrentIndex(id)
+ find_and_set_in_combo_box(self.DefaultComboBox, self.global_theme)
self.parent.renderManager.set_global_theme(
self.global_theme, self.theme_level)
if self.global_theme is not u'':
@@ -206,4 +201,4 @@ class ThemesTab(SettingsTab):
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
- self.DefaultListView.setPixmap(preview)
+ self.DefaultListView.setPixmap(preview)
\ No newline at end of file
diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py
index 3c639297e..1bc7037ae 100644
--- a/openlp/core/utils/__init__.py
+++ b/openlp/core/utils/__init__.py
@@ -495,7 +495,7 @@ def get_uno_instance(resolver):
from languagemanager import LanguageManager
from actions import ActionList
-__all__ = [u'AppLocation', u'check_latest_version', u'add_actions',
- u'get_filesystem_encoding', u'LanguageManager', u'ActionList',
- u'get_web_page', u'file_is_unicode', u'string_is_unicode',
+__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
+ u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
+ u'ActionList', u'get_web_page', u'file_is_unicode', u'string_is_unicode',
u'get_uno_command', u'get_uno_instance', u'delete_file']
diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py
index 41ae41f4b..0c4eee655 100644
--- a/openlp/core/utils/actions.py
+++ b/openlp/core/utils/actions.py
@@ -27,6 +27,8 @@
The :mod:`~openlp.core.utils.actions` module provides action list classes used
by the shortcuts system.
"""
+from PyQt4 import QtCore, QtGui
+
class ActionCategory(object):
"""
The :class:`~openlp.core.utils.ActionCategory` class encapsulates a
@@ -67,6 +69,7 @@ class CategoryActionList(object):
Python 3 "next" method.
"""
if self.index >= len(self.actions):
+ self.index = 0
raise StopIteration
else:
self.index += 1
@@ -94,6 +97,12 @@ class CategoryActionList(object):
self.actions.append((weight, action))
self.actions.sort(key=lambda act: act[0])
+ def remove(self, remove_action):
+ for action in self.actions:
+ if action[1] == remove_action:
+ self.actions.remove(action)
+ return
+
class CategoryList(object):
"""
@@ -126,6 +135,7 @@ class CategoryList(object):
Python 3 "next" method for iterator.
"""
if self.index >= len(self.categories):
+ self.index = 0
raise StopIteration
else:
self.index += 1
@@ -163,6 +173,11 @@ class CategoryList(object):
self.categories.append(category)
self.categories.sort(key=lambda cat: cat.weight)
+ def remove(self, name):
+ for category in self.categories:
+ if category.name == name:
+ self.categories.remove(category)
+
class ActionList(object):
"""
@@ -171,13 +186,101 @@ class ActionList(object):
has a weight by which it is sorted when iterating through the list of
actions or categories.
"""
+ instance = None
+
def __init__(self):
self.categories = CategoryList()
- def add_action(self, action, category=u'Default', weight=None):
+ @staticmethod
+ def get_instance():
+ if ActionList.instance is None:
+ ActionList.instance = ActionList()
+ return ActionList.instance
+
+ def add_action(self, action, category=None, weight=None):
+ """
+ Add an action to the list of actions.
+
+ ``action``
+ The action to add (QAction).
+
+ ``category``
+ The category this action belongs to. The category can be a QString
+ or python unicode string. **Note**, if the category is ``None``, the
+ category and its actions are being hidden in the shortcut dialog.
+ However, if they are added, it is possible to avoid assigning
+ shortcuts twice, which is important.
+
+ ``weight``
+ The weight specifies how important a category is. However, this only
+ has an impact on the order the categories are displayed.
+ """
+ if category is not None:
+ category = unicode(category)
if category not in self.categories:
self.categories.append(category)
+ action.defaultShortcuts = action.shortcuts()
if weight is None:
self.categories[category].actions.append(action)
else:
self.categories[category].actions.add(action, weight)
+ if category is None:
+ # Stop here, as this action is not configurable.
+ return
+ # Load the shortcut from the config.
+ settings = QtCore.QSettings()
+ settings.beginGroup(u'shortcuts')
+ shortcuts = settings.value(action.objectName(),
+ QtCore.QVariant(action.shortcuts())).toStringList()
+ action.setShortcuts(
+ [QtGui.QKeySequence(shortcut) for shortcut in shortcuts])
+ settings.endGroup()
+
+ def remove_action(self, action, category=None):
+ """
+ This removes an action from its category. Empty categories are
+ automatically removed.
+
+ ``action``
+ The QAction object to be removed.
+
+ ``category``
+ The name (unicode string) of the category, which contains the
+ action. Defaults to None.
+ """
+ if category is not None:
+ category = unicode(category)
+ if category not in self.categories:
+ return
+ self.categories[category].actions.remove(action)
+ # Remove empty categories.
+ if len(self.categories[category].actions) == 0:
+ self.categories.remove(category)
+
+ def add_category(self, name, weight):
+ """
+ Add an empty category to the list of categories. This is ony convenient
+ for categories with a given weight.
+
+ ``name``
+ The category's name.
+
+ ``weight``
+ The category's weight (int).
+ """
+ if name in self.categories:
+ # Only change the weight and resort the categories again.
+ for category in self.categories:
+ if category.name == name:
+ category.weight = weight
+ self.categories.categories.sort(key=lambda cat: cat.weight)
+ return
+ self.categories.add(name, weight)
+
+
+class CategoryOrder(object):
+ """
+ An enumeration class for category weights.
+ """
+ standardMenu = -20
+ standardToolbar = -10
diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py
index db0ba3b7e..7d6eac6e2 100644
--- a/openlp/plugins/alerts/alertsplugin.py
+++ b/openlp/plugins/alerts/alertsplugin.py
@@ -30,6 +30,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.db import Manager
+from openlp.core.lib.ui import icon_action, UiStrings
+from openlp.core.utils.actions import ActionList
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
from openlp.plugins.alerts.lib.db import init_schema
from openlp.plugins.alerts.forms import AlertForm
@@ -58,9 +60,8 @@ class AlertsPlugin(Plugin):
use it as their parent.
"""
log.info(u'add tools menu')
- self.toolsAlertItem = QtGui.QAction(tools_menu)
- self.toolsAlertItem.setIcon(build_icon(u':/plugins/plugin_alerts.png'))
- self.toolsAlertItem.setObjectName(u'toolsAlertItem')
+ self.toolsAlertItem = icon_action(tools_menu, u'toolsAlertItem',
+ u':/plugins/plugin_alerts.png')
self.toolsAlertItem.setText(translate('AlertsPlugin', '&Alert'))
self.toolsAlertItem.setStatusTip(
translate('AlertsPlugin', 'Show an alert message.'))
@@ -74,6 +75,8 @@ class AlertsPlugin(Plugin):
log.info(u'Alerts Initialising')
Plugin.initialise(self)
self.toolsAlertItem.setVisible(True)
+ action_list = ActionList.get_instance()
+ action_list.add_action(self.toolsAlertItem, UiStrings.Tools)
self.liveController.alertTab = self.settings_tab
def finalise(self):
@@ -84,6 +87,8 @@ class AlertsPlugin(Plugin):
self.manager.finalise()
Plugin.finalise(self)
self.toolsAlertItem.setVisible(False)
+ action_list = ActionList.get_instance()
+ action_list.remove_action(self.toolsAlertItem, u'Tools')
def toggleAlertsState(self):
self.alertsActive = not self.alertsActive
diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py
index 4f677f211..aea732688 100644
--- a/openlp/plugins/bibles/bibleplugin.py
+++ b/openlp/plugins/bibles/bibleplugin.py
@@ -29,6 +29,8 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate
+from openlp.core.lib.ui import base_action, UiStrings
+from openlp.core.utils.actions import ActionList
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
log = logging.getLogger(__name__)
@@ -50,6 +52,10 @@ class BiblePlugin(Plugin):
self.manager = BibleManager(self)
Plugin.initialise(self)
self.importBibleItem.setVisible(True)
+ action_list = ActionList.get_instance()
+ action_list.add_action(self.importBibleItem, UiStrings.Import)
+ # Do not add the action to the list yet.
+ #action_list.add_action(self.exportBibleItem, UiStrings.Export)
# Set to invisible until we can export bibles
self.exportBibleItem.setVisible(False)
@@ -60,25 +66,25 @@ class BiblePlugin(Plugin):
log.info(u'Plugin Finalise')
self.manager.finalise()
Plugin.finalise(self)
+ action_list = ActionList.get_instance()
+ action_list.remove_action(self.importBibleItem, UiStrings.Import)
self.importBibleItem.setVisible(False)
+ #action_list.remove_action(self.exportBibleItem, UiStrings.Export)
self.exportBibleItem.setVisible(False)
def addImportMenuItem(self, import_menu):
- self.importBibleItem = QtGui.QAction(import_menu)
- self.importBibleItem.setObjectName(u'importBibleItem')
+ self.importBibleItem = base_action(import_menu, u'importBibleItem')
+ self.importBibleItem.setText(translate('BiblesPlugin', '&Bible'))
import_menu.addAction(self.importBibleItem)
- self.importBibleItem.setText(
- translate('BiblesPlugin', '&Bible'))
# signals and slots
QtCore.QObject.connect(self.importBibleItem,
QtCore.SIGNAL(u'triggered()'), self.onBibleImportClick)
self.importBibleItem.setVisible(False)
def addExportMenuItem(self, export_menu):
- self.exportBibleItem = QtGui.QAction(export_menu)
- self.exportBibleItem.setObjectName(u'exportBibleItem')
- export_menu.addAction(self.exportBibleItem)
+ self.exportBibleItem = base_action(export_menu, u'exportBibleItem')
self.exportBibleItem.setText(translate('BiblesPlugin', '&Bible'))
+ export_menu.addAction(self.exportBibleItem)
self.exportBibleItem.setVisible(False)
def onBibleImportClick(self):
diff --git a/openlp/plugins/bibles/forms/bibleimportform.py b/openlp/plugins/bibles/forms/bibleimportform.py
index 117ffaf4c..35cd17c4b 100644
--- a/openlp/plugins/bibles/forms/bibleimportform.py
+++ b/openlp/plugins/bibles/forms/bibleimportform.py
@@ -85,8 +85,18 @@ class BibleImportForm(OpenLPWizard):
"""
OpenLPWizard.setupUi(self, image)
QtCore.QObject.connect(self.formatComboBox,
- QtCore.SIGNAL(u'currentIndexChanged(int)'), self.selectStack,
- QtCore.SLOT(u'setCurrentIndex(int)'))
+ QtCore.SIGNAL(u'currentIndexChanged(int)'),
+ self.onCurrentIndexChanged)
+
+ def onCurrentIndexChanged(self, index):
+ """
+ Called when the format combo box's index changed. We have to check if
+ the import is available and accordingly to disable or enable the next
+ button.
+ """
+ self.selectStack.setCurrentIndex(index)
+ next_button = self.button(QtGui.QWizard.NextButton)
+ next_button.setEnabled(BibleFormat.get_availability(index))
def customInit(self):
"""
diff --git a/openlp/plugins/bibles/lib/biblestab.py b/openlp/plugins/bibles/lib/biblestab.py
index 7a631ad09..914377e35 100644
--- a/openlp/plugins/bibles/lib/biblestab.py
+++ b/openlp/plugins/bibles/lib/biblestab.py
@@ -30,6 +30,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsTab, translate
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle
+from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box
log = logging.getLogger(__name__)
@@ -48,108 +49,107 @@ class BiblesTab(SettingsTab):
def setupUi(self):
self.setObjectName(u'BiblesTab')
SettingsTab.setupUi(self)
- self.VerseDisplayGroupBox = QtGui.QGroupBox(self.leftColumn)
- self.VerseDisplayGroupBox.setObjectName(u'VerseDisplayGroupBox')
- self.VerseDisplayLayout = QtGui.QFormLayout(self.VerseDisplayGroupBox)
- self.VerseDisplayLayout.setObjectName(u'VerseDisplayLayout')
- self.NewChaptersCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox)
- self.NewChaptersCheckBox.setObjectName(u'NewChaptersCheckBox')
- self.VerseDisplayLayout.addRow(self.NewChaptersCheckBox)
- self.DisplayStyleLabel = QtGui.QLabel(self.VerseDisplayGroupBox)
- self.DisplayStyleLabel.setObjectName(u'DisplayStyleLabel')
- self.DisplayStyleComboBox = QtGui.QComboBox(self.VerseDisplayGroupBox)
- self.DisplayStyleComboBox.addItems([u'', u'', u'', u''])
- self.DisplayStyleComboBox.setObjectName(u'DisplayStyleComboBox')
- self.VerseDisplayLayout.addRow(self.DisplayStyleLabel,
- self.DisplayStyleComboBox)
- self.LayoutStyleLabel = QtGui.QLabel(self.VerseDisplayGroupBox)
- self.LayoutStyleLabel.setObjectName(u'LayoutStyleLabel')
- self.LayoutStyleComboBox = QtGui.QComboBox(self.VerseDisplayGroupBox)
- self.LayoutStyleComboBox.setObjectName(u'LayoutStyleComboBox')
- self.LayoutStyleComboBox.addItems([u'', u'', u''])
- self.VerseDisplayLayout.addRow(self.LayoutStyleLabel,
- self.LayoutStyleComboBox)
- self.BibleSecondCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox)
- self.BibleSecondCheckBox.setObjectName(u'BibleSecondCheckBox')
- self.VerseDisplayLayout.addRow(self.BibleSecondCheckBox)
- self.BibleThemeLabel = QtGui.QLabel(self.VerseDisplayGroupBox)
- self.BibleThemeLabel.setObjectName(u'BibleThemeLabel')
- self.BibleThemeComboBox = QtGui.QComboBox(self.VerseDisplayGroupBox)
- self.BibleThemeComboBox.setSizeAdjustPolicy(
+ self.verseDisplayGroupBox = QtGui.QGroupBox(self.leftColumn)
+ self.verseDisplayGroupBox.setObjectName(u'verseDisplayGroupBox')
+ self.verseDisplayLayout = QtGui.QFormLayout(self.verseDisplayGroupBox)
+ self.verseDisplayLayout.setObjectName(u'verseDisplayLayout')
+ self.newChaptersCheckBox = QtGui.QCheckBox(self.verseDisplayGroupBox)
+ self.newChaptersCheckBox.setObjectName(u'newChaptersCheckBox')
+ self.verseDisplayLayout.addRow(self.newChaptersCheckBox)
+ self.displayStyleLabel = QtGui.QLabel(self.verseDisplayGroupBox)
+ self.displayStyleLabel.setObjectName(u'displayStyleLabel')
+ self.displayStyleComboBox = QtGui.QComboBox(self.verseDisplayGroupBox)
+ self.displayStyleComboBox.addItems([u'', u'', u'', u''])
+ self.displayStyleComboBox.setObjectName(u'displayStyleComboBox')
+ self.verseDisplayLayout.addRow(self.displayStyleLabel,
+ self.displayStyleComboBox)
+ self.layoutStyleLabel = QtGui.QLabel(self.verseDisplayGroupBox)
+ self.layoutStyleLabel.setObjectName(u'layoutStyleLabel')
+ self.layoutStyleComboBox = QtGui.QComboBox(self.verseDisplayGroupBox)
+ self.layoutStyleComboBox.setObjectName(u'layoutStyleComboBox')
+ self.layoutStyleComboBox.addItems([u'', u'', u''])
+ self.verseDisplayLayout.addRow(self.layoutStyleLabel,
+ self.layoutStyleComboBox)
+ self.bibleSecondCheckBox = QtGui.QCheckBox(self.verseDisplayGroupBox)
+ self.bibleSecondCheckBox.setObjectName(u'bibleSecondCheckBox')
+ self.verseDisplayLayout.addRow(self.bibleSecondCheckBox)
+ self.bibleThemeLabel = QtGui.QLabel(self.verseDisplayGroupBox)
+ self.bibleThemeLabel.setObjectName(u'BibleThemeLabel')
+ self.bibleThemeComboBox = QtGui.QComboBox(self.verseDisplayGroupBox)
+ self.bibleThemeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
- self.BibleThemeComboBox.setSizePolicy(
+ self.bibleThemeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
- self.BibleThemeComboBox.addItem(u'')
- self.BibleThemeComboBox.setObjectName(u'BibleThemeComboBox')
- self.VerseDisplayLayout.addRow(self.BibleThemeLabel,
- self.BibleThemeComboBox)
- self.ChangeNoteLabel = QtGui.QLabel(self.VerseDisplayGroupBox)
- self.ChangeNoteLabel.setWordWrap(True)
- self.ChangeNoteLabel.setObjectName(u'ChangeNoteLabel')
- self.VerseDisplayLayout.addRow(self.ChangeNoteLabel)
- self.leftLayout.addWidget(self.VerseDisplayGroupBox)
+ self.bibleThemeComboBox.addItem(u'')
+ self.bibleThemeComboBox.setObjectName(u'BibleThemeComboBox')
+ self.verseDisplayLayout.addRow(self.bibleThemeLabel,
+ self.bibleThemeComboBox)
+ self.changeNoteLabel = QtGui.QLabel(self.verseDisplayGroupBox)
+ self.changeNoteLabel.setWordWrap(True)
+ self.changeNoteLabel.setObjectName(u'changeNoteLabel')
+ self.verseDisplayLayout.addRow(self.changeNoteLabel)
+ self.leftLayout.addWidget(self.verseDisplayGroupBox)
self.leftLayout.addStretch()
self.rightColumn.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
self.rightLayout.addStretch()
# Signals and slots
QtCore.QObject.connect(
- self.NewChaptersCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
+ self.newChaptersCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
self.onNewChaptersCheckBoxChanged)
QtCore.QObject.connect(
- self.DisplayStyleComboBox, QtCore.SIGNAL(u'activated(int)'),
+ self.displayStyleComboBox, QtCore.SIGNAL(u'activated(int)'),
self.onDisplayStyleComboBoxChanged)
QtCore.QObject.connect(
- self.BibleThemeComboBox, QtCore.SIGNAL(u'activated(int)'),
+ self.bibleThemeComboBox, QtCore.SIGNAL(u'activated(int)'),
self.onBibleThemeComboBoxChanged)
QtCore.QObject.connect(
- self.LayoutStyleComboBox, QtCore.SIGNAL(u'activated(int)'),
+ self.layoutStyleComboBox, QtCore.SIGNAL(u'activated(int)'),
self.onLayoutStyleComboBoxChanged)
QtCore.QObject.connect(
- self.BibleSecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
+ self.bibleSecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
self.onBibleSecondCheckBox)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
def retranslateUi(self):
- self.VerseDisplayGroupBox.setTitle(
+ self.verseDisplayGroupBox.setTitle(
translate('BiblesPlugin.BiblesTab', 'Verse Display'))
- self.NewChaptersCheckBox.setText(
+ self.newChaptersCheckBox.setText(
translate('BiblesPlugin.BiblesTab',
'Only show new chapter numbers'))
- self.LayoutStyleLabel.setText(
+ self.layoutStyleLabel.setText(
translate('BiblesPlugin.BiblesTab', 'Layout style:'))
- self.DisplayStyleLabel.setText(
- translate('BiblesPlugin.BiblesTab', 'Display style:'))
- self.BibleThemeLabel.setText(
+ self.displayStyleLabel.setText(UiStrings.DisplayStyle)
+ self.bibleThemeLabel.setText(
translate('BiblesPlugin.BiblesTab', 'Bible theme:'))
- self.LayoutStyleComboBox.setItemText(LayoutStyle.VersePerSlide,
- translate('BiblesPlugin.BiblesTab', 'Verse Per Slide'))
- self.LayoutStyleComboBox.setItemText(LayoutStyle.VersePerLine,
- translate('BiblesPlugin.BiblesTab', 'Verse Per Line'))
- self.LayoutStyleComboBox.setItemText(LayoutStyle.Continuous,
- translate('BiblesPlugin.BiblesTab', 'Continuous'))
- self.DisplayStyleComboBox.setItemText(DisplayStyle.NoBrackets,
+ self.layoutStyleComboBox.setItemText(LayoutStyle.VersePerSlide,
+ UiStrings.VersePerSlide)
+ self.layoutStyleComboBox.setItemText(LayoutStyle.VersePerLine,
+ UiStrings.VersePerLine)
+ self.layoutStyleComboBox.setItemText(LayoutStyle.Continuous,
+ UiStrings.Continuous)
+ self.displayStyleComboBox.setItemText(DisplayStyle.NoBrackets,
translate('BiblesPlugin.BiblesTab', 'No Brackets'))
- self.DisplayStyleComboBox.setItemText(DisplayStyle.Round,
+ self.displayStyleComboBox.setItemText(DisplayStyle.Round,
translate('BiblesPlugin.BiblesTab', '( And )'))
- self.DisplayStyleComboBox.setItemText(DisplayStyle.Curly,
+ self.displayStyleComboBox.setItemText(DisplayStyle.Curly,
translate('BiblesPlugin.BiblesTab', '{ And }'))
- self.DisplayStyleComboBox.setItemText(DisplayStyle.Square,
+ self.displayStyleComboBox.setItemText(DisplayStyle.Square,
translate('BiblesPlugin.BiblesTab', '[ And ]'))
- self.ChangeNoteLabel.setText(translate('BiblesPlugin.BiblesTab',
+ self.changeNoteLabel.setText(translate('BiblesPlugin.BiblesTab',
'Note:\nChanges do not affect verses already in the service.'))
- self.BibleSecondCheckBox.setText(
+ self.bibleSecondCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'Display second Bible verses'))
def onBibleThemeComboBoxChanged(self):
- self.bible_theme = self.BibleThemeComboBox.currentText()
+ self.bible_theme = self.bibleThemeComboBox.currentText()
def onDisplayStyleComboBoxChanged(self):
- self.display_style = self.DisplayStyleComboBox.currentIndex()
+ self.display_style = self.displayStyleComboBox.currentIndex()
def onLayoutStyleComboBoxChanged(self):
- self.layout_style = self.LayoutStyleComboBox.currentIndex()
+ self.layout_style = self.layoutStyleComboBox.currentIndex()
def onNewChaptersCheckBoxChanged(self, check_state):
self.show_new_chapters = False
@@ -176,10 +176,10 @@ class BiblesTab(SettingsTab):
settings.value(u'bible theme', QtCore.QVariant(u'')).toString())
self.second_bibles = settings.value(
u'second bibles', QtCore.QVariant(True)).toBool()
- self.NewChaptersCheckBox.setChecked(self.show_new_chapters)
- self.DisplayStyleComboBox.setCurrentIndex(self.display_style)
- self.LayoutStyleComboBox.setCurrentIndex(self.layout_style)
- self.BibleSecondCheckBox.setChecked(self.second_bibles)
+ self.newChaptersCheckBox.setChecked(self.show_new_chapters)
+ self.displayStyleComboBox.setCurrentIndex(self.display_style)
+ self.layoutStyleComboBox.setCurrentIndex(self.layout_style)
+ self.bibleSecondCheckBox.setChecked(self.second_bibles)
settings.endGroup()
def save(self):
@@ -204,14 +204,8 @@ class BiblesTab(SettingsTab):
[u'Bible Theme', u'Song Theme']
"""
- self.BibleThemeComboBox.clear()
- self.BibleThemeComboBox.addItem(u'')
+ self.bibleThemeComboBox.clear()
+ self.bibleThemeComboBox.addItem(u'')
for theme in theme_list:
- self.BibleThemeComboBox.addItem(theme)
- index = self.BibleThemeComboBox.findText(
- unicode(self.bible_theme), QtCore.Qt.MatchExactly)
- if index == -1:
- # Not Found.
- index = 0
- self.bible_theme = u''
- self.BibleThemeComboBox.setCurrentIndex(index)
+ self.bibleThemeComboBox.addItem(theme)
+ find_and_set_in_combo_box(self.bibleThemeComboBox, self.bible_theme)
diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py
index a9694fd0c..118bdfc66 100644
--- a/openlp/plugins/bibles/lib/mediaitem.py
+++ b/openlp/plugins/bibles/lib/mediaitem.py
@@ -32,7 +32,7 @@ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
translate
from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import UiStrings, add_widget_completer, \
- media_item_combo_box, critical_error_message_box
+ media_item_combo_box, critical_error_message_box, find_and_set_in_combo_box
from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
VerseReferenceList, get_reference_match
@@ -106,6 +106,12 @@ class BibleMediaItem(MediaManagerItem):
translate('BiblesPlugin.MediaItem', 'Text Search'))
])
self.quickLayout.addRow(self.quickSearchLabel, self.quickSearchEdit)
+ self.quickLayoutLabel = QtGui.QLabel(self.quickTab)
+ self.quickLayoutLabel.setObjectName(u'quickClearLabel')
+ self.quickLayoutComboBox = media_item_combo_box(self.quickTab,
+ u'quickLayoutComboBox')
+ self.quickLayoutComboBox.addItems([u'', u'', u''])
+ self.quickLayout.addRow(self.quickLayoutLabel, self.quickLayoutComboBox)
self.quickClearLabel = QtGui.QLabel(self.quickTab)
self.quickClearLabel.setObjectName(u'quickClearLabel')
self.quickClearComboBox = media_item_combo_box(self.quickTab,
@@ -210,6 +216,9 @@ class BibleMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'searchTypeChanged(int)'), self.updateAutoCompleter)
QtCore.QObject.connect(self.quickVersionComboBox,
QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter)
+ QtCore.QObject.connect(
+ self.quickLayoutComboBox, QtCore.SIGNAL(u'activated(int)'),
+ self.onlayoutStyleComboBoxChanged)
# Buttons
QtCore.QObject.connect(self.advancedSearchButton,
QtCore.SIGNAL(u'pressed()'), self.onAdvancedSearchButton)
@@ -234,6 +243,7 @@ class BibleMediaItem(MediaManagerItem):
self.advancedSecondComboBox.setVisible(False)
self.quickSecondLabel.setVisible(False)
self.quickSecondComboBox.setVisible(False)
+ self.quickLayoutComboBox.setCurrentIndex(self.settings.layout_style)
def retranslateUi(self):
log.debug(u'retranslateUi')
@@ -269,11 +279,22 @@ class BibleMediaItem(MediaManagerItem):
translate('BiblesPlugin.MediaItem', 'Clear'))
self.advancedClearComboBox.addItem(
translate('BiblesPlugin.MediaItem', 'Keep'))
+ self.quickLayoutLabel.setText(UiStrings.DisplayStyle)
+ self.quickLayoutComboBox.setItemText(LayoutStyle.VersePerSlide,
+ UiStrings.VersePerSlide)
+ self.quickLayoutComboBox.setItemText(LayoutStyle.VersePerLine,
+ UiStrings.VersePerLine)
+ self.quickLayoutComboBox.setItemText(LayoutStyle.Continuous,
+ UiStrings.Continuous)
def initialise(self):
log.debug(u'bible manager initialise')
self.parent.manager.media = self
self.loadBibles()
+ bible = QtCore.QSettings().value(
+ self.settingsSection + u'/quick bible', QtCore.QVariant(
+ self.quickVersionComboBox.currentText())).toString()
+ find_and_set_in_combo_box(self.quickVersionComboBox, bible)
self.updateAutoCompleter()
self.configUpdated()
log.debug(u'bible manager initialise complete')
@@ -298,23 +319,28 @@ class BibleMediaItem(MediaManagerItem):
bibles = self.parent.manager.get_bibles().keys()
bibles.sort()
# Load the bibles into the combo boxes.
- first = True
for bible in bibles:
if bible:
self.quickVersionComboBox.addItem(bible)
self.quickSecondComboBox.addItem(bible)
self.advancedVersionComboBox.addItem(bible)
self.advancedSecondComboBox.addItem(bible)
- if first:
- first = False
- self.initialiseBible(bible)
+ # set the default value
+ bible = QtCore.QSettings().value(
+ self.settingsSection + u'/advanced bible',
+ QtCore.QVariant(u'')).toString()
+ if bible in bibles:
+ find_and_set_in_combo_box(self.advancedVersionComboBox, bible)
+ self.initialiseAdvancedBible(unicode(bible))
+ elif len(bibles):
+ self.initialiseAdvancedBible(bibles[0])
def reloadBibles(self):
log.debug(u'Reloading Bibles')
self.parent.manager.reload_bibles()
self.loadBibles()
- def initialiseBible(self, bible):
+ def initialiseAdvancedBible(self, bible):
"""
This initialises the given bible, which means that its book names and
their chapter numbers is added to the combo boxes on the
@@ -324,7 +350,7 @@ class BibleMediaItem(MediaManagerItem):
``bible``
The bible to initialise (unicode).
"""
- log.debug(u'initialiseBible %s', bible)
+ log.debug(u'initialiseAdvancedBible %s', bible)
book_data = self.parent.manager.get_books(bible)
self.advancedBookComboBox.clear()
first = True
@@ -360,6 +386,8 @@ class BibleMediaItem(MediaManagerItem):
completion depends on the bible. It is only updated when we are doing a
reference search, otherwise the auto completion list is removed.
"""
+ QtCore.QSettings().setValue(self.settingsSection + u'/quick bible',
+ QtCore.QVariant(self.quickVersionComboBox.currentText()))
books = []
# We have to do a 'Reference Search'.
if self.quickSearchEdit.currentSearchType() == BibleSearch.Reference:
@@ -367,12 +395,14 @@ class BibleMediaItem(MediaManagerItem):
bible = unicode(self.quickVersionComboBox.currentText())
if bible:
book_data = bibles[bible].get_books()
- books = [book.name for book in book_data]
+ books = [book.name + u' ' for book in book_data]
books.sort()
add_widget_completer(books, self.quickSearchEdit)
def onAdvancedVersionComboBox(self):
- self.initialiseBible(
+ QtCore.QSettings().setValue(self.settingsSection + u'/advanced bible',
+ QtCore.QVariant(self.advancedVersionComboBox.currentText()))
+ self.initialiseAdvancedBible(
unicode(self.advancedVersionComboBox.currentText()))
def onAdvancedBookComboBox(self):
@@ -804,3 +834,11 @@ class BibleMediaItem(MediaManagerItem):
if self.settings.display_style == DisplayStyle.Square:
return u'{su}[%s]{/su}' % verse_text
return u'{su}%s{/su}' % verse_text
+
+ def onlayoutStyleComboBoxChanged(self):
+ self.settings.layout_style = self.quickLayoutComboBox.currentIndex()
+ self.settings.layoutStyleComboBox.setCurrentIndex(
+ self.settings.layout_style)
+ QtCore.QSettings().setValue(
+ self.settingsSection + u'/verse layout style',
+ QtCore.QVariant(self.settings.layout_style))
diff --git a/openlp/plugins/bibles/lib/versereferencelist.py b/openlp/plugins/bibles/lib/versereferencelist.py
index bc28f2570..bab6d7e11 100644
--- a/openlp/plugins/bibles/lib/versereferencelist.py
+++ b/openlp/plugins/bibles/lib/versereferencelist.py
@@ -96,4 +96,7 @@ class VerseReferenceList(object):
version[u'copyright'])
if version[u'permission'].strip():
result = result + u', ' + version[u'permission']
+ result = result.rstrip()
+ if result.endswith(u','):
+ return result[:len(result)-1]
return result
diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py
index f81bd4c7d..9312b5ddd 100644
--- a/openlp/plugins/custom/forms/editcustomform.py
+++ b/openlp/plugins/custom/forms/editcustomform.py
@@ -29,7 +29,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, translate
-from openlp.core.lib.ui import critical_error_message_box
+from openlp.core.lib.ui import critical_error_message_box, find_and_set_in_combo_box
from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide
from editcustomdialog import Ui_CustomEditDialog
@@ -98,11 +98,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
for slide in slideList:
self.slideListView.addItem(slide[1])
theme = self.customSlide.theme_name
- id = self.themeComboBox.findText(theme, QtCore.Qt.MatchExactly)
- # No theme match
- if id == -1:
- id = 0
- self.themeComboBox.setCurrentIndex(id)
+ find_and_set_in_combo_box(self.themeComboBox, theme)
# If not preview hide the preview button.
self.previewButton.setVisible(False)
if preview:
@@ -265,4 +261,4 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
message=translate('CustomPlugin.EditCustomForm',
'You need to add at least one slide'))
return False
- return True
+ return True
\ No newline at end of file
diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py
index 2f21e57cd..85294d92b 100644
--- a/openlp/plugins/songs/forms/editsongform.py
+++ b/openlp/plugins/songs/forms/editsongform.py
@@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, translate
from openlp.core.lib.ui import UiStrings, add_widget_completer, \
- critical_error_message_box
+ critical_error_message_box, find_and_set_in_combo_box
from openlp.plugins.songs.forms import EditVerseForm
from openlp.plugins.songs.lib import SongXML, VerseType, clean_song
from openlp.plugins.songs.lib.db import Book, Song, Author, Topic
@@ -208,20 +208,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.alternativeEdit.setText(u'')
if self.song.song_book_id != 0:
book_name = self.manager.get_object(Book, self.song.song_book_id)
- id = self.songBookComboBox.findText(
- unicode(book_name.name), QtCore.Qt.MatchExactly)
- if id == -1:
- # Not Found
- id = 0
- self.songBookComboBox.setCurrentIndex(id)
+ find_and_set_in_combo_box(self.songBookComboBox, unicode(book_name.name))
if self.song.theme_name:
- id = self.themeComboBox.findText(
- unicode(self.song.theme_name), QtCore.Qt.MatchExactly)
- if id == -1:
- # Not Found
- id = 0
- self.song.theme_name = None
- self.themeComboBox.setCurrentIndex(id)
+ find_and_set_in_combo_box(self.themeComboBox, unicode(self.song.theme_name))
if self.song.copyright:
self.copyrightEdit.setText(self.song.copyright)
else:
@@ -790,4 +779,4 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.song.verse_order)
except:
log.exception(u'Problem processing song Lyrics \n%s',
- sxml.dump_xml())
+ sxml.dump_xml())
\ No newline at end of file
diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py
index 6d20c8f41..468d2f341 100644
--- a/openlp/plugins/songs/forms/songimportform.py
+++ b/openlp/plugins/songs/forms/songimportform.py
@@ -66,7 +66,17 @@ class SongImportForm(OpenLPWizard):
self.formatStack.setCurrentIndex(0)
QtCore.QObject.connect(self.formatComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
- self.formatStack.setCurrentIndex)
+ self.onCurrentIndexChanged)
+
+ def onCurrentIndexChanged(self, index):
+ """
+ Called when the format combo box's index changed. We have to check if
+ the import is available and accordingly to disable or enable the next
+ button.
+ """
+ self.formatStack.setCurrentIndex(index)
+ next_button = self.button(QtGui.QWizard.NextButton)
+ next_button.setEnabled(SongFormat.get_availability(index))
def customInit(self):
"""
diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py
index f4803d653..e2882ed29 100644
--- a/openlp/plugins/songs/lib/mediaitem.py
+++ b/openlp/plugins/songs/lib/mediaitem.py
@@ -283,19 +283,20 @@ class SongMediaItem(MediaManagerItem):
self.remoteTriggered = None
self.remoteSong = -1
- def onRemoteEdit(self, songid):
+ def onRemoteEdit(self, message):
"""
Called by ServiceManager or SlideController by event passing
the Song Id in the payload along with an indicator to say which
type of display is required.
"""
- log.debug(u'onRemoteEdit %s' % songid)
- fields = songid.split(u':')
- valid = self.parent.manager.get_object(Song, fields[1])
+ log.debug(u'onRemoteEdit %s' % message)
+ remote_type, song_id = message.split(u':')
+ song_id = int(song_id)
+ valid = self.parent.manager.get_object(Song, song_id)
if valid:
- self.remoteSong = fields[1]
- self.remoteTriggered = fields[0]
- self.edit_song_form.loadSong(fields[1], (fields[0] == u'P'))
+ self.remoteSong = song_id
+ self.remoteTriggered = remote_type
+ self.edit_song_form.loadSong(song_id, (remote_type == u'P'))
self.edit_song_form.exec_()
def onEditClick(self):
diff --git a/openlp/plugins/songs/lib/oooimport.py b/openlp/plugins/songs/lib/oooimport.py
index c9c05907e..2ab66820c 100644
--- a/openlp/plugins/songs/lib/oooimport.py
+++ b/openlp/plugins/songs/lib/oooimport.py
@@ -39,12 +39,8 @@ if os.name == u'nt':
PAGE_AFTER = 5
PAGE_BOTH = 6
else:
- try:
- import uno
- from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, \
- PAGE_BOTH
- except ImportError:
- pass
+ import uno
+ from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
class OooImport(SongImport):
"""
diff --git a/openlp/plugins/songs/lib/openlyricsexport.py b/openlp/plugins/songs/lib/openlyricsexport.py
index d3367bfa9..59b720d3e 100644
--- a/openlp/plugins/songs/lib/openlyricsexport.py
+++ b/openlp/plugins/songs/lib/openlyricsexport.py
@@ -73,6 +73,8 @@ class OpenLyricsExport(object):
u', '.join([author.display_name for author in song.authors]))
filename = re.sub(
r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_')
- tree.write(os.path.join(self.save_path, filename),
+ # Pass a file object, because lxml does not cope with some special
+ # characters in the path (see lp:757673 and lp:744337).
+ tree.write(open(os.path.join(self.save_path, filename), u'w'),
encoding=u'utf-8', xml_declaration=True, pretty_print=True)
return True
diff --git a/openlp/plugins/songs/lib/openlyricsimport.py b/openlp/plugins/songs/lib/openlyricsimport.py
index 208ef3e52..c29abc0b5 100644
--- a/openlp/plugins/songs/lib/openlyricsimport.py
+++ b/openlp/plugins/songs/lib/openlyricsimport.py
@@ -63,7 +63,9 @@ class OpenLyricsImport(SongImport):
self.import_wizard.incrementProgressBar(
WizardStrings.ImportingType % os.path.basename(file_path))
try:
- parsed_file = etree.parse(file_path, parser)
+ # Pass a file object, because lxml does not cope with some
+ # special characters in the path (see lp:757673 and lp:744337).
+ parsed_file = etree.parse(open(file_path, u'r'), parser)
xml = unicode(etree.tostring(parsed_file))
if self.openLyrics.xml_to_song(xml) is None:
log.debug(u'File could not be imported: %s' % file_path)
diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py
index 1260a832b..af50f3f94 100644
--- a/openlp/plugins/songs/songsplugin.py
+++ b/openlp/plugins/songs/songsplugin.py
@@ -33,7 +33,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate, \
Receiver
from openlp.core.lib.db import Manager
-from openlp.core.lib.ui import UiStrings
+from openlp.core.lib.ui import UiStrings, base_action, icon_action
+from openlp.core.utils.actions import ActionList
from openlp.plugins.songs.lib import clean_song, SongMediaItem, SongsTab
from openlp.plugins.songs.lib.db import init_schema, Song
from openlp.plugins.songs.lib.importer import SongFormat
@@ -65,6 +66,10 @@ class SongsPlugin(Plugin):
log.info(u'Songs Initialising')
Plugin.initialise(self)
self.toolsReindexItem.setVisible(True)
+ action_list = ActionList.get_instance()
+ action_list.add_action(self.SongImportItem, UiStrings.Import)
+ action_list.add_action(self.SongExportItem, UiStrings.Export)
+ action_list.add_action(self.toolsReindexItem, UiStrings.Tools)
self.mediaItem.displayResultsSong(
self.manager.get_all_objects(Song, order_by_ref=Song.search_title))
@@ -78,10 +83,8 @@ class SongsPlugin(Plugin):
use it as their parent.
"""
# Main song import menu item - will eventually be the only one
- self.SongImportItem = QtGui.QAction(import_menu)
- self.SongImportItem.setObjectName(u'SongImportItem')
- self.SongImportItem.setText(translate(
- 'SongsPlugin', '&Song'))
+ self.SongImportItem = base_action(import_menu, u'SongImportItem')
+ self.SongImportItem.setText(translate('SongsPlugin', '&Song'))
self.SongImportItem.setToolTip(translate('SongsPlugin',
'Import songs using the import wizard.'))
import_menu.addAction(self.SongImportItem)
@@ -99,10 +102,8 @@ class SongsPlugin(Plugin):
use it as their parent.
"""
# Main song import menu item - will eventually be the only one
- self.SongExportItem = QtGui.QAction(export_menu)
- self.SongExportItem.setObjectName(u'SongExportItem')
- self.SongExportItem.setText(translate(
- 'SongsPlugin', '&Song'))
+ self.SongExportItem = base_action(export_menu, u'SongExportItem')
+ self.SongExportItem.setText(translate('SongsPlugin', '&Song'))
self.SongExportItem.setToolTip(translate('SongsPlugin',
'Exports songs using the export wizard.'))
export_menu.addAction(self.SongExportItem)
@@ -120,9 +121,8 @@ class SongsPlugin(Plugin):
use it as their parent.
"""
log.info(u'add tools menu')
- self.toolsReindexItem = QtGui.QAction(tools_menu)
- self.toolsReindexItem.setIcon(build_icon(u':/plugins/plugin_songs.png'))
- self.toolsReindexItem.setObjectName(u'toolsReindexItem')
+ self.toolsReindexItem = icon_action(tools_menu, u'toolsReindexItem',
+ u':/plugins/plugin_songs.png')
self.toolsReindexItem.setText(
translate('SongsPlugin', '&Re-index Songs'))
self.toolsReindexItem.setStatusTip(
@@ -259,4 +259,8 @@ class SongsPlugin(Plugin):
log.info(u'Songs Finalising')
self.manager.finalise()
self.toolsReindexItem.setVisible(False)
+ action_list = ActionList.get_instance()
+ action_list.remove_action(self.SongImportItem, UiStrings.Import)
+ action_list.remove_action(self.SongExportItem, UiStrings.Export)
+ action_list.remove_action(self.toolsReindexItem, UiStrings.Tools)
Plugin.finalise(self)
diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py
index 8ff40373a..5f21451b6 100644
--- a/openlp/plugins/songusage/songusageplugin.py
+++ b/openlp/plugins/songusage/songusageplugin.py
@@ -32,6 +32,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, Receiver, build_icon, \
translate
from openlp.core.lib.db import Manager
+from openlp.core.lib.ui import base_action, shortcut_action, UiStrings
+from openlp.core.utils.actions import ActionList
from openlp.plugins.songusage.forms import SongUsageDetailForm, \
SongUsageDeleteForm
from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem
@@ -63,30 +65,25 @@ class SongUsagePlugin(Plugin):
self.SongUsageMenu.setObjectName(u'SongUsageMenu')
self.SongUsageMenu.setTitle(translate(
'SongUsagePlugin', '&Song Usage Tracking'))
- #SongUsage Delete
- self.SongUsageDelete = QtGui.QAction(tools_menu)
+ # SongUsage Delete
+ self.SongUsageDelete = base_action(tools_menu, u'SongUsageDelete')
self.SongUsageDelete.setText(translate('SongUsagePlugin',
'&Delete Tracking Data'))
self.SongUsageDelete.setStatusTip(translate('SongUsagePlugin',
'Delete song usage data up to a specified date.'))
- self.SongUsageDelete.setObjectName(u'SongUsageDelete')
- #SongUsage Report
- self.SongUsageReport = QtGui.QAction(tools_menu)
+ # SongUsage Report
+ self.SongUsageReport = base_action(tools_menu, u'SongUsageReport')
self.SongUsageReport.setText(
translate('SongUsagePlugin', '&Extract Tracking Data'))
self.SongUsageReport.setStatusTip(
translate('SongUsagePlugin', 'Generate a report on song usage.'))
- self.SongUsageReport.setObjectName(u'SongUsageReport')
- #SongUsage activation
- self.SongUsageStatus = QtGui.QAction(tools_menu)
- self.SongUsageStatus.setCheckable(True)
- self.SongUsageStatus.setChecked(False)
+ # SongUsage activation
+ self.SongUsageStatus = shortcut_action(tools_menu, u'SongUsageStatus',
+ [QtCore.Qt.Key_F4], self.toggleSongUsageState, checked=False)
self.SongUsageStatus.setText(translate(
'SongUsagePlugin', 'Toggle Tracking'))
self.SongUsageStatus.setStatusTip(translate('SongUsagePlugin',
'Toggle the tracking of song usage.'))
- self.SongUsageStatus.setShortcut(u'F4')
- self.SongUsageStatus.setObjectName(u'SongUsageStatus')
#Add Menus together
self.toolsMenu.addAction(self.SongUsageMenu.menuAction())
self.SongUsageMenu.addAction(self.SongUsageStatus)
@@ -97,9 +94,6 @@ class SongUsagePlugin(Plugin):
QtCore.QObject.connect(self.SongUsageStatus,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.SongUsageStatus.setChecked)
- QtCore.QObject.connect(self.SongUsageStatus,
- QtCore.SIGNAL(u'triggered(bool)'),
- self.toggleSongUsageState)
QtCore.QObject.connect(self.SongUsageDelete,
QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete)
QtCore.QObject.connect(self.SongUsageReport,
@@ -116,6 +110,13 @@ class SongUsagePlugin(Plugin):
self.settingsSection + u'/active',
QtCore.QVariant(False)).toBool()
self.SongUsageStatus.setChecked(self.SongUsageActive)
+ action_list = ActionList.get_instance()
+ action_list.add_action(self.SongUsageDelete,
+ translate('SongUsagePlugin', 'Song Usage'))
+ action_list.add_action(self.SongUsageReport,
+ translate('SongUsagePlugin', 'Song Usage'))
+ action_list.add_action(self.SongUsageStatus,
+ translate('SongUsagePlugin', 'Song Usage'))
if self.manager is None:
self.manager = Manager(u'songusage', init_schema)
self.SongUsagedeleteform = SongUsageDeleteForm(self.manager,
@@ -131,6 +132,13 @@ class SongUsagePlugin(Plugin):
self.manager.finalise()
Plugin.finalise(self)
self.SongUsageMenu.menuAction().setVisible(False)
+ action_list = ActionList.get_instance()
+ action_list.remove_action(self.SongUsageDelete,
+ translate('SongUsagePlugin', 'Song Usage'))
+ action_list.remove_action(self.SongUsageReport,
+ translate('SongUsagePlugin', 'Song Usage'))
+ action_list.remove_action(self.SongUsageStatus,
+ translate('SongUsagePlugin', 'Song Usage'))
#stop any events being processed
self.SongUsageActive = False
diff --git a/resources/forms/shortcutlistdialog.ui b/resources/forms/shortcutlistdialog.ui
index 519925560..9a5c599d1 100644
--- a/resources/forms/shortcutlistdialog.ui
+++ b/resources/forms/shortcutlistdialog.ui
@@ -41,35 +41,35 @@
-
-
+
+
+ 0
+
8
-
- 0
-
-
-
+
-
- Default: None
+ Default:
true
- -
-
+
-
+
+
+ Custom:
+
+
+
+ -
+
8
-
-
-
-
- Custom:
-
-
-
-
@@ -83,7 +83,7 @@
- :/system/system_settings.png:/system/system_settings.png
+ :/system/system_configure_shortcuts.png:/system/system_configure_shortcuts.png
true
@@ -110,21 +110,51 @@
+
+
+ -
+
+
+ 8
+
-
-
-
- Qt::Horizontal
+
+
+ None
-
-
- 40
- 20
-
+
+
+ :/system/system_configure_shortcuts.png:/system/system_configure_shortcuts.png
-
+
+
+ -
+
+
+
+
+
+
+ :/system/clear_shortcut.png:/system/clear_shortcut.png
+
+
+ -
+
+
+ Ctrl+V
+
+
+
+ -
+
+
+ Shift+Ins
+
+
+
-