diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py
index 86e0a0a30..b6f12d180 100644
--- a/openlp/core/lib/db.py
+++ b/openlp/core/lib/db.py
@@ -358,10 +358,17 @@ class Manager(object):
def delete_all_objects(self, object_class, filter_clause=None):
"""
- Delete all object records
+ Delete all object records.
+ This method should only be used for simple tables and not ones with
+ relationships. The relationships are not deleted from the database and
+ this will lead to database corruptions.
``object_class``
The type of object to delete
+
+ ``filter_clause``
+ The filter governing selection of objects to return. Defaults to
+ None.
"""
try:
query = self.session.query(object_class)
diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py
index 14b6126bc..40cac8e35 100644
--- a/openlp/core/lib/eventreceiver.py
+++ b/openlp/core/lib/eventreceiver.py
@@ -115,8 +115,12 @@ class EventReceiver(QtCore.QObject):
``slidecontroller_live_stop_loop``
Stop the loop on the main display.
+
**Servicemanager related signals**
+ ``servicemanager_new_service``
+ A new service is being loaded or created.
+
``servicemanager_previous_item``
Display the previous item in the service.
diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py
index b12a27f1d..62418f49e 100644
--- a/openlp/core/lib/serviceitem.py
+++ b/openlp/core/lib/serviceitem.py
@@ -119,6 +119,7 @@ class ServiceItem(object):
self.image_border = u'#000000'
self.background_audio = []
self.theme_overwritten = False
+ self.temporary_edit = False
self._new_item()
def _new_item(self):
@@ -365,6 +366,7 @@ class ServiceItem(object):
"""
self._uuid = other._uuid
self.notes = other.notes
+ self.temporary_edit = other.temporary_edit
# Copy theme over if present.
if other.theme is not None:
self.theme = other.theme
diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py
index e439b1db1..328970d45 100644
--- a/openlp/core/ui/maindisplay.py
+++ b/openlp/core/ui/maindisplay.py
@@ -45,7 +45,7 @@ log = logging.getLogger(__name__)
class Display(QtGui.QGraphicsView):
"""
- This is a general display screen class. Here the general display settings
+ This is a general display screen class. Here the general display settings
will done. It will be used as specialized classes by Main Display and
Preview display.
"""
@@ -66,7 +66,7 @@ class Display(QtGui.QGraphicsView):
"""
Set up and build the screen base
"""
- log.debug(u'Start Display base setup (live = %s)' % self.isLive)
+ log.debug(u'Start Display base setup (live = %s)' % self.isLive)
self.setGeometry(self.screen[u'size'])
log.debug(u'Setup webView')
self.webView = QtWebKit.QWebView(self)
diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py
index 0480cb70b..0eb1e77c5 100644
--- a/openlp/core/ui/servicemanager.py
+++ b/openlp/core/ui/servicemanager.py
@@ -37,7 +37,7 @@ log = logging.getLogger(__name__)
from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
- ItemCapabilities, SettingsManager, translate
+ ItemCapabilities, SettingsManager, translate, str_to_bool
from openlp.core.lib.theme import ThemeLevel
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
context_menu_action, context_menu_separator, find_and_set_in_combo_box
@@ -465,6 +465,7 @@ class ServiceManager(QtGui.QWidget):
self.setModified(False)
QtCore.QSettings(). \
setValue(u'servicemanager/last file',QtCore.QVariant(u''))
+ Receiver.send_message(u'servicemanager_new_service')
def saveFile(self):
"""
@@ -663,13 +664,14 @@ class ServiceManager(QtGui.QWidget):
serviceItem.renderer = self.mainwindow.renderer
serviceItem.set_from_service(item, self.servicePath)
self.validateItem(serviceItem)
- self.loadItem_uuid = 0
+ self.load_item_uuid = 0
if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate):
Receiver.send_message(u'%s_service_load' %
serviceItem.name.lower(), serviceItem)
# if the item has been processed
- if serviceItem._uuid == self.loadItem_uuid:
- serviceItem.edit_id = int(self.loadItem_editId)
+ if serviceItem._uuid == self.load_item_uuid:
+ serviceItem.edit_id = int(self.load_item_edit_id)
+ serviceItem.temporary_edit = self.load_item_temporary
self.addServiceItem(serviceItem, repaint=False)
delete_file(p_file)
self.setFileName(fileName)
@@ -999,6 +1001,17 @@ class ServiceManager(QtGui.QWidget):
painter.drawImage(0, 0, overlay)
painter.end()
treewidgetitem.setIcon(0, build_icon(icon))
+ elif serviceitem.temporary_edit:
+ icon = QtGui.QImage(serviceitem.icon)
+ icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
+ QtCore.Qt.SmoothTransformation)
+ overlay = QtGui.QImage(':/general/general_export.png')
+ overlay = overlay.scaled(40, 40, QtCore.Qt.KeepAspectRatio,
+ QtCore.Qt.SmoothTransformation)
+ painter = QtGui.QPainter(icon)
+ painter.drawImage(40, 0, overlay)
+ painter.end()
+ treewidgetitem.setIcon(0, build_icon(icon))
else:
treewidgetitem.setIcon(0, serviceitem.iconic_representation)
else:
@@ -1006,6 +1019,11 @@ class ServiceManager(QtGui.QWidget):
build_icon(u':/general/general_delete.png'))
treewidgetitem.setText(0, serviceitem.get_display_title())
tips = []
+ if serviceitem.temporary_edit:
+ tips.append(u'%s: %s' %
+ (unicode(translate('OpenLP.ServiceManager', 'Edit')),
+ (unicode(translate('OpenLP.ServiceManager',
+ 'Service copy only')))))
if serviceitem.theme and serviceitem.theme != -1:
tips.append(u'%s: %s' %
(unicode(translate('OpenLP.ServiceManager', 'Slide theme')),
@@ -1127,8 +1145,9 @@ class ServiceManager(QtGui.QWidget):
Triggered from plugins to update service items.
Save the values as they will be used as part of the service load
"""
- editId, self.loadItem_uuid = message.split(u':')
- self.loadItem_editId = int(editId)
+ edit_id, self.load_item_uuid, temporary = message.split(u':')
+ self.load_item_edit_id = int(edit_id)
+ self.load_item_temporary = str_to_bool(temporary)
def replaceServiceItem(self, newItem):
"""
diff --git a/openlp/plugins/songs/forms/songexportform.py b/openlp/plugins/songs/forms/songexportform.py
index 22020a401..20a52c82d 100644
--- a/openlp/plugins/songs/forms/songexportform.py
+++ b/openlp/plugins/songs/forms/songexportform.py
@@ -252,6 +252,9 @@ class SongExportForm(OpenLPWizard):
songs = self.plugin.manager.get_all_objects(Song)
songs.sort(cmp=locale.strcoll, key=lambda song: song.title.lower())
for song in songs:
+ # No need to export temporary songs.
+ if song.temporary:
+ continue
authors = u', '.join([author.display_name
for author in song.authors])
title = u'%s (%s)' % (unicode(song.title), authors)
diff --git a/openlp/plugins/songs/lib/db.py b/openlp/plugins/songs/lib/db.py
index 37ee42451..ce228e5f8 100644
--- a/openlp/plugins/songs/lib/db.py
+++ b/openlp/plugins/songs/lib/db.py
@@ -199,7 +199,8 @@ def init_schema(url):
Column(u'search_lyrics', types.UnicodeText, nullable=False),
Column(u'create_date', types.DateTime(), default=func.now()),
Column(u'last_modified', types.DateTime(), default=func.now(),
- onupdate=func.now())
+ onupdate=func.now()),
+ Column(u'temporary', types.Boolean(), default=False)
)
# Definition of the "topics" table
diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py
index dad95c61b..052fb5b7b 100644
--- a/openlp/plugins/songs/lib/mediaitem.py
+++ b/openlp/plugins/songs/lib/mediaitem.py
@@ -270,6 +270,9 @@ class SongMediaItem(MediaManagerItem):
searchresults.sort(
cmp=locale.strcoll, key=lambda song: song.title.lower())
for song in searchresults:
+ # Do not display temporary songs
+ if song.temporary:
+ continue
author_list = [author.display_name for author in song.authors]
song_title = unicode(song.title)
song_detail = u'%s (%s)' % (song_title, u', '.join(author_list))
@@ -286,6 +289,9 @@ class SongMediaItem(MediaManagerItem):
self.listView.clear()
for author in searchresults:
for song in author.songs:
+ # Do not display temporary songs
+ if song.temporary:
+ continue
song_detail = u'%s (%s)' % (author.display_name, song.title)
song_name = QtGui.QListWidgetItem(song_detail)
song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id))
@@ -534,6 +540,7 @@ class SongMediaItem(MediaManagerItem):
Song.search_title.asc())
editId = 0
add_song = True
+ temporary = False
if search_results:
for song in search_results:
author_list = item.data_string[u'authors']
@@ -559,13 +566,18 @@ class SongMediaItem(MediaManagerItem):
self._updateBackgroundAudio(song, item)
editId = song.id
self.onSearchTextButtonClick()
- else:
+ elif add_song and not self.addSongFromService:
# Make sure we temporary import formatting tags.
- self.openLyrics.xml_to_song(item.xml_version, True)
+ song = self.openLyrics.xml_to_song(item.xml_version, True)
+ # If there's any backing tracks, copy them over.
+ if len(item.background_audio) > 0:
+ self._updateBackgroundAudio(song, item)
+ editId = song.id
+ temporary = True
# Update service with correct song id.
if editId:
Receiver.send_message(u'service_item_update',
- u'%s:%s' % (editId, item._uuid))
+ u'%s:%s:%s' % (editId, item._uuid, temporary))
def search(self, string):
"""
diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py
index f97fdff42..25f90e860 100644
--- a/openlp/plugins/songs/lib/upgrade.py
+++ b/openlp/plugins/songs/lib/upgrade.py
@@ -33,7 +33,9 @@ from sqlalchemy import Column, Table, types
from sqlalchemy.sql.expression import func
from migrate.changeset.constraint import ForeignKeyConstraint
-__version__ = 2
+from openlp.plugins.songs.lib.db import Song
+
+__version__ = 3
def upgrade_setup(metadata):
"""
@@ -86,3 +88,12 @@ def upgrade_2(session, metadata, tables):
Column(u'last_modified', types.DateTime(), default=func.now())\
.create(table=tables[u'songs'])
+def upgrade_3(session, metadata, tables):
+ """
+ Version 3 upgrade.
+
+ This upgrade adds a temporary song flag to the songs table
+ """
+ Column(u'temporary', types.Boolean(), default=False)\
+ .create(table=tables[u'songs'])
+
diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py
index aaf82b395..b16db7e94 100644
--- a/openlp/plugins/songs/lib/xml.py
+++ b/openlp/plugins/songs/lib/xml.py
@@ -346,7 +346,7 @@ class OpenLyrics(object):
lines_element.set(u'break', u'optional')
return self._extract_xml(song_xml)
- def xml_to_song(self, xml, parse_and_not_save=False):
+ def xml_to_song(self, xml, parse_and_temporary_save=False):
"""
Create and save a song from OpenLyrics format xml to the database. Since
we also export XML from external sources (e. g. OpenLyrics import), we
@@ -355,9 +355,9 @@ class OpenLyrics(object):
``xml``
The XML to parse (unicode).
- ``parse_and_not_save``
- Switch to skip processing the whole song and to prevent storing the
- songs to the database. Defaults to ``False``.
+ ``parse_and_temporary_save``
+ Switch to skip processing the whole song and storing the songs in
+ the database with a temporary flag. Defaults to ``False``.
"""
# No xml get out of here.
if not xml:
@@ -371,14 +371,13 @@ class OpenLyrics(object):
return None
# Formatting tags are new in OpenLyrics 0.8
if float(song_xml.get(u'version')) > 0.7:
- self._process_formatting_tags(song_xml, parse_and_not_save)
- if parse_and_not_save:
- return
+ self._process_formatting_tags(song_xml, parse_and_temporary_save)
song = Song()
# Values will be set when cleaning the song.
song.search_lyrics = u''
song.verse_order = u''
song.search_title = u''
+ song.temporary = parse_and_temporary_save
self._process_copyright(properties, song)
self._process_cclinumber(properties, song)
self._process_titles(properties, song)
diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py
index 307769df0..5402ec1fa 100644
--- a/openlp/plugins/songs/songsplugin.py
+++ b/openlp/plugins/songs/songsplugin.py
@@ -78,6 +78,10 @@ class SongsPlugin(Plugin):
action_list.add_action(self.songExportItem, unicode(UiStrings().Export))
action_list.add_action(self.toolsReindexItem,
unicode(UiStrings().Tools))
+ QtCore.QObject.connect(Receiver.get_receiver(),
+ QtCore.SIGNAL(u'servicemanager_new_service'),
+ self.clearTemporarySongs)
+
def addImportMenuItem(self, import_menu):
"""
@@ -265,6 +269,8 @@ class SongsPlugin(Plugin):
Time to tidy up on exit
"""
log.info(u'Songs Finalising')
+ self.clearTemporarySongs()
+ # Clean up files and connections
self.manager.finalise()
self.songImportItem.setVisible(False)
self.songExportItem.setVisible(False)
@@ -277,3 +283,9 @@ class SongsPlugin(Plugin):
action_list.remove_action(self.toolsReindexItem,
unicode(UiStrings().Tools))
Plugin.finalise(self)
+
+ def clearTemporarySongs(self):
+ # Remove temporary songs
+ songs = self.manager.get_all_objects(Song, Song.temporary == True)
+ for song in songs:
+ self.manager.delete_object(Song, song.id)