← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~j-corwin/openlp/custom into lp:openlp

 

Jonathan Corwin has proposed merging lp:~j-corwin/openlp/custom into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~j-corwin/openlp/custom/+merge/141191

Edit/save custom slide items in service files.

- When re-opening a saved service file, custom items that are already in the media manager can now be edited.

- Add a setting to automatically add missing custom items to the media manager (note, this will only work for custom items in services saved in this branch, not existing service files due it not having the required 'capability' saved)

- For any 'text' item in the service (customs, songs, bibles) there is now a context menu to save this as a custom. I'm open to constructive criticism on this! I added it for when the "auto add missing item" option was off, but someone might want to save one-offs. Then I remembered that someone requested the ability to convert a bible item to a custom so it could be re-formatted if required. Since I didn't want to hard code specific plugins in the service manager I just enabled it for all text items. However I accept it might be odd to be able to save a song as a custom item, but some might find benefit!

IMPORTANT:
This contains changes that will conflict with Andreas' changes, so should not be merged until that is and I've then updated it accordingly. (I'm merge requesting it for comment and errors)

I will update code standards in the changed modules in a separate request, once this has gone in.


-- 
https://code.launchpad.net/~j-corwin/openlp/custom/+merge/141191
Your team OpenLP Core is requested to review the proposed merge of lp:~j-corwin/openlp/custom into lp:openlp.
=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2012-12-10 18:04:58 +0000
+++ openlp/core/ui/servicemanager.py	2012-12-23 20:53:23 +0000
@@ -40,7 +40,7 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, ItemCapabilities, SettingsManager, \
-    translate, str_to_bool, check_directory_exists
+    translate, str_to_bool, check_directory_exists, PluginStatus
 from openlp.core.lib.theme import ThemeLevel
 from openlp.core.lib.settings import Settings
 from openlp.core.lib.ui import UiStrings, critical_error_message_box, create_widget_action, find_and_set_in_combo_box
@@ -258,6 +258,8 @@
             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)
@@ -759,6 +761,7 @@
             pos = item.parent().data(0, QtCore.Qt.UserRole).toInt()[0]
         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)
@@ -778,6 +781,11 @@
             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:
@@ -1317,6 +1325,13 @@
             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

=== modified file 'openlp/plugins/custom/forms/editcustomform.py'
--- openlp/plugins/custom/forms/editcustomform.py	2012-12-05 06:12:07 +0000
+++ openlp/plugins/custom/forms/editcustomform.py	2012-12-23 20:53:23 +0000
@@ -125,8 +125,6 @@
         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),
                 unicode(self.slideListView.item(count).text()))

=== modified file 'openlp/plugins/custom/lib/customtab.py'
--- openlp/plugins/custom/lib/customtab.py	2012-12-01 07:57:54 +0000
+++ openlp/plugins/custom/lib/customtab.py	2012-12-23 20:53:23 +0000
@@ -49,18 +49,25 @@
         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
@@ -68,12 +75,24 @@
         if check_state == QtCore.Qt.Checked:
             self.displayFooter = True
 
+    def on_add_from_service_check_box_changed(self, check_state):
+        self.update_load = False
+        # we have a set value convert to True/False
+        if check_state == QtCore.Qt.Checked:
+            self.update_load = True
+
     def load(self):
-        self.displayFooter = Settings().value(
-            self.settingsSection + u'/display footer',
-            QtCore.QVariant(True)).toBool()
+        settings = Settings()
+        settings.beginGroup(self.settingsSection)
+        self.displayFooter = settings.value(u'/display footer', QtCore.QVariant(True)).toBool()
+        self.update_load = settings.value(u'add custom from service', QtCore.QVariant(True)).toBool()
         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',
-            QtCore.QVariant(self.displayFooter))
+        settings = Settings()
+        settings.beginGroup(self.settingsSection)
+        settings.setValue(self.settingsSection + u'/display footer', QtCore.QVariant(self.displayFooter))
+        settings.setValue(u'add custom from service', QtCore.QVariant(self.update_load))
+        settings.endGroup()

=== modified file 'openlp/plugins/custom/lib/customxmlhandler.py'
--- openlp/plugins/custom/lib/customxmlhandler.py	2012-12-01 07:57:54 +0000
+++ openlp/plugins/custom/lib/customxmlhandler.py	2012-12-23 20:53:23 +0000
@@ -62,6 +62,8 @@
         """
         # Create the minidom document
         self.custom_xml = Document()
+        self.new_document()
+        self.add_lyrics_to_song()
 
     def new_document(self):
         """

=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
--- openlp/plugins/custom/lib/mediaitem.py	2012-12-03 19:19:10 +0000
+++ openlp/plugins/custom/lib/mediaitem.py	2012-12-23 20:53:23 +0000
@@ -30,14 +30,14 @@
 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
+from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, check_item_selected, translate, \
+    ServiceItemContext, PluginStatus
 from openlp.core.lib.ui import UiStrings
 from openlp.core.lib.settings import Settings
 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__)
@@ -86,6 +86,13 @@
             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', QtCore.QVariant(u'True')).toBool()
 
     def retranslateUi(self):
         self.searchTextLabel.setText(u'%s:' % UiStrings().Search)
@@ -104,6 +111,7 @@
         self.searchTextEdit.setCurrentSearchType(Settings().value(
             u'%s/last search type' % self.settingsSection,
             QtCore.QVariant(CustomSearch.Titles)).toInt()[0])
+        self.config_updated()
 
     def loadList(self, custom_slides):
         # Sort out what custom we want to select after loading the list.
@@ -201,6 +209,7 @@
         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
@@ -256,6 +265,50 @@
         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':
+            self.plugin.serviceManager.replaceServiceItem(item)
+            Receiver.send_message(u'service_item_update', u'%s:%s:%s' % (custom.id, item._uuid, False))
+
     def onClearTextButtonClick(self):
         """
         Clear the search text.


Follow ups