forked from openlp/openlp
Head
This commit is contained in:
commit
d6ad079a0b
@ -141,10 +141,21 @@ class Settings(QtCore.QSettings):
|
||||
if defaultValue is None and not super(Settings, self).contains(key):
|
||||
return None
|
||||
setting = super(Settings, self).value(key, defaultValue)
|
||||
# An empty list saved to the settings results in a None type being
|
||||
# returned.
|
||||
# On OS X (and probably on other platforms too) empty value from QSettings
|
||||
# is represented as type PyQt4.QtCore.QPyNullVariant. This type has to be
|
||||
# converted to proper 'None' Python type.
|
||||
if isinstance(setting, QtCore.QPyNullVariant) and setting.isNull():
|
||||
setting = None
|
||||
# Handle 'None' type (empty value) properly.
|
||||
if setting is None:
|
||||
return []
|
||||
# An empty string saved to the settings results in a None type being
|
||||
# returned. Convert it to empty unicode string.
|
||||
if isinstance(defaultValue, unicode):
|
||||
return u''
|
||||
# An empty list saved to the settings results in a None type being
|
||||
# returned.
|
||||
else:
|
||||
return []
|
||||
# Convert the setting to the correct type.
|
||||
if isinstance(defaultValue, bool):
|
||||
if isinstance(setting, bool):
|
||||
|
@ -40,7 +40,7 @@ log = logging.getLogger(__name__)
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, ItemCapabilities, SettingsManager, \
|
||||
translate, str_to_bool, check_directory_exists, Settings
|
||||
translate, str_to_bool, check_directory_exists, Settings, PluginStatus
|
||||
from openlp.core.lib.theme import ThemeLevel
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box, create_widget_action, find_and_set_in_combo_box
|
||||
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
|
||||
@ -252,6 +252,9 @@ class ServiceManager(QtGui.QWidget):
|
||||
icon=u':/media/auto-start_active.png', triggers=self.onAutoStart)
|
||||
# Add already existing delete action to the menu.
|
||||
self.menu.addAction(self.serviceManagerList.delete)
|
||||
self.create_custom_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ServiceManager', 'Create New &Custom Slide'),
|
||||
icon=u':/general/general_edit.png', triggers=self.create_custom)
|
||||
self.menu.addSeparator()
|
||||
self.previewAction = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', 'Show &Preview'),
|
||||
icon=u':/general/general_preview.png', triggers=self.makePreview)
|
||||
@ -751,6 +754,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
pos = item.data(0, QtCore.Qt.UserRole)
|
||||
serviceItem = self.serviceItems[pos - 1]
|
||||
self.editAction.setVisible(False)
|
||||
self.create_custom_action.setVisible(False)
|
||||
self.maintainAction.setVisible(False)
|
||||
self.notesAction.setVisible(False)
|
||||
self.timeAction.setVisible(False)
|
||||
@ -770,6 +774,11 @@ class ServiceManager(QtGui.QWidget):
|
||||
if serviceItem[u'service_item'].will_auto_start:
|
||||
self.autoStartAction.setText(translate('OpenLP.ServiceManager', '&Auto Start - active'))
|
||||
self.autoStartAction.setIcon(self.active)
|
||||
if serviceItem[u'service_item'].is_text():
|
||||
for plugin in self.mainwindow.pluginManager.plugins:
|
||||
if plugin.name == u'custom' and plugin.status == PluginStatus.Active:
|
||||
self.create_custom_action.setVisible(True)
|
||||
break
|
||||
self.themeMenu.menuAction().setVisible(False)
|
||||
# Set up the theme menu.
|
||||
if serviceItem[u'service_item'].is_text() and self.mainwindow.renderer.theme_level == ThemeLevel.Song:
|
||||
@ -1306,6 +1315,13 @@ class ServiceManager(QtGui.QWidget):
|
||||
Receiver.send_message(u'%s_edit' % self.serviceItems[item][u'service_item'].name.lower(),
|
||||
u'L:%s' % self.serviceItems[item][u'service_item'].edit_id)
|
||||
|
||||
def create_custom(self):
|
||||
"""
|
||||
Saves the current text item as a custom slide
|
||||
"""
|
||||
item = self.findServiceItem()[0]
|
||||
Receiver.send_message(u'custom_create_from_service', self.serviceItems[item][u'service_item'])
|
||||
|
||||
def findServiceItem(self):
|
||||
"""
|
||||
Finds the first selected ServiceItem in the list and returns the
|
||||
|
@ -125,8 +125,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
if not self._validate():
|
||||
return False
|
||||
sxml = CustomXMLBuilder()
|
||||
sxml.new_document()
|
||||
sxml.add_lyrics_to_song()
|
||||
for count in range(self.slideListView.count()):
|
||||
sxml.add_verse_to_lyrics(u'custom', unicode(count + 1),
|
||||
self.slideListView.item(count).text())
|
||||
|
@ -48,18 +48,25 @@ class CustomTab(SettingsTab):
|
||||
self.displayFooterCheckBox = QtGui.QCheckBox(self.customModeGroupBox)
|
||||
self.displayFooterCheckBox.setObjectName(u'displayFooterCheckBox')
|
||||
self.customModeLayout.addRow(self.displayFooterCheckBox)
|
||||
self.add_from_service_checkbox = QtGui.QCheckBox(self.customModeGroupBox)
|
||||
self.add_from_service_checkbox.setObjectName(u'add_from_service_checkbox')
|
||||
self.customModeLayout.addRow(self.add_from_service_checkbox)
|
||||
self.leftLayout.addWidget(self.customModeGroupBox)
|
||||
self.leftLayout.addStretch()
|
||||
self.rightLayout.addStretch()
|
||||
QtCore.QObject.connect(self.displayFooterCheckBox,
|
||||
QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onDisplayFooterCheckBoxChanged)
|
||||
QtCore.QObject.connect(self.add_from_service_checkbox,
|
||||
QtCore.SIGNAL(u'stateChanged(int)'), self.on_add_from_service_check_box_changed)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.customModeGroupBox.setTitle(translate('CustomPlugin.CustomTab',
|
||||
'Custom Display'))
|
||||
self.displayFooterCheckBox.setText(
|
||||
translate('CustomPlugin.CustomTab', 'Display footer'))
|
||||
self.add_from_service_checkbox.setText(translate('CustomPlugin.CustomTab',
|
||||
'Import missing custom slides from service files'))
|
||||
|
||||
def onDisplayFooterCheckBoxChanged(self, check_state):
|
||||
self.displayFooter = False
|
||||
@ -67,11 +74,21 @@ class CustomTab(SettingsTab):
|
||||
if check_state == QtCore.Qt.Checked:
|
||||
self.displayFooter = True
|
||||
|
||||
def on_add_from_service_check_box_changed(self, check_state):
|
||||
self.update_load = (check_state == QtCore.Qt.Checked)
|
||||
|
||||
def load(self):
|
||||
self.displayFooter = Settings().value(
|
||||
self.settingsSection + u'/display footer', True)
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.displayFooter = settings.value(u'display footer', True)
|
||||
self.update_load = settings.value(u'add custom from service', True)
|
||||
self.displayFooterCheckBox.setChecked(self.displayFooter)
|
||||
self.add_from_service_checkbox.setChecked(self.update_load)
|
||||
settings.endGroup()
|
||||
|
||||
def save(self):
|
||||
Settings().setValue(self.settingsSection + u'/display footer',
|
||||
self.displayFooter)
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settingsSection)
|
||||
settings.setValue(u'display footer', self.displayFooter)
|
||||
settings.setValue(u'add custom from service', self.update_load)
|
||||
settings.endGroup()
|
||||
|
@ -62,6 +62,8 @@ class CustomXMLBuilder(object):
|
||||
"""
|
||||
# Create the minidom document
|
||||
self.custom_xml = Document()
|
||||
self.new_document()
|
||||
self.add_lyrics_to_song()
|
||||
|
||||
def new_document(self):
|
||||
"""
|
||||
|
@ -30,13 +30,13 @@
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from sqlalchemy.sql import or_, func
|
||||
from sqlalchemy.sql import or_, func, and_
|
||||
|
||||
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
|
||||
check_item_selected, translate, ServiceItemContext, Settings
|
||||
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, check_item_selected, translate, \
|
||||
ServiceItemContext, Settings, PluginStatus
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
from openlp.plugins.custom.forms import EditCustomForm
|
||||
from openlp.plugins.custom.lib import CustomXMLParser
|
||||
from openlp.plugins.custom.lib import CustomXMLParser, CustomXMLBuilder
|
||||
from openlp.plugins.custom.lib.db import CustomSlide
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -85,6 +85,12 @@ class CustomMediaItem(MediaManagerItem):
|
||||
QtCore.SIGNAL(u'custom_load_list'), self.loadList)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_updated'), self.config_updated)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'custom_create_from_service'), self.create_from_service_item)
|
||||
|
||||
def config_updated(self):
|
||||
self.add_custom_from_service = Settings().value(self.settingsSection + u'/add custom from service', True)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.searchTextLabel.setText(u'%s:' % UiStrings().Search)
|
||||
@ -102,6 +108,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
CustomSlide, order_by_ref=CustomSlide.title))
|
||||
self.searchTextEdit.setCurrentSearchType(Settings().value(
|
||||
u'%s/last search type' % self.settingsSection, CustomSearch.Titles))
|
||||
self.config_updated()
|
||||
|
||||
def loadList(self, custom_slides):
|
||||
# Sort out what custom we want to select after loading the list.
|
||||
@ -198,6 +205,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
service_item.add_capability(ItemCapabilities.CanPreview)
|
||||
service_item.add_capability(ItemCapabilities.CanLoop)
|
||||
service_item.add_capability(ItemCapabilities.CanSoftBreak)
|
||||
service_item.add_capability(ItemCapabilities.OnLoadUpdate)
|
||||
customSlide = self.plugin.manager.get_object(CustomSlide, item_id)
|
||||
title = customSlide.title
|
||||
credit = customSlide.credits
|
||||
@ -252,6 +260,49 @@ class CustomMediaItem(MediaManagerItem):
|
||||
elif not text:
|
||||
self.onClearTextButtonClick()
|
||||
|
||||
def serviceLoad(self, item):
|
||||
"""
|
||||
Triggered by a song being loaded by the service manager.
|
||||
"""
|
||||
log.debug(u'serviceLoad')
|
||||
if self.plugin.status != PluginStatus.Active:
|
||||
return
|
||||
custom = self.plugin.manager.get_object_filtered(CustomSlide,
|
||||
and_(CustomSlide.title == item.title, CustomSlide.theme_name == item.theme,
|
||||
CustomSlide.credits == item.raw_footer[0][len(item.title) + 1:]))
|
||||
if custom:
|
||||
Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item._uuid, False))
|
||||
else:
|
||||
if self.add_custom_from_service:
|
||||
self.create_from_service_item(item)
|
||||
|
||||
def create_from_service_item(self, item):
|
||||
"""
|
||||
Create a custom slide from a text service item
|
||||
"""
|
||||
custom = CustomSlide()
|
||||
custom.title = item.title
|
||||
if item.theme:
|
||||
custom.theme_name = item.theme
|
||||
else:
|
||||
custom.theme_name = u''
|
||||
footer = u' '.join(item.raw_footer)
|
||||
if footer:
|
||||
if footer.startswith(item.title):
|
||||
custom.credits = footer[len(item.title) + 1:]
|
||||
else:
|
||||
custom.credits = footer
|
||||
else:
|
||||
custom.credits = u''
|
||||
custom_xml = CustomXMLBuilder()
|
||||
for (idx, slide) in enumerate(item._raw_frames):
|
||||
custom_xml.add_verse_to_lyrics(u'custom', unicode(idx + 1), slide['raw_slide'])
|
||||
custom.text = unicode(custom_xml.extract_xml(), u'utf-8')
|
||||
self.plugin.manager.save_object(custom)
|
||||
self.onSearchTextButtonClicked()
|
||||
if item.name.lower() == u'custom':
|
||||
Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item._uuid, False))
|
||||
|
||||
def onClearTextButtonClick(self):
|
||||
"""
|
||||
Clear the search text.
|
||||
|
@ -93,6 +93,12 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
||||
self.verseNumberBox.value())
|
||||
|
||||
def onVerseTypeComboBoxChanged(self):
|
||||
self.updateSuggestedVerseNumber()
|
||||
|
||||
def onCursorPositionChanged(self):
|
||||
self.updateSuggestedVerseNumber()
|
||||
|
||||
def updateSuggestedVerseNumber(self):
|
||||
"""
|
||||
Adjusts the verse number SpinBox in regard to the selected verse type
|
||||
and the cursor's position.
|
||||
@ -116,43 +122,10 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
||||
if match:
|
||||
verse_tag = match.group(1)
|
||||
try:
|
||||
verse_num = int(match.group(2))
|
||||
verse_num = int(match.group(2)) + 1
|
||||
except ValueError:
|
||||
verse_num = 1
|
||||
if VerseType.from_loose_input(verse_tag, False):
|
||||
self.verseNumberBox.setValue(verse_num)
|
||||
|
||||
def onCursorPositionChanged(self):
|
||||
"""
|
||||
Determines the previous verse type and number in regard to the cursor's
|
||||
position and adjusts the ComboBox and SpinBox to these values.
|
||||
"""
|
||||
position = self.verseTextEdit.textCursor().position()
|
||||
text = self.verseTextEdit.toPlainText()
|
||||
if not text:
|
||||
return
|
||||
if text.rfind(u'[', 0, position) > text.rfind(u']', 0, position) and \
|
||||
text.find(u']', position) < text.find(u'[', position):
|
||||
return
|
||||
position = text.rfind(u'---[', 0, position)
|
||||
if position == -1:
|
||||
return
|
||||
text = text[position:]
|
||||
position = text.find(u']---')
|
||||
if position == -1:
|
||||
return
|
||||
text = text[:position + 4]
|
||||
match = VERSE_REGEX.match(text)
|
||||
if match:
|
||||
verse_type = match.group(1)
|
||||
verse_type_index = VerseType.from_loose_input(verse_type, None)
|
||||
try:
|
||||
verse_number = int(match.group(2))
|
||||
except ValueError:
|
||||
verse_number = 1
|
||||
if verse_type_index is not None:
|
||||
self.verseTypeComboBox.setCurrentIndex(verse_type_index)
|
||||
self.verseNumberBox.setValue(verse_number)
|
||||
self.verseNumberBox.setValue(verse_num)
|
||||
|
||||
def setVerse(self, text, single=False,
|
||||
tag=u'%s1' % VerseType.Tags[VerseType.Verse]):
|
||||
|
Loading…
Reference in New Issue
Block a user