From 4c3e32c4d7bc2bd91acf14db81829ba9e4cbc725 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 26 Nov 2010 07:36:20 +0000 Subject: [PATCH 01/18] Song Usage documentation --- documentation/manual/source/index.rst | 1 + .../manual/source/pics/songusage.png | Bin 0 -> 27549 bytes .../manual/source/pics/songusagedelete.png | Bin 0 -> 27818 bytes .../manual/source/pics/songusagereport.png | Bin 0 -> 56226 bytes documentation/manual/source/songusage.rst | 35 ++++++++++++++++++ 5 files changed, 36 insertions(+) create mode 100644 documentation/manual/source/pics/songusage.png create mode 100644 documentation/manual/source/pics/songusagedelete.png create mode 100644 documentation/manual/source/pics/songusagereport.png create mode 100644 documentation/manual/source/songusage.rst diff --git a/documentation/manual/source/index.rst b/documentation/manual/source/index.rst index ac29c4360..5228256cf 100644 --- a/documentation/manual/source/index.rst +++ b/documentation/manual/source/index.rst @@ -14,6 +14,7 @@ Contents: introduction glossary dualmonitors + songusage Indices and tables ================== diff --git a/documentation/manual/source/pics/songusage.png b/documentation/manual/source/pics/songusage.png new file mode 100644 index 0000000000000000000000000000000000000000..10f29f2a931d6fab0e3334aa538fbfbaed45c222 GIT binary patch literal 27549 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 AE&u=k literal 0 HcmV?d00001 diff --git a/documentation/manual/source/pics/songusagereport.png b/documentation/manual/source/pics/songusagereport.png new file mode 100644 index 0000000000000000000000000000000000000000..c0d9df3dde4edc8525bba19cb25168abef153c1d GIT binary patch literal 56226 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%0DLyWkk*7?m_T$|V# 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 b&&!1jNoTXOXJkOG5>HcAPo-MPF6RFL%{|*K literal 0 HcmV?d00001 diff --git a/documentation/manual/source/songusage.rst b/documentation/manual/source/songusage.rst new file mode 100644 index 000000000..d77cc3632 --- /dev/null +++ b/documentation/manual/source/songusage.rst @@ -0,0 +1,35 @@ +========== +Song Usage +========== + +The Songusage plugin records the usage of Songs when they are used in a **Live** situation. +If the plugin is active all songs sent to the Live Service Manager are recorded by this plugin. +Once the plugin has been activated by the plugin menu it can be turned on and off by use of +the``F4`` key or the SongUsage menus. + +The image below shows the menu items and how to access them. + +.. image:: pics/songusage.png + + +Generating reports +------------------ +Reports can be generated between any two dates. The system defaults to 1st September previous year to 31st +August current year. The data is written to a file in a selectable directory. +The file name is **usage_detail_fromdate_todate.txt**. + +.. image:: pics/songusagereport.png + +The details extracted are: + - Date item used + - Time item used + - Song Title + - Song Copyright + - Song CCLI. + +Removing data +------------- +To remove stored data use the option below which can be access from the Tools Toolbar. Select the +date you wish to remove data up to and press``Ok`` + +.. image:: pics/songusagedelete.png \ No newline at end of file From f153c27d321e478fa5397e5a50ba2ddee8a45958 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 26 Nov 2010 09:00:14 +0000 Subject: [PATCH 02/18] Fix preview of live when returning from blank display --- openlp/core/ui/maindisplay.py | 2 +- openlp/core/ui/slidecontroller.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 5a53a84fe..9d6c04075 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -459,9 +459,9 @@ class MainDisplay(DisplayWidget): if self.phononActive: self.webView.setVisible(False) self.videoPlay() + self.hide_mode = None # Trigger actions when display is active again Receiver.send_message(u'maindisplay_active') - self.hide_mode = None class AudioPlayer(QtCore.QObject): """ diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 0afb0efaa..618665a7c 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -391,6 +391,8 @@ class SlideController(QtGui.QWidget): if self.isLive: QtCore.QObject.connect(self.volumeSlider, QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'maindisplay_active'), self.updatePreview) def screenSizeChanged(self): """ @@ -823,16 +825,15 @@ class SlideController(QtGui.QWidget): row) def updatePreview(self): + log.debug(u'updatePreview %s ' %self.screens.current[u'primary']) if not self.screens.current[u'primary']: # Grab now, but try again in a couple of seconds if slide change # is slow QtCore.QTimer.singleShot(0.5, self.grabMainDisplay) QtCore.QTimer.singleShot(2.5, self.grabMainDisplay) else: - label = self.PreviewListWidget.cellWidget( - self.PreviewListWidget.currentRow(), 1) - if label: - self.SlidePreview.setPixmap(label.pixmap()) + self.SlidePreview.setPixmap( + QtGui.QPixmap.fromImage(self.display.preview())) def grabMainDisplay(self): winid = QtGui.QApplication.desktop().winId() From 2752279d4311f4ad5256804027724ebc25625dbd Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 26 Nov 2010 09:49:06 +0000 Subject: [PATCH 03/18] Remove need to restart for double click event changes --- openlp/core/lib/mediamanageritem.py | 22 +++++++++++++--------- openlp/core/ui/advancedtab.py | 2 +- openlp/core/ui/slidecontroller.py | 14 ++++++++++---- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 3eae97238..749543fd9 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -320,15 +320,9 @@ class MediaManagerItem(QtGui.QWidget): translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'), self.onAddEditClick)) - if QtCore.QSettings().value(u'advanced/double click live', - QtCore.QVariant(False)).toBool(): - QtCore.QObject.connect(self.listView, - QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), - self.onLiveClick) - else: - QtCore.QObject.connect(self.listView, - QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), - self.onPreviewClick) + QtCore.QObject.connect(self.listView, + QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), + self.onClickPressed) def initialise(self): """ @@ -430,6 +424,16 @@ class MediaManagerItem(QtGui.QWidget): raise NotImplementedError(u'MediaManagerItem.generateSlideData needs ' u'to be defined by the plugin') + def onClickPressed(self): + """ + Allows the list click action to be determined dynamically + """ + if QtCore.QSettings().value(u'advanced/double click live', + QtCore.QVariant(False)).toBool(): + self.onLiveClick() + else: + self.onPreviewClick() + def onPreviewClick(self): """ Preview an item by building a service item then adding that service diff --git a/openlp/core/ui/advancedtab.py b/openlp/core/ui/advancedtab.py index dc126d863..a390780ca 100644 --- a/openlp/core/ui/advancedtab.py +++ b/openlp/core/ui/advancedtab.py @@ -146,7 +146,7 @@ class AdvancedTab(SettingsTab): self.mediaPluginCheckBox.setText(translate('OpenLP.AdvancedTab', 'Remember active media manager tab on startup')) self.doubleClickLiveCheckBox.setText(translate('OpenLP.AdvancedTab', - 'Double-click to send items straight to live (requires restart)')) + 'Double-click to send items straight to live')) self.expandServiceItemCheckBox.setText(translate('OpenLP.AdvancedTab', 'Expand new service items on creation')) # self.sharedDirGroupBox.setTitle( diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 618665a7c..48810990a 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -331,10 +331,8 @@ class SlideController(QtGui.QWidget): QtCore.QObject.connect(self.PreviewListWidget, QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected) if not self.isLive: - if QtCore.QSettings().value(u'advanced/double click live', - QtCore.QVariant(False)).toBool(): - QtCore.QObject.connect(self.PreviewListWidget, - QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onGoLive) + QtCore.QObject.connect(self.PreviewListWidget, + QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onGoLiveClick) if isLive: QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'slidecontroller_live_spin_delay'), @@ -945,6 +943,14 @@ class SlideController(QtGui.QWidget): Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(), u'P:%s' % self.serviceItem.edit_id) + def onGoLiveClick(self): + """ + triggered by clicking the Preview slide items + """ + if QtCore.QSettings().value(u'advanced/double click live', + QtCore.QVariant(False)).toBool(): + self.onGoLive() + def onGoLive(self): """ If preview copy slide item to live From 2989b40147f22cef620bcde2710039d8ceb6da96 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 27 Nov 2010 08:53:29 +0000 Subject: [PATCH 04/18] Documentation fixes --- documentation/manual/source/songusage.rst | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/documentation/manual/source/songusage.rst b/documentation/manual/source/songusage.rst index d77cc3632..df6d930f3 100644 --- a/documentation/manual/source/songusage.rst +++ b/documentation/manual/source/songusage.rst @@ -2,10 +2,10 @@ Song Usage ========== -The Songusage plugin records the usage of Songs when they are used in a **Live** situation. -If the plugin is active all songs sent to the Live Service Manager are recorded by this plugin. -Once the plugin has been activated by the plugin menu it can be turned on and off by use of -the``F4`` key or the SongUsage menus. +The Songusage plugin records the usage of Songs when they are used in a **Live** +situation. If the plugin is active all songs sent to the Live Service Manager +are recorded by this plugin. Once the plugin has been activated by the plugin +menu it can be turned on and off by use of the``F4`` key or the SongUsage menus. The image below shows the menu items and how to access them. @@ -14,8 +14,9 @@ The image below shows the menu items and how to access them. Generating reports ------------------ -Reports can be generated between any two dates. The system defaults to 1st September previous year to 31st -August current year. The data is written to a file in a selectable directory. +This option allows reports to be generated between any two dates. The system +automatically defaults to dates between the 1st September last year and 31st +August this year. The data is written to a file in a selectable directory. The file name is **usage_detail_fromdate_todate.txt**. .. image:: pics/songusagereport.png @@ -24,12 +25,13 @@ The details extracted are: - Date item used - Time item used - Song Title - - Song Copyright + - Song Copyright - Song CCLI. Removing data ------------- -To remove stored data use the option below which can be access from the Tools Toolbar. Select the -date you wish to remove data up to and press``Ok`` +This option allows the removal of stored data use is no longer required. +Select the date you wish to remove data up to and press``Ok``. This option is +not reversable. -.. image:: pics/songusagedelete.png \ No newline at end of file +.. image:: pics/songusagedelete.png From 771c86783edda0dba7226adaa74c729c7dfe93bc Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 27 Nov 2010 08:59:49 +0000 Subject: [PATCH 05/18] Remove theme background for Images --- openlp/plugins/images/lib/mediaitem.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 71dbd8903..7394758c3 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -163,6 +163,8 @@ class ImageMediaItem(MediaManagerItem): service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsAdditions) + # force a nonexistent theme + service_item.theme = -1 for item in items: bitem = self.listView.item(item.row()) filename = unicode(bitem.data(QtCore.Qt.UserRole).toString()) From 90c631ce87a195b54537276cbd2416c2dca72ca9 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 27 Nov 2010 15:25:00 +0000 Subject: [PATCH 06/18] Documentation fixups and \nstart to add OpenlLyrics export for songs --- documentation/manual/source/songusage.rst | 32 +++++---- openlp/core/lib/mediamanageritem.py | 10 +-- openlp/core/lib/serviceitem.py | 6 +- openlp/plugins/bibles/lib/mediaitem.py | 2 +- openlp/plugins/custom/lib/mediaitem.py | 2 +- openlp/plugins/images/lib/mediaitem.py | 2 +- openlp/plugins/media/lib/mediaitem.py | 2 +- openlp/plugins/presentations/lib/mediaitem.py | 10 +-- openlp/plugins/songs/lib/__init__.py | 3 +- openlp/plugins/songs/lib/mediaitem.py | 24 +++++-- openlp/plugins/songs/lib/xml.py | 69 ++++++++++++++++++- 11 files changed, 123 insertions(+), 39 deletions(-) diff --git a/documentation/manual/source/songusage.rst b/documentation/manual/source/songusage.rst index df6d930f3..6e439ce6c 100644 --- a/documentation/manual/source/songusage.rst +++ b/documentation/manual/source/songusage.rst @@ -5,18 +5,30 @@ Song Usage The Songusage plugin records the usage of Songs when they are used in a **Live** situation. If the plugin is active all songs sent to the Live Service Manager are recorded by this plugin. Once the plugin has been activated by the plugin -menu it can be turned on and off by use of the``F4`` key or the SongUsage menus. +menu it can be turned on and off by use of the :guilabel:`F4` key or the +SongUsage menus. The image below shows the menu items and how to access them. .. image:: pics/songusage.png +Delete Tracking Data +^^^^^^^^^^^^^^^^^^^^ +This option allows the removal of stored data use is no longer required. +Select the date you wish to remove data up to and press :guilabel:`Ok`. + +This option is not reversable. + +.. image:: pics/songusagedelete.png + +Extract Tracking Data +^^^^^^^^^^^^^^^^^^^^^ +This option allows reports to be generated between any two dates. + +The system automatically defaults to dates between the 1st September last year +and 31st August this year. The data is written to a file in the selected +directory. -Generating reports ------------------- -This option allows reports to be generated between any two dates. The system -automatically defaults to dates between the 1st September last year and 31st -August this year. The data is written to a file in a selectable directory. The file name is **usage_detail_fromdate_todate.txt**. .. image:: pics/songusagereport.png @@ -27,11 +39,3 @@ The details extracted are: - Song Title - Song Copyright - Song CCLI. - -Removing data -------------- -This option allows the removal of stored data use is no longer required. -Select the date you wish to remove data up to and press``Ok``. This option is -not reversable. - -.. image:: pics/songusagedelete.png diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 749543fd9..58b69bf83 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -420,7 +420,7 @@ class MediaManagerItem(QtGui.QWidget): raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to ' u'be defined by the plugin') - def generateSlideData(self, service_item, item=None): + def generateSlideData(self, service_item, item=None, xmlVersion=False): raise NotImplementedError(u'MediaManagerItem.generateSlideData needs ' u'to be defined by the plugin') @@ -482,7 +482,7 @@ class MediaManagerItem(QtGui.QWidget): # service items? if self.singleServiceItem or self.remoteTriggered: log.debug(self.plugin.name + u' Add requested') - service_item = self.buildServiceItem() + service_item = self.buildServiceItem(None, True) if service_item: service_item.from_plugin = False self.parent.serviceManager.addServiceItem(service_item, @@ -490,7 +490,7 @@ class MediaManagerItem(QtGui.QWidget): else: items = self.listView.selectedIndexes() for item in items: - service_item = self.buildServiceItem(item) + service_item = self.buildServiceItem(item, True) if service_item: service_item.from_plugin = False self.parent.serviceManager.addServiceItem(service_item) @@ -525,7 +525,7 @@ class MediaManagerItem(QtGui.QWidget): unicode(translate('OpenLP.MediaManagerItem', 'You must select a %s service item.')) % self.title) - def buildServiceItem(self, item=None): + def buildServiceItem(self, item=None, xmlVersion=False): """ Common method for generating a service item """ @@ -534,7 +534,7 @@ class MediaManagerItem(QtGui.QWidget): service_item.add_icon(self.serviceItemIconName) else: service_item.add_icon(self.parent.icon_path) - if self.generateSlideData(service_item, item): + if self.generateSlideData(service_item, item, xmlVersion): return service_item else: return None diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 0cbc34de5..585a89276 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -101,6 +101,7 @@ class ServiceItem(object): self.search_string = u'' self.data_string = u'' self.edit_id = None + self.xml_version = None self._new_item() def _new_item(self): @@ -252,7 +253,8 @@ class ServiceItem(object): u'from_plugin': self.from_plugin, u'capabilities': self.capabilities, u'search': self.search_string, - u'data': self.data_string + u'data': self.data_string, + u'xmlVersion': self.xml_version } service_data = [] if self.service_item_type == ServiceItemType.Text: @@ -294,6 +296,8 @@ class ServiceItem(object): if u'search' in header: self.search_string = header[u'search'] self.data_string = header[u'data'] + if u'xmlVersion' in header: + self.xml_version = header[u'xmlVersion'] if self.service_item_type == ServiceItemType.Text: for slide in serviceitem[u'serviceitem'][u'data']: self._raw_frames.append(slide) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index bb3c1b26d..25edb4926 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -651,7 +651,7 @@ class BibleMediaItem(MediaManagerItem): obj = obj.toPyObject() return unicode(obj) - def generateSlideData(self, service_item, item=None): + def generateSlideData(self, service_item, item=None, xmlVersion=False): """ Generates and formats the slides for the service item as well as the service item's title. diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 8549e6449..83a43fba8 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -144,7 +144,7 @@ class CustomMediaItem(MediaManagerItem): for row in row_list: self.listView.takeItem(row) - def generateSlideData(self, service_item, item=None): + def generateSlideData(self, service_item, item=None, xmlVersion=False): raw_slides = [] raw_footer = [] slide = None diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 7394758c3..4f1e9378e 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -154,7 +154,7 @@ class ImageMediaItem(MediaManagerItem): item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) self.listView.addItem(item_name) - def generateSlideData(self, service_item, item=None): + def generateSlideData(self, service_item, item=None, xmlVersion=False): items = self.listView.selectedIndexes() if items: service_item.title = unicode( diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 030f67153..11e00628e 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -116,7 +116,7 @@ class MediaMediaItem(MediaManagerItem): self.parent.liveController.display.video(filename, 0, True) self.resetButton.setVisible(True) - def generateSlideData(self, service_item, item=None): + def generateSlideData(self, service_item, item=None, xmlVersion=False): if item is None: item = self.listView.currentItem() if item is None: diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index e6f456e5c..8e3a2fc36 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -38,7 +38,7 @@ log = logging.getLogger(__name__) class PresentationListView(BaseListWithDnD): """ Class for the list of Presentations - + We have to explicitly create separate classes for each plugin in order for DnD to the Service manager to work correctly. """ @@ -67,7 +67,7 @@ class PresentationMediaItem(MediaManagerItem): self.message_listener = MessageListener(self) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild) - + def retranslateUi(self): """ The name of the plugin media displayed in UI @@ -159,7 +159,7 @@ class PresentationMediaItem(MediaManagerItem): if self.DisplayTypeComboBox.count() > 1: self.DisplayTypeComboBox.insertItem(0, self.Automatic) self.DisplayTypeComboBox.setCurrentIndex(0) - if QtCore.QSettings().value(self.settingsSection + u'/override app', + if QtCore.QSettings().value(self.settingsSection + u'/override app', QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: self.PresentationWidget.show() else: @@ -238,7 +238,7 @@ class PresentationMediaItem(MediaManagerItem): SettingsManager.set_list(self.settingsSection, self.settingsSection, self.getFileList()) - def generateSlideData(self, service_item, item=None): + def generateSlideData(self, service_item, item=None, xmlVersion=False): """ Load the relevant information for displaying the presentation in the slidecontroller. In the case of powerpoints, an image @@ -277,7 +277,7 @@ class PresentationMediaItem(MediaManagerItem): def findControllerByType(self, filename): """ Determine the default application controller to use for the selected - file type. This is used if "Automatic" is set as the preferred + file type. This is used if "Automatic" is set as the preferred controller. Find the first (alphabetic) enabled controller which "supports" the extension. If none found, then look for a controller which "alsosupports" it instead. diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index 351d50071..bb9c6ebf9 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -92,7 +92,6 @@ class VerseType(object): unicode(VerseType.to_string(VerseType.Other)).lower(): return VerseType.Other - -from xml import LyricsXML, SongXMLBuilder, SongXMLParser +from xml import LyricsXML, SongXMLBuilder, SongXMLParser, OpenLyricsParser from songstab import SongsTab from mediaitem import SongMediaItem diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index cb2d6a6e0..546751a48 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -32,7 +32,7 @@ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \ ItemCapabilities, translate, check_item_selected from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ SongImportForm -from openlp.plugins.songs.lib import SongXMLParser +from openlp.plugins.songs.lib import SongXMLParser, OpenLyricsParser from openlp.plugins.songs.lib.db import Author, Song log = logging.getLogger(__name__) @@ -54,7 +54,6 @@ class SongMediaItem(MediaManagerItem): MediaManagerItem.__init__(self, parent, self, icon) self.edit_song_form = EditSongForm(self, self.parent.manager) self.singleServiceItem = False - #self.edit_song_form = EditSongForm(self.parent.manager, self) self.song_maintenance_form = SongMaintenanceForm( self.parent.manager, self) # Holds information about whether the edit is remotly triggered and @@ -141,7 +140,7 @@ class SongMediaItem(MediaManagerItem): self.updateServiceOnEdit = QtCore.QSettings().value( self.settingsSection + u'/update service on edit', QtCore.QVariant(u'False')).toBool() - self.AddSongFromServide = QtCore.QSettings().value( + self.addSongFromService = QtCore.QSettings().value( self.settingsSection + u'/add song from service', QtCore.QVariant(u'True')).toBool() @@ -328,7 +327,7 @@ class SongMediaItem(MediaManagerItem): self.parent.manager.delete_object(Song, item_id) self.onSearchTextButtonClick() - def generateSlideData(self, service_item, item=None): + def generateSlideData(self, service_item, item=None, xmlVersion=False): log.debug(u'generateSlideData (%s:%s)' % (service_item, item)) raw_footer = [] author_list = u'' @@ -355,7 +354,7 @@ class SongMediaItem(MediaManagerItem): if song.lyrics.startswith(u'' + \ u'%s' % lyrics_output return song_output + +class OpenLyricsParser(object): + """ + This class represents the converter for Song to/from OpenLyrics XML. + """ + def songToXml(self, song): + """ + Convert the song to OpenLyrics Format + """ + songXML = SongXMLParser(song.lyrics) + verseList = songXML.get_verses() + song_xml = objectify.fromstring( + u'') + properties = etree.SubElement(song_xml, u'properties') + titles = etree.SubElement(properties, u'titles') + self.add_text_to_element(u'title', titles, song.title) + if song.alternate_title: + self.add_text_to_element(u'title', titles, song.alternate_title) + if song.theme_name: + themes = etree.SubElement(properties, u'themes') + self.add_text_to_element(u'theme', themes, song.theme_name) + self.add_text_to_element(u'copyright', properties, song.copyright) + self.add_text_to_element(u'verseOrder', properties, song.verse_order) + if song.ccli_number: + self.add_text_to_element(u'ccliNo', properties, song.ccli_number) + authors = etree.SubElement(properties, u'authors') + for author in song.authors: + self.add_text_to_element(u'author', authors, author.display_name) + lyrics = etree.SubElement(song_xml, u'lyrics') + for verse in verseList: + verseTag = u'%s%s' % ( + verse[0][u'type'][0].lower(), verse[0][u'label']) + element = self.add_text_to_element(u'verse', lyrics, None, verseTag) + element = self.add_text_to_element(u'lines', element) + for line in unicode(verse[1]).split(u'\n'): + self.add_text_to_element(u'line', element, line) + #print self.dump_xml(song_xml) + return u'' #self.extract_xml(song_xml) + + def add_text_to_element(self, tag, parent, text=None, label=None): + if label: + element = etree.Element(tag, name = unicode(label)) + else: + element = etree.Element(tag) + if text: + element.text = unicode(text) + parent.append(element) + return element + + def xmlToSong(self, xml): + """ + Create a Song from OpenLyrics format xml + """ + return 0 + + def dump_xml(self, xml): + """ + Debugging aid to dump XML so that we can see what we have. + """ + return etree.tostring(xml, encoding=u'UTF-8', + xml_declaration=True, pretty_print=True) + + def extract_xml(self, xml): + """ + Extract our newly created XML song. + """ + return etree.tostring(xml, encoding=u'UTF-8', + xml_declaration=True) From 326580559a198516328092fcc6bac54926f07fb1 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 27 Nov 2010 16:22:23 +0000 Subject: [PATCH 07/18] Remove documenation for now --- documentation/manual/source/index.rst | 1 - documentation/manual/source/songusage.rst | 41 ----------------------- 2 files changed, 42 deletions(-) delete mode 100644 documentation/manual/source/songusage.rst diff --git a/documentation/manual/source/index.rst b/documentation/manual/source/index.rst index 5228256cf..ac29c4360 100644 --- a/documentation/manual/source/index.rst +++ b/documentation/manual/source/index.rst @@ -14,7 +14,6 @@ Contents: introduction glossary dualmonitors - songusage Indices and tables ================== diff --git a/documentation/manual/source/songusage.rst b/documentation/manual/source/songusage.rst deleted file mode 100644 index 6e439ce6c..000000000 --- a/documentation/manual/source/songusage.rst +++ /dev/null @@ -1,41 +0,0 @@ -========== -Song Usage -========== - -The Songusage plugin records the usage of Songs when they are used in a **Live** -situation. If the plugin is active all songs sent to the Live Service Manager -are recorded by this plugin. Once the plugin has been activated by the plugin -menu it can be turned on and off by use of the :guilabel:`F4` key or the -SongUsage menus. - -The image below shows the menu items and how to access them. - -.. image:: pics/songusage.png - -Delete Tracking Data -^^^^^^^^^^^^^^^^^^^^ -This option allows the removal of stored data use is no longer required. -Select the date you wish to remove data up to and press :guilabel:`Ok`. - -This option is not reversable. - -.. image:: pics/songusagedelete.png - -Extract Tracking Data -^^^^^^^^^^^^^^^^^^^^^ -This option allows reports to be generated between any two dates. - -The system automatically defaults to dates between the 1st September last year -and 31st August this year. The data is written to a file in the selected -directory. - -The file name is **usage_detail_fromdate_todate.txt**. - -.. image:: pics/songusagereport.png - -The details extracted are: - - Date item used - - Time item used - - Song Title - - Song Copyright - - Song CCLI. From 1cf49148620916f7c8c83ffba33cc3891fd89b85 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 27 Nov 2010 20:51:54 +0000 Subject: [PATCH 08/18] fixes from last merge and more code for song management --- openlp/core/lib/mediamanageritem.py | 54 +++++++++++----------- openlp/core/lib/serviceitem.py | 6 +-- openlp/core/ui/maindisplay.py | 14 +++--- openlp/plugins/bibles/lib/mediaitem.py | 2 +- openlp/plugins/songs/forms/editsongform.py | 7 ++- openlp/plugins/songs/lib/mediaitem.py | 2 +- openlp/plugins/songs/lib/xml.py | 40 ++++++++++++++-- 7 files changed, 81 insertions(+), 44 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 58b69bf83..03ecba088 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -420,7 +420,7 @@ class MediaManagerItem(QtGui.QWidget): raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to ' u'be defined by the plugin') - def generateSlideData(self, service_item, item=None, xmlVersion=False): + def generateSlideData(self, serviceItem, item=None, xmlVersion=False): raise NotImplementedError(u'MediaManagerItem.generateSlideData needs ' u'to be defined by the plugin') @@ -446,10 +446,10 @@ class MediaManagerItem(QtGui.QWidget): 'You must select one or more items to preview.')) else: log.debug(self.plugin.name + u' Preview requested') - service_item = self.buildServiceItem() - if service_item: - service_item.from_plugin = True - self.parent.previewController.addServiceItem(service_item) + serviceItem = self.buildServiceItem() + if serviceItem: + serviceItem.from_plugin = True + self.parent.previewController.addServiceItem(serviceItem) def onLiveClick(self): """ @@ -463,10 +463,10 @@ class MediaManagerItem(QtGui.QWidget): 'You must select one or more items to send live.')) else: log.debug(self.plugin.name + u' Live requested') - service_item = self.buildServiceItem() - if service_item: - service_item.from_plugin = True - self.parent.liveController.addServiceItem(service_item) + serviceItem = self.buildServiceItem() + if serviceItem: + serviceItem.from_plugin = True + self.parent.liveController.addServiceItem(serviceItem) def onAddClick(self): """ @@ -482,18 +482,18 @@ class MediaManagerItem(QtGui.QWidget): # service items? if self.singleServiceItem or self.remoteTriggered: log.debug(self.plugin.name + u' Add requested') - service_item = self.buildServiceItem(None, True) - if service_item: - service_item.from_plugin = False - self.parent.serviceManager.addServiceItem(service_item, + serviceItem = self.buildServiceItem(None, True) + if serviceItem: + serviceItem.from_plugin = False + self.parent.serviceManager.addServiceItem(serviceItem, replace=self.remoteTriggered) else: items = self.listView.selectedIndexes() for item in items: - service_item = self.buildServiceItem(item, True) - if service_item: - service_item.from_plugin = False - self.parent.serviceManager.addServiceItem(service_item) + serviceItem = self.buildServiceItem(item, True) + if serviceItem: + serviceItem.from_plugin = False + self.parent.serviceManager.addServiceItem(serviceItem) def onAddEditClick(self): """ @@ -506,16 +506,16 @@ class MediaManagerItem(QtGui.QWidget): 'You must select one or more items')) else: log.debug(self.plugin.name + u' Add requested') - service_item = self.parent.serviceManager.getServiceItem() - if not service_item: + serviceItem = self.parent.serviceManager.getServiceItem() + if not serviceItem: QtGui.QMessageBox.information(self, translate('OpenLP.MediaManagerItem', 'No Service Item Selected'), translate('OpenLP.MediaManagerItem', 'You must select an existing service item to add to.')) - elif self.title.lower() == service_item.name.lower(): - self.generateSlideData(service_item) - self.parent.serviceManager.addServiceItem(service_item, + elif self.title.lower() == serviceItem.name.lower(): + self.generateSlideData(serviceItem) + self.parent.serviceManager.addServiceItem(serviceItem, replace=True) else: # Turn off the remote edit update message indicator @@ -529,13 +529,13 @@ class MediaManagerItem(QtGui.QWidget): """ Common method for generating a service item """ - service_item = ServiceItem(self.parent) + serviceItem = ServiceItem(self.parent) if self.serviceItemIconName: - service_item.add_icon(self.serviceItemIconName) + serviceItem.add_icon(self.serviceItemIconName) else: - service_item.add_icon(self.parent.icon_path) - if self.generateSlideData(service_item, item, xmlVersion): - return service_item + serviceItem.add_icon(self.parent.icon_path) + if self.generateSlideData(serviceItem, item, xmlVersion): + return serviceItem else: return None diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 585a89276..b9394030a 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -254,7 +254,7 @@ class ServiceItem(object): u'capabilities': self.capabilities, u'search': self.search_string, u'data': self.data_string, - u'xmlVersion': self.xml_version + u'xml_version': self.xml_version } service_data = [] if self.service_item_type == ServiceItemType.Text: @@ -296,8 +296,8 @@ class ServiceItem(object): if u'search' in header: self.search_string = header[u'search'] self.data_string = header[u'data'] - if u'xmlVersion' in header: - self.xml_version = header[u'xmlVersion'] + if u'xml_version' in header: + self.xml_version = header[u'xml_version'] if self.service_item_type == ServiceItemType.Text: for slide in serviceitem[u'serviceitem'][u'data']: self._raw_frames.append(slide) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 9d6c04075..90f920a50 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -100,7 +100,7 @@ class MainDisplay(DisplayWidget): self.screens = screens self.isLive = live self.alertTab = None - self.hide_mode = None + self.hideMode = None self.setWindowTitle(u'OpenLP Display') self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;') self.setWindowFlags(QtCore.Qt.FramelessWindowHint | @@ -381,8 +381,8 @@ class MainDisplay(DisplayWidget): if self.isLive: self.setVisible(True) # if was hidden keep it hidden - if self.hide_mode and self.isLive: - self.hideDisplay(self.hide_mode) + if self.hideMode and self.isLive: + self.hideDisplay(self.hideMode) preview = QtGui.QImage(self.screen[u'size'].width(), self.screen[u'size'].height(), QtGui.QImage.Format_ARGB32_Premultiplied) @@ -412,8 +412,8 @@ class MainDisplay(DisplayWidget): if serviceItem.foot_text and serviceItem.foot_text: self.footer(serviceItem.foot_text) # if was hidden keep it hidden - if self.hide_mode and self.isLive: - self.hideDisplay(self.hide_mode) + if self.hideMode and self.isLive: + self.hideDisplay(self.hideMode) def footer(self, text): """ @@ -444,7 +444,7 @@ class MainDisplay(DisplayWidget): self.setVisible(True) if self.phononActive: self.webView.setVisible(True) - self.hide_mode = mode + self.hideMode = mode def showDisplay(self): """ @@ -459,7 +459,7 @@ class MainDisplay(DisplayWidget): if self.phononActive: self.webView.setVisible(False) self.videoPlay() - self.hide_mode = None + self.hideMode = None # Trigger actions when display is active again Receiver.send_message(u'maindisplay_active') diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 25edb4926..0e1850485 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -545,7 +545,7 @@ class BibleMediaItem(MediaManagerItem): self.dual_search_results = self.parent.manager.get_verses( dual_bible, text) else: - # We are doing a ' Text Search'. + # We are doing a 'Text Search'. bibles = self.parent.manager.get_bibles() self.search_results = self.parent.manager.verse_search(bible, text) if dual_bible and self.search_results: diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 241c6fd95..8c92583d5 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -630,7 +630,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): Get all the data from the widgets on the form, and then save it to the database. - ``preview`` + ``preview`` Should be True if song is also previewed. """ self.song.title = unicode(self.TitleEditItem.text()) @@ -648,6 +648,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): Book.name == book_name) else: self.song.book = None + theme_name = unicode(self.ThemeSelectionComboItem.currentText()) + if theme_name: + self.song.theme_name = theme_name + else: + self.song.theme_name = None if self._validate_song(): self.processLyrics() self.processTitle() diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 546751a48..3441aed86 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -396,7 +396,7 @@ class SongMediaItem(MediaManagerItem): ] service_item.data_string = {u'title':song.search_title, u'authors':author_list} - service_item.xml_version = OpenLyricsParser().songToXml(song) + service_item.xml_version = OpenLyricsParser().song_to_xml(song) return True def serviceLoad(self, item): diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 782a86bfa..bdd8478d4 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -41,6 +41,7 @@ The basic XML is of the format:: import logging from lxml import etree, objectify +from openlp.plugins.songs.lib.db import Author, Song log = logging.getLogger(__name__) @@ -97,6 +98,7 @@ class SongXMLBuilder(object): return etree.tostring(self.song_xml, encoding=u'UTF-8', xml_declaration=True) + class SongXMLParser(object): """ A class to read in and parse a song's XML. @@ -239,11 +241,12 @@ class LyricsXML(object): u'%s' % lyrics_output return song_output + class OpenLyricsParser(object): """ This class represents the converter for Song to/from OpenLyrics XML. """ - def songToXml(self, song): + def song_to_xml(self, song): """ Convert the song to OpenLyrics Format """ @@ -274,8 +277,8 @@ class OpenLyricsParser(object): element = self.add_text_to_element(u'lines', element) for line in unicode(verse[1]).split(u'\n'): self.add_text_to_element(u'line', element, line) - #print self.dump_xml(song_xml) - return u'' #self.extract_xml(song_xml) + self.xml_to_song(self.extract_xml(song_xml)) + return u'' #self.xml_to_song(self.extract_xml(song_xml)) def add_text_to_element(self, tag, parent, text=None, label=None): if label: @@ -287,11 +290,40 @@ class OpenLyricsParser(object): parent.append(element) return element - def xmlToSong(self, xml): + def xml_to_song(self, xml): """ Create a Song from OpenLyrics format xml """ return 0 + song = Song() + if xml[:5] == u' Date: Sun, 28 Nov 2010 13:39:51 +0000 Subject: [PATCH 09/18] Song rebuilding continues --- openlp/plugins/songs/lib/mediaitem.py | 7 +- openlp/plugins/songs/lib/xml.py | 143 +++++++++++++++++--------- 2 files changed, 97 insertions(+), 53 deletions(-) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 3441aed86..0d5572d1e 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -53,6 +53,7 @@ class SongMediaItem(MediaManagerItem): self.ListViewWithDnD_class = SongListView MediaManagerItem.__init__(self, parent, self, icon) self.edit_song_form = EditSongForm(self, self.parent.manager) + self.openLyrics = OpenLyricsParser(self.parent.manager) self.singleServiceItem = False self.song_maintenance_form = SongMaintenanceForm( self.parent.manager, self) @@ -396,7 +397,7 @@ class SongMediaItem(MediaManagerItem): ] service_item.data_string = {u'title':song.search_title, u'authors':author_list} - service_item.xml_version = OpenLyricsParser().song_to_xml(song) + service_item.xml_version = self.openLyrics.song_to_xml(song) return True def serviceLoad(self, item): @@ -424,12 +425,12 @@ class SongMediaItem(MediaManagerItem): else: # Authors different if self.addSongFromService: - editId = OpenLyricsParser(). \ + editId = self.openLyrics. \ xmlToSong(item.xml_version) else: # Title does not match if self.addSongFromService: - editId = OpenLyricsParser().xmlToSong(item.xml_version) + editId = self.openLyrics.xmlToSong(item.xml_version) # Update service with correct song id if editId != 0: Receiver.send_message(u'service_item_update', diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index bdd8478d4..03b672928 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -39,6 +39,7 @@ The basic XML is of the format:: """ import logging +import re from lxml import etree, objectify from openlp.plugins.songs.lib.db import Author, Song @@ -246,6 +247,9 @@ class OpenLyricsParser(object): """ This class represents the converter for Song to/from OpenLyrics XML. """ + def __init__(self, manager): + self.manager = manager + def song_to_xml(self, song): """ Convert the song to OpenLyrics Format @@ -256,31 +260,87 @@ class OpenLyricsParser(object): u'') properties = etree.SubElement(song_xml, u'properties') titles = etree.SubElement(properties, u'titles') - self.add_text_to_element(u'title', titles, song.title) + self._add_text_to_element(u'title', titles, song.title) if song.alternate_title: - self.add_text_to_element(u'title', titles, song.alternate_title) + self._add_text_to_element(u'title', titles, song.alternate_title) if song.theme_name: themes = etree.SubElement(properties, u'themes') - self.add_text_to_element(u'theme', themes, song.theme_name) - self.add_text_to_element(u'copyright', properties, song.copyright) - self.add_text_to_element(u'verseOrder', properties, song.verse_order) + self._add_text_to_element(u'theme', themes, song.theme_name) + self._add_text_to_element(u'copyright', properties, song.copyright) + self._add_text_to_element(u'verseOrder', properties, song.verse_order) if song.ccli_number: - self.add_text_to_element(u'ccliNo', properties, song.ccli_number) + self._add_text_to_element(u'ccliNo', properties, song.ccli_number) authors = etree.SubElement(properties, u'authors') for author in song.authors: - self.add_text_to_element(u'author', authors, author.display_name) + self._add_text_to_element(u'author', authors, author.display_name) lyrics = etree.SubElement(song_xml, u'lyrics') for verse in verseList: verseTag = u'%s%s' % ( verse[0][u'type'][0].lower(), verse[0][u'label']) - element = self.add_text_to_element(u'verse', lyrics, None, verseTag) - element = self.add_text_to_element(u'lines', element) + element = self._add_text_to_element(u'verse', lyrics, None, verseTag) + element = self._add_text_to_element(u'lines', element) for line in unicode(verse[1]).split(u'\n'): - self.add_text_to_element(u'line', element, line) - self.xml_to_song(self.extract_xml(song_xml)) - return u'' #self.xml_to_song(self.extract_xml(song_xml)) + self._add_text_to_element(u'line', element, line) + print self._dump_xml(song_xml) + self.xml_to_song(self._extract_xml(song_xml)) + return u'' #self.xml_to_song(self._extract_xml(song_xml)) - def add_text_to_element(self, tag, parent, text=None, label=None): + def xml_to_song(self, xml): + """ + Create a Song from OpenLyrics format xml + """ + song = Song() + if xml[:5] == u' Date: Sun, 28 Nov 2010 13:41:52 +0000 Subject: [PATCH 10/18] Fix DnD bug --- openlp/core/ui/servicemanager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index f294cedd4..454819f32 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -1028,6 +1028,9 @@ class ServiceManager(QtGui.QWidget): # ServiceManager started the drag and drop if plugin == u'ServiceManager': startpos, startCount = self.findServiceItem() + # If no items selected + if startpos == -1: + return if item is None: endpos = len(self.serviceItems) else: From 9fa384b57f988f695820caed6f424af7ade20221 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 28 Nov 2010 14:40:46 +0000 Subject: [PATCH 11/18] More changes --- openlp/plugins/songs/lib/xml.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 03b672928..5cfa8603b 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -317,9 +317,7 @@ class OpenLyricsParser(object): unicode(song.search_title)).lower() # Process Authors for author in properties.authors.author: - print author, author.text - #song.authors.append(self._process_author(author.text)) - print "here" + self._process_author(author.text, song) # Process Lyrics sxml = SongXMLBuilder() search_text = u'' @@ -327,16 +325,18 @@ class OpenLyricsParser(object): for verse in song_xml.lyrics.verse: print "verse", verse.attrib text = u'' - for line in lyrics.verse.lines.line: + for line in verse.lines.line: line = unicode(line) if not text: text = line else: text += u'\n' + line - sxml.add_verse_to_lyrics(u'V', verse.attrib, text) + sxml.add_verse_to_lyrics(u'V', verse.attrib[u'name'], text) search_text = search_text + text song.search_lyrics = search_text.lower() song.lyrics = unicode(sxml.extract_xml(), u'utf-8') + song.comments = u'' + song.song_number = u'' self.manager.save_object(song) return 0 @@ -364,7 +364,7 @@ class OpenLyricsParser(object): return etree.tostring(xml, encoding=u'UTF-8', xml_declaration=True) - def _process_author(self, name): + def _process_author(self, name, song): """ Find or create an Author from display_name. """ @@ -374,10 +374,10 @@ class OpenLyricsParser(object): Author.display_name == name) if search_results: # should only be one! so take the first - return search_results[0] + song.authors.append(search_results[0]) else: # Need a new author new_author = Author.populate(first_name=name.rsplit(u' ', 1)[0], last_name=name.rsplit(u' ', 1)[1], display_name=name) self.manager.save_object(new_author) - return author + song.authors.append(new_author) From 132c67856939276238e26ebd60db60235cc3fcdb Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 28 Nov 2010 15:20:53 +0000 Subject: [PATCH 12/18] Fix exit for non Sqlite Databases --- openlp/core/lib/db.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 0dc138abc..8afa02111 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -294,4 +294,5 @@ class Manager(object): """ if self.is_dirty: engine = create_engine(self.db_url) - engine.execute("vacuum") + if self.db_url.startswith(u'sqlite'): + engine.execute("vacuum") From e2ac8b6dcc50139ebc5b5b96499e993945f396c8 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 28 Nov 2010 16:48:36 +0000 Subject: [PATCH 13/18] More code fixes --- openlp/plugins/songs/lib/xml.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 5cfa8603b..a12bdc24c 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -79,7 +79,6 @@ class SongXMLBuilder(object): ``content`` The actual text of the verse to be stored. """ - # log.debug(u'add_verse_to_lyrics %s, %s\n%s' % (type, number, content)) verse = etree.Element(u'verse', type = unicode(type), label = unicode(number)) verse.text = etree.CDATA(content) @@ -368,13 +367,12 @@ class OpenLyricsParser(object): """ Find or create an Author from display_name. """ - print "name = ", name name = unicode(name) - search_results = self.manager.get_all_objects(Author, + author = self.manager.get_object_filtered(Author, Author.display_name == name) - if search_results: + if author: # should only be one! so take the first - song.authors.append(search_results[0]) + song.authors.append(author) else: # Need a new author new_author = Author.populate(first_name=name.rsplit(u' ', 1)[0], From 6ecc121bdfc5998db261e90e1adf9c5464fc0296 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 28 Nov 2010 19:38:27 +0000 Subject: [PATCH 14/18] Convert verse tags --- openlp/core/lib/mediamanageritem.py | 4 ++-- openlp/plugins/songs/lib/__init__.py | 30 +++++++++++++++++++++++++++ openlp/plugins/songs/lib/mediaitem.py | 1 + openlp/plugins/songs/lib/xml.py | 4 +++- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 03ecba088..130da0c0e 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -478,8 +478,8 @@ class MediaManagerItem(QtGui.QWidget): translate('OpenLP.MediaManagerItem', 'You must select one or more items.')) else: - # Is it posssible to process multiple list items to generate multiple - # service items? + # Is it posssible to process multiple list items to generate + # multiple service items? if self.singleServiceItem or self.remoteTriggered: log.debug(self.plugin.name + u' Add requested') serviceItem = self.buildServiceItem(None, True) diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index bb9c6ebf9..795116b4e 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -62,6 +62,36 @@ class VerseType(object): elif verse_type == VerseType.Other: return translate('SongsPlugin.VerseType', 'Other') + @staticmethod + def expand_string(verse_type): + """ + Return the VerseType for a given string + + ``verse_type`` + The string to return a VerseType for + """ + verse_type = verse_type.lower() + if verse_type == unicode(VerseType.to_string(VerseType.Verse)).lower()[0]: + return translate('SongsPlugin.VerseType', 'Verse') + elif verse_type == \ + unicode(VerseType.to_string(VerseType.Chorus)).lower()[0]: + return translate('SongsPlugin.VerseType', 'Chorus') + elif verse_type == \ + unicode(VerseType.to_string(VerseType.Bridge)).lower()[0]: + return translate('SongsPlugin.VerseType', 'Bridge') + elif verse_type == \ + unicode(VerseType.to_string(VerseType.PreChorus)).lower()[0]: + return translate('SongsPlugin.VerseType', 'PreChorus') + elif verse_type == \ + unicode(VerseType.to_string(VerseType.Intro)).lower()[0]: + return translate('SongsPlugin.VerseType', 'Intro') + elif verse_type == \ + unicode(VerseType.to_string(VerseType.Ending)).lower()[0]: + return translate('SongsPlugin.VerseType', 'Ending') + elif verse_type == \ + unicode(VerseType.to_string(VerseType.Other)).lower()[0]: + return translate('SongsPlugin.VerseType', 'Other') + @staticmethod def from_string(verse_type): """ diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 0d5572d1e..2ffa096a6 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -397,6 +397,7 @@ class SongMediaItem(MediaManagerItem): ] service_item.data_string = {u'title':song.search_title, u'authors':author_list} + # if xmlVersion: service_item.xml_version = self.openLyrics.song_to_xml(song) return True diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index a12bdc24c..910fb6549 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -42,6 +42,7 @@ import logging import re from lxml import etree, objectify +from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib.db import Author, Song log = logging.getLogger(__name__) @@ -330,7 +331,8 @@ class OpenLyricsParser(object): text = line else: text += u'\n' + line - sxml.add_verse_to_lyrics(u'V', verse.attrib[u'name'], text) + type = VerseType.expand_string(verse.attrib[u'name'][0]) + sxml.add_verse_to_lyrics(type, verse.attrib[u'name'][1], text) search_text = search_text + text song.search_lyrics = search_text.lower() song.lyrics = unicode(sxml.extract_xml(), u'utf-8') From 5decd5c4661f6860fa54e508ddfafbec966d4e3c Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 29 Nov 2010 07:32:08 +0000 Subject: [PATCH 15/18] Cleanups and fixes --- openlp/plugins/custom/forms/editcustomform.py | 6 +++--- openlp/plugins/custom/forms/editcustomslideform.py | 4 ++-- openlp/plugins/custom/lib/customxmlhandler.py | 11 ++++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 65a73337a..c5281574b 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -46,7 +46,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): Constructor """ QtGui.QDialog.__init__(self, parent) - #self.parent = parent self.setupUi(self) # Connecting signals and slots self.previewButton = QtGui.QPushButton() @@ -124,8 +123,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): 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 # Not Found + id = 0 self.themeComboBox.setCurrentIndex(id) else: self.themeComboBox.setCurrentIndex(0) @@ -264,7 +264,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): self.titleEdit.setFocus() return False, translate('CustomPlugin.EditCustomForm', 'You need to type in a title.') - # We must have one slide. + # We must have at least one slide. if self.slideListView.count() == 0: return False, translate('CustomPlugin.EditCustomForm', 'You need to add at least one slide') diff --git a/openlp/plugins/custom/forms/editcustomslideform.py b/openlp/plugins/custom/forms/editcustomslideform.py index 5f535c8bc..72c7dbb4a 100644 --- a/openlp/plugins/custom/forms/editcustomslideform.py +++ b/openlp/plugins/custom/forms/editcustomslideform.py @@ -50,7 +50,7 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog): def setText(self, text): """ Set the text for slideTextEdit. - + ``text`` The text (unicode). """ @@ -67,7 +67,7 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog): def onSplitButtonPressed(self): """ - Splits a slide in two slides. + Adds a slide split at the cursor. """ if self.slideTextEdit.textCursor().columnNumber() != 0: self.slideTextEdit.insertPlainText(u'\n') diff --git a/openlp/plugins/custom/lib/customxmlhandler.py b/openlp/plugins/custom/lib/customxmlhandler.py index b554f9657..987163aa3 100644 --- a/openlp/plugins/custom/lib/customxmlhandler.py +++ b/openlp/plugins/custom/lib/customxmlhandler.py @@ -43,6 +43,7 @@ import logging from xml.dom.minidom import Document from xml.etree.ElementTree import ElementTree, XML, dump +from lxml import etree, objectify from xml.parsers.expat import ExpatError log = logging.getLogger(__name__) @@ -129,10 +130,11 @@ class CustomXMLParser(object): The XML of the song to be parsed. """ self.custom_xml = None + if xml[:5] == u' Date: Mon, 29 Nov 2010 14:04:37 +0000 Subject: [PATCH 16/18] Songs get built correctly --- openlp/plugins/custom/lib/customxmlhandler.py | 19 ++++--- openlp/plugins/custom/lib/mediaitem.py | 6 +-- openlp/plugins/songs/lib/xml.py | 50 +++++++++---------- 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/openlp/plugins/custom/lib/customxmlhandler.py b/openlp/plugins/custom/lib/customxmlhandler.py index 987163aa3..907c3470d 100644 --- a/openlp/plugins/custom/lib/customxmlhandler.py +++ b/openlp/plugins/custom/lib/customxmlhandler.py @@ -56,14 +56,14 @@ class CustomXMLBuilder(object): def __init__(self): """ - Set up the song builder. + Set up the custom builder. """ # Create the minidom document self.custom_xml = Document() def new_document(self): """ - Create a new song XML document. + Create a new custom XML document. """ # Create the base element self.song = self.custom_xml.createElement(u'song') @@ -73,7 +73,7 @@ class CustomXMLBuilder(object): def add_lyrics_to_song(self): """ Set up and add a ```` tag which contains the lyrics of the - song. + custom item. """ # Create the main element self.lyrics = self.custom_xml.createElement(u'lyrics') @@ -94,7 +94,6 @@ class CustomXMLBuilder(object): ``content`` The actual text of the verse to be stored. """ - #log.debug(u'add_verse_to_lyrics %s, %s\n%s' % (type, number, content)) verse = self.custom_xml.createElement(u'verse') verse.setAttribute(u'type', type) verse.setAttribute(u'label', number) @@ -103,7 +102,7 @@ class CustomXMLBuilder(object): cds = self.custom_xml.createCDATASection(content) verse.appendChild(cds) - def dump_xml(self): + def _dump_xml(self): """ Debugging aid to dump XML so that we can see what we have. """ @@ -111,23 +110,23 @@ class CustomXMLBuilder(object): def extract_xml(self): """ - Extract our newly created XML song. + Extract our newly created XML custom. """ return self.custom_xml.toxml(u'utf-8') class CustomXMLParser(object): """ - A class to read in and parse a song's XML. + A class to read in and parse a custom's XML. """ log.info(u'CustomXMLParser Loaded') def __init__(self, xml): """ - Set up our song XML parser. + Set up our custom XML parser. ``xml`` - The XML of the song to be parsed. + The XML of the custom to be parsed. """ self.custom_xml = None if xml[:5] == u' Date: Mon, 29 Nov 2010 16:02:41 +0000 Subject: [PATCH 17/18] Songs get created correctly and displays refreshed --- openlp/core/ui/servicemanager.py | 2 ++ openlp/plugins/songs/forms/editsongform.py | 7 +++++-- openlp/plugins/songs/lib/mediaitem.py | 11 ++++++----- openlp/plugins/songs/lib/xml.py | 23 +++++++++++++++------- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 454819f32..6d721823a 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -789,6 +789,8 @@ class ServiceManager(QtGui.QWidget): self.serviceName = name[len(name) - 1] self.parent.addRecentFile(filename) self.parent.serviceChanged(True, self.serviceName) + # Refresh Plugin lists + Receiver.send_message(u'plugin_list_refresh') def validateItem(self, serviceItem): """ diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 8c92583d5..c9868d2e3 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -636,8 +636,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.song.title = unicode(self.TitleEditItem.text()) self.song.alternate_title = unicode(self.AlternativeEdit.text()) self.song.copyright = unicode(self.CopyrightEditItem.text()) - self.song.search_title = self.song.title + u'@' + \ - self.song.alternate_title + if self.song.alternate_title: + self.song.search_title = self.song.title + u'@' + \ + self.song.alternate_title + else: + self.song.search_title = self.song.title self.song.comments = unicode(self.CommentsEdit.toPlainText()) self.song.verse_order = unicode(self.VerseOrderEdit.text()) self.song.ccli_number = unicode(self.CCLNumberEdit.text()) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 2ffa096a6..432eee744 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -114,6 +114,8 @@ class SongMediaItem(MediaManagerItem): self.SearchButtonLayout.addWidget(self.ClearTextButton) self.pageLayout.addLayout(self.SearchButtonLayout) # Signals and slots + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'plugin_list_refresh'), self.onSearchTextButtonClick) QtCore.QObject.connect(self.SearchTextEdit, QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick) QtCore.QObject.connect(self.SearchTextButton, @@ -397,7 +399,6 @@ class SongMediaItem(MediaManagerItem): ] service_item.data_string = {u'title':song.search_title, u'authors':author_list} - # if xmlVersion: service_item.xml_version = self.openLyrics.song_to_xml(song) return True @@ -408,8 +409,8 @@ class SongMediaItem(MediaManagerItem): log.debug(u'serviceLoad') if item.data_string: search_results = self.parent.manager.get_all_objects(Song, - Song.search_title.like(u'%' + - item.data_string[u'title'].split(u'@')[0] + u'%'), + Song.search_title == + item.data_string[u'title'].split(u'@')[0].lower() , Song.search_title.asc()) author_list = item.data_string[u'authors'].split(u', ') editId = 0 @@ -427,11 +428,11 @@ class SongMediaItem(MediaManagerItem): # Authors different if self.addSongFromService: editId = self.openLyrics. \ - xmlToSong(item.xml_version) + xml_to_song(item.xml_version) else: # Title does not match if self.addSongFromService: - editId = self.openLyrics.xmlToSong(item.xml_version) + editId = self.openLyrics.xml_to_song(item.xml_version) # Update service with correct song id if editId != 0: Receiver.send_message(u'service_item_update', diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index f5f285396..2d9855ca8 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -281,14 +281,15 @@ class OpenLyricsParser(object): element = self._add_text_to_element(u'lines', element) for line in unicode(verse[1]).split(u'\n'): self._add_text_to_element(u'line', element, line) - print self._dump_xml(song_xml) - self.xml_to_song(self._extract_xml(song_xml)) - return u'' #self.xml_to_song(self._extract_xml(song_xml)) + return self._extract_xml(song_xml) def xml_to_song(self, xml): """ Create a Song from OpenLyrics format xml """ + # No xml get out of here + if not xml: + return 0 song = Song() if xml[:5] == u' Date: Tue, 30 Nov 2010 20:23:21 +0000 Subject: [PATCH 18/18] Fix field names and verse order bug --- openlp/plugins/songs/lib/xml.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 2d9855ca8..655ea1e3c 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -254,8 +254,8 @@ class OpenLyricsParser(object): """ Convert the song to OpenLyrics Format """ - songXML = SongXMLParser(song.lyrics) - verseList = songXML.get_verses() + song_xml_parser = SongXMLParser(song.lyrics) + verse_list = song_xml_parser.get_verses() song_xml = objectify.fromstring( u'') properties = etree.SubElement(song_xml, u'properties') @@ -274,10 +274,11 @@ class OpenLyricsParser(object): for author in song.authors: self._add_text_to_element(u'author', authors, author.display_name) lyrics = etree.SubElement(song_xml, u'lyrics') - for verse in verseList: - verseTag = u'%s%s' % ( + for verse in verse_list: + verse_tag = u'%s%s' % ( verse[0][u'type'][0].lower(), verse[0][u'label']) - element = self._add_text_to_element(u'verse', lyrics, None, verseTag) + element = \ + self._add_text_to_element(u'verse', lyrics, None, verse_tag) element = self._add_text_to_element(u'lines', element) for line in unicode(verse[1]).split(u'\n'): self._add_text_to_element(u'line', element, line) @@ -297,6 +298,8 @@ class OpenLyricsParser(object): properties = song_xml.properties song.copyright = unicode(properties.copyright.text) song.verse_order = unicode(properties.verseOrder.text) + if song.verse_order == u'None': + song.verse_order = u'' song.topics = [] song.book = None theme_name = None