forked from openlp/openlp
trunk r1129
This commit is contained in:
commit
f58775bef7
BIN
documentation/manual/source/pics/songusage.png
Normal file
BIN
documentation/manual/source/pics/songusage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
documentation/manual/source/pics/songusagedelete.png
Normal file
BIN
documentation/manual/source/pics/songusagedelete.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
documentation/manual/source/pics/songusagereport.png
Normal file
BIN
documentation/manual/source/pics/songusagereport.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
@ -38,48 +38,51 @@ log = logging.getLogger(__name__)
|
|||||||
# TODO make external and configurable in alpha 4 via a settings dialog
|
# TODO make external and configurable in alpha 4 via a settings dialog
|
||||||
html_expands = []
|
html_expands = []
|
||||||
|
|
||||||
html_expands.append({u'desc':u'Red', u'start tag':u'{r}',
|
html_expands.append({u'desc': u'Red', u'start tag': u'{r}',
|
||||||
u'start html':u'<span style="-webkit-text-fill-color:red">',
|
u'start html': u'<span style="-webkit-text-fill-color:red">',
|
||||||
u'end tag':u'{/r}', u'end html':u'</span>', u'protected':False})
|
u'end tag': u'{/r}', u'end html': u'</span>', u'protected': False})
|
||||||
html_expands.append({u'desc':u'Black', u'start tag':u'{b}',
|
html_expands.append({u'desc': u'Black', u'start tag': u'{b}',
|
||||||
u'start html':u'<span style="-webkit-text-fill-color:black">',
|
u'start html': u'<span style="-webkit-text-fill-color:black">',
|
||||||
u'end tag':u'{/b}', u'end html':u'</span>', u'protected':False})
|
u'end tag': u'{/b}', u'end html': u'</span>', u'protected': False})
|
||||||
html_expands.append({u'desc':u'Blue', u'start tag':u'{bl}',
|
html_expands.append({u'desc': u'Blue', u'start tag': u'{bl}',
|
||||||
u'start html':u'<span style="-webkit-text-fill-color:blue">',
|
u'start html': u'<span style="-webkit-text-fill-color:blue">',
|
||||||
u'end tag':u'{/bl}', u'end html':u'</span>', u'protected':False})
|
u'end tag': u'{/bl}', u'end html': u'</span>', u'protected': False})
|
||||||
html_expands.append({u'desc':u'Yellow', u'start tag':u'{y}',
|
html_expands.append({u'desc': u'Yellow', u'start tag': u'{y}',
|
||||||
u'start html':u'<span style="-webkit-text-fill-color:yellow">',
|
u'start html': u'<span style="-webkit-text-fill-color:yellow">',
|
||||||
u'end tag':u'{/y}', u'end html':u'</span>', u'protected':False})
|
u'end tag': u'{/y}', u'end html': u'</span>', u'protected': False})
|
||||||
html_expands.append({u'desc':u'Green', u'start tag':u'{g}',
|
html_expands.append({u'desc': u'Green', u'start tag': u'{g}',
|
||||||
u'start html':u'<span style="-webkit-text-fill-color:green">',
|
u'start html': u'<span style="-webkit-text-fill-color:green">',
|
||||||
u'end tag':u'{/g}', u'end html':u'</span>', u'protected':False})
|
u'end tag': u'{/g}', u'end html': u'</span>', u'protected': False})
|
||||||
html_expands.append({u'desc':u'Pink', u'start tag':u'{pk}',
|
html_expands.append({u'desc': u'Pink', u'start tag': u'{pk}',
|
||||||
u'start html':u'<span style="-webkit-text-fill-color:#CC33CC">',
|
u'start html': u'<span style="-webkit-text-fill-color:#CC33CC">',
|
||||||
u'end tag':u'{/pk}', u'end html':u'</span>', u'protected':False})
|
u'end tag': u'{/pk}', u'end html': u'</span>', u'protected': False})
|
||||||
html_expands.append({u'desc':u'Orange', u'start tag':u'{o}',
|
html_expands.append({u'desc': u'Orange', u'start tag': u'{o}',
|
||||||
u'start html':u'<span style="-webkit-text-fill-color:#CC0033">',
|
u'start html': u'<span style="-webkit-text-fill-color:#CC0033">',
|
||||||
u'end tag':u'{/o}', u'end html':u'</span>', u'protected':False})
|
u'end tag': u'{/o}', u'end html': u'</span>', u'protected': False})
|
||||||
html_expands.append({u'desc':u'Purple', u'start tag':u'{pp}',
|
html_expands.append({u'desc': u'Purple', u'start tag': u'{pp}',
|
||||||
u'start html':u'<span style="-webkit-text-fill-color:#9900FF">',
|
u'start html': u'<span style="-webkit-text-fill-color:#9900FF">',
|
||||||
u'end tag':u'{/pp}', u'end html':u'</span>', u'protected':False})
|
u'end tag': u'{/pp}', u'end html': u'</span>', u'protected': False})
|
||||||
html_expands.append({u'desc':u'White', u'start tag':u'{w}',
|
html_expands.append({u'desc': u'White', u'start tag': u'{w}',
|
||||||
u'start html':u'<span style="-webkit-text-fill-color:white">',
|
u'start html': u'<span style="-webkit-text-fill-color:white">',
|
||||||
u'end tag':u'{/w}', u'end html':u'</span>', u'protected':False})
|
u'end tag': u'{/w}', u'end html': u'</span>', u'protected': False})
|
||||||
html_expands.append({u'desc':u'Superscript', u'start tag':u'{su}',
|
html_expands.append({u'desc': u'Superscript', u'start tag': u'{su}',
|
||||||
u'start html':u'<sup>', u'end tag':u'{/su}', u'end html':u'</sup>',
|
u'start html': u'<sup>', u'end tag': u'{/su}', u'end html': u'</sup>',
|
||||||
u'protected':True})
|
u'protected': True})
|
||||||
html_expands.append({u'desc':u'Subscript', u'start tag':u'{sb}',
|
html_expands.append({u'desc': u'Subscript', u'start tag': u'{sb}',
|
||||||
u'start html':u'<sub>', u'end tag':u'{/sb}', u'end html':u'</sub>',
|
u'start html': u'<sub>', u'end tag': u'{/sb}', u'end html': u'</sub>',
|
||||||
u'protected':True})
|
u'protected': True})
|
||||||
html_expands.append({u'desc':u'Paragraph', u'start tag':u'{p}',
|
html_expands.append({u'desc': u'Paragraph', u'start tag': u'{p}',
|
||||||
u'start html':u'<p>', u'end tag':u'{/p}', u'end html':u'</p>',
|
u'start html': u'<p>', u'end tag': u'{/p}', u'end html': u'</p>',
|
||||||
u'protected':True})
|
u'protected': True})
|
||||||
html_expands.append({u'desc':u'Bold', u'start tag':u'{st}',
|
html_expands.append({u'desc': u'Bold', u'start tag': u'{st}',
|
||||||
u'start html':u'<strong>', u'end tag':u'{/st}', u'end html':u'</strong>',
|
u'start html': u'<strong>', u'end tag': u'{/st}', u'end html': u'</strong>',
|
||||||
u'protected':True})
|
u'protected': True})
|
||||||
html_expands.append({u'desc':u'Italics', u'start tag':u'{it}',
|
html_expands.append({u'desc': u'Italics', u'start tag': u'{it}',
|
||||||
u'start html':u'<em>', u'end tag':u'{/it}', u'end html':u'</em>',
|
u'start html': u'<em>', u'end tag': u'{/it}', u'end html': u'</em>',
|
||||||
u'protected':True})
|
u'protected': True})
|
||||||
|
html_expands.append({u'desc': u'Underline', u'start tag': u'{u}',
|
||||||
|
u'start html': u'<span style="text-decoration: underline;">',
|
||||||
|
u'end tag': u'{/u}', u'end html': u'</span>', u'protected': True})
|
||||||
|
|
||||||
def translate(context, text, comment=None):
|
def translate(context, text, comment=None):
|
||||||
"""
|
"""
|
||||||
|
@ -294,4 +294,5 @@ class Manager(object):
|
|||||||
"""
|
"""
|
||||||
if self.is_dirty:
|
if self.is_dirty:
|
||||||
engine = create_engine(self.db_url)
|
engine = create_engine(self.db_url)
|
||||||
engine.execute("vacuum")
|
if self.db_url.startswith(u'sqlite'):
|
||||||
|
engine.execute("vacuum")
|
||||||
|
@ -320,15 +320,9 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'&Add to selected Service Item'),
|
'&Add to selected Service Item'),
|
||||||
self.onAddEditClick))
|
self.onAddEditClick))
|
||||||
if QtCore.QSettings().value(u'advanced/double click live',
|
QtCore.QObject.connect(self.listView,
|
||||||
QtCore.QVariant(False)).toBool():
|
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
||||||
QtCore.QObject.connect(self.listView,
|
self.onClickPressed)
|
||||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
|
||||||
self.onLiveClick)
|
|
||||||
else:
|
|
||||||
QtCore.QObject.connect(self.listView,
|
|
||||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
|
|
||||||
self.onPreviewClick)
|
|
||||||
|
|
||||||
def initialise(self):
|
def initialise(self):
|
||||||
"""
|
"""
|
||||||
@ -426,10 +420,20 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to '
|
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to '
|
||||||
u'be defined by the plugin')
|
u'be defined by the plugin')
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None):
|
def generateSlideData(self, serviceItem, item=None, xmlVersion=False):
|
||||||
raise NotImplementedError(u'MediaManagerItem.generateSlideData needs '
|
raise NotImplementedError(u'MediaManagerItem.generateSlideData needs '
|
||||||
u'to be defined by the plugin')
|
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):
|
def onPreviewClick(self):
|
||||||
"""
|
"""
|
||||||
Preview an item by building a service item then adding that service
|
Preview an item by building a service item then adding that service
|
||||||
@ -442,10 +446,10 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
'You must select one or more items to preview.'))
|
'You must select one or more items to preview.'))
|
||||||
else:
|
else:
|
||||||
log.debug(self.plugin.name + u' Preview requested')
|
log.debug(self.plugin.name + u' Preview requested')
|
||||||
service_item = self.buildServiceItem()
|
serviceItem = self.buildServiceItem()
|
||||||
if service_item:
|
if serviceItem:
|
||||||
service_item.from_plugin = True
|
serviceItem.from_plugin = True
|
||||||
self.parent.previewController.addServiceItem(service_item)
|
self.parent.previewController.addServiceItem(serviceItem)
|
||||||
|
|
||||||
def onLiveClick(self):
|
def onLiveClick(self):
|
||||||
"""
|
"""
|
||||||
@ -459,10 +463,10 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
'You must select one or more items to send live.'))
|
'You must select one or more items to send live.'))
|
||||||
else:
|
else:
|
||||||
log.debug(self.plugin.name + u' Live requested')
|
log.debug(self.plugin.name + u' Live requested')
|
||||||
service_item = self.buildServiceItem()
|
serviceItem = self.buildServiceItem()
|
||||||
if service_item:
|
if serviceItem:
|
||||||
service_item.from_plugin = True
|
serviceItem.from_plugin = True
|
||||||
self.parent.liveController.addServiceItem(service_item)
|
self.parent.liveController.addServiceItem(serviceItem)
|
||||||
|
|
||||||
def onAddClick(self):
|
def onAddClick(self):
|
||||||
"""
|
"""
|
||||||
@ -474,22 +478,22 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'You must select one or more items.'))
|
'You must select one or more items.'))
|
||||||
else:
|
else:
|
||||||
# Is it posssible to process multiple list items to generate multiple
|
# Is it posssible to process multiple list items to generate
|
||||||
# service items?
|
# multiple service items?
|
||||||
if self.singleServiceItem or self.remoteTriggered:
|
if self.singleServiceItem or self.remoteTriggered:
|
||||||
log.debug(self.plugin.name + u' Add requested')
|
log.debug(self.plugin.name + u' Add requested')
|
||||||
service_item = self.buildServiceItem()
|
serviceItem = self.buildServiceItem(None, True)
|
||||||
if service_item:
|
if serviceItem:
|
||||||
service_item.from_plugin = False
|
serviceItem.from_plugin = False
|
||||||
self.parent.serviceManager.addServiceItem(service_item,
|
self.parent.serviceManager.addServiceItem(serviceItem,
|
||||||
replace=self.remoteTriggered)
|
replace=self.remoteTriggered)
|
||||||
else:
|
else:
|
||||||
items = self.listView.selectedIndexes()
|
items = self.listView.selectedIndexes()
|
||||||
for item in items:
|
for item in items:
|
||||||
service_item = self.buildServiceItem(item)
|
serviceItem = self.buildServiceItem(item, True)
|
||||||
if service_item:
|
if serviceItem:
|
||||||
service_item.from_plugin = False
|
serviceItem.from_plugin = False
|
||||||
self.parent.serviceManager.addServiceItem(service_item)
|
self.parent.serviceManager.addServiceItem(serviceItem)
|
||||||
|
|
||||||
def onAddEditClick(self):
|
def onAddEditClick(self):
|
||||||
"""
|
"""
|
||||||
@ -502,16 +506,16 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
'You must select one or more items'))
|
'You must select one or more items'))
|
||||||
else:
|
else:
|
||||||
log.debug(self.plugin.name + u' Add requested')
|
log.debug(self.plugin.name + u' Add requested')
|
||||||
service_item = self.parent.serviceManager.getServiceItem()
|
serviceItem = self.parent.serviceManager.getServiceItem()
|
||||||
if not service_item:
|
if not serviceItem:
|
||||||
QtGui.QMessageBox.information(self,
|
QtGui.QMessageBox.information(self,
|
||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'No Service Item Selected'),
|
'No Service Item Selected'),
|
||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'You must select an existing service item to add to.'))
|
'You must select an existing service item to add to.'))
|
||||||
elif self.title.lower() == service_item.name.lower():
|
elif self.title.lower() == serviceItem.name.lower():
|
||||||
self.generateSlideData(service_item)
|
self.generateSlideData(serviceItem)
|
||||||
self.parent.serviceManager.addServiceItem(service_item,
|
self.parent.serviceManager.addServiceItem(serviceItem,
|
||||||
replace=True)
|
replace=True)
|
||||||
else:
|
else:
|
||||||
# Turn off the remote edit update message indicator
|
# Turn off the remote edit update message indicator
|
||||||
@ -521,17 +525,17 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
unicode(translate('OpenLP.MediaManagerItem',
|
unicode(translate('OpenLP.MediaManagerItem',
|
||||||
'You must select a %s service item.')) % self.title)
|
'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
|
Common method for generating a service item
|
||||||
"""
|
"""
|
||||||
service_item = ServiceItem(self.parent)
|
serviceItem = ServiceItem(self.parent)
|
||||||
if self.serviceItemIconName:
|
if self.serviceItemIconName:
|
||||||
service_item.add_icon(self.serviceItemIconName)
|
serviceItem.add_icon(self.serviceItemIconName)
|
||||||
else:
|
else:
|
||||||
service_item.add_icon(self.parent.icon_path)
|
serviceItem.add_icon(self.parent.icon_path)
|
||||||
if self.generateSlideData(service_item, item):
|
if self.generateSlideData(serviceItem, item, xmlVersion):
|
||||||
return service_item
|
return serviceItem
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -101,6 +101,7 @@ class ServiceItem(object):
|
|||||||
self.search_string = u''
|
self.search_string = u''
|
||||||
self.data_string = u''
|
self.data_string = u''
|
||||||
self.edit_id = None
|
self.edit_id = None
|
||||||
|
self.xml_version = None
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
|
||||||
def _new_item(self):
|
def _new_item(self):
|
||||||
@ -252,7 +253,8 @@ class ServiceItem(object):
|
|||||||
u'from_plugin': self.from_plugin,
|
u'from_plugin': self.from_plugin,
|
||||||
u'capabilities': self.capabilities,
|
u'capabilities': self.capabilities,
|
||||||
u'search': self.search_string,
|
u'search': self.search_string,
|
||||||
u'data': self.data_string
|
u'data': self.data_string,
|
||||||
|
u'xml_version': self.xml_version
|
||||||
}
|
}
|
||||||
service_data = []
|
service_data = []
|
||||||
if self.service_item_type == ServiceItemType.Text:
|
if self.service_item_type == ServiceItemType.Text:
|
||||||
@ -294,6 +296,8 @@ class ServiceItem(object):
|
|||||||
if u'search' in header:
|
if u'search' in header:
|
||||||
self.search_string = header[u'search']
|
self.search_string = header[u'search']
|
||||||
self.data_string = header[u'data']
|
self.data_string = header[u'data']
|
||||||
|
if u'xml_version' in header:
|
||||||
|
self.xml_version = header[u'xml_version']
|
||||||
if self.service_item_type == ServiceItemType.Text:
|
if self.service_item_type == ServiceItemType.Text:
|
||||||
for slide in serviceitem[u'serviceitem'][u'data']:
|
for slide in serviceitem[u'serviceitem'][u'data']:
|
||||||
self._raw_frames.append(slide)
|
self._raw_frames.append(slide)
|
||||||
|
@ -146,7 +146,7 @@ class AdvancedTab(SettingsTab):
|
|||||||
self.mediaPluginCheckBox.setText(translate('OpenLP.AdvancedTab',
|
self.mediaPluginCheckBox.setText(translate('OpenLP.AdvancedTab',
|
||||||
'Remember active media manager tab on startup'))
|
'Remember active media manager tab on startup'))
|
||||||
self.doubleClickLiveCheckBox.setText(translate('OpenLP.AdvancedTab',
|
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',
|
self.expandServiceItemCheckBox.setText(translate('OpenLP.AdvancedTab',
|
||||||
'Expand new service items on creation'))
|
'Expand new service items on creation'))
|
||||||
# self.sharedDirGroupBox.setTitle(
|
# self.sharedDirGroupBox.setTitle(
|
||||||
|
@ -100,7 +100,7 @@ class MainDisplay(DisplayWidget):
|
|||||||
self.screens = screens
|
self.screens = screens
|
||||||
self.isLive = live
|
self.isLive = live
|
||||||
self.alertTab = None
|
self.alertTab = None
|
||||||
self.hide_mode = None
|
self.hideMode = None
|
||||||
self.setWindowTitle(u'OpenLP Display')
|
self.setWindowTitle(u'OpenLP Display')
|
||||||
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
|
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
|
||||||
self.setWindowFlags(QtCore.Qt.FramelessWindowHint |
|
self.setWindowFlags(QtCore.Qt.FramelessWindowHint |
|
||||||
@ -381,8 +381,8 @@ class MainDisplay(DisplayWidget):
|
|||||||
if self.isLive:
|
if self.isLive:
|
||||||
self.setVisible(True)
|
self.setVisible(True)
|
||||||
# if was hidden keep it hidden
|
# if was hidden keep it hidden
|
||||||
if self.hide_mode and self.isLive:
|
if self.hideMode and self.isLive:
|
||||||
self.hideDisplay(self.hide_mode)
|
self.hideDisplay(self.hideMode)
|
||||||
preview = QtGui.QImage(self.screen[u'size'].width(),
|
preview = QtGui.QImage(self.screen[u'size'].width(),
|
||||||
self.screen[u'size'].height(),
|
self.screen[u'size'].height(),
|
||||||
QtGui.QImage.Format_ARGB32_Premultiplied)
|
QtGui.QImage.Format_ARGB32_Premultiplied)
|
||||||
@ -412,8 +412,8 @@ class MainDisplay(DisplayWidget):
|
|||||||
if serviceItem.foot_text and serviceItem.foot_text:
|
if serviceItem.foot_text and serviceItem.foot_text:
|
||||||
self.footer(serviceItem.foot_text)
|
self.footer(serviceItem.foot_text)
|
||||||
# if was hidden keep it hidden
|
# if was hidden keep it hidden
|
||||||
if self.hide_mode and self.isLive:
|
if self.hideMode and self.isLive:
|
||||||
self.hideDisplay(self.hide_mode)
|
self.hideDisplay(self.hideMode)
|
||||||
|
|
||||||
def footer(self, text):
|
def footer(self, text):
|
||||||
"""
|
"""
|
||||||
@ -444,7 +444,7 @@ class MainDisplay(DisplayWidget):
|
|||||||
self.setVisible(True)
|
self.setVisible(True)
|
||||||
if self.phononActive:
|
if self.phononActive:
|
||||||
self.webView.setVisible(True)
|
self.webView.setVisible(True)
|
||||||
self.hide_mode = mode
|
self.hideMode = mode
|
||||||
|
|
||||||
def showDisplay(self):
|
def showDisplay(self):
|
||||||
"""
|
"""
|
||||||
@ -459,9 +459,9 @@ class MainDisplay(DisplayWidget):
|
|||||||
if self.phononActive:
|
if self.phononActive:
|
||||||
self.webView.setVisible(False)
|
self.webView.setVisible(False)
|
||||||
self.videoPlay()
|
self.videoPlay()
|
||||||
|
self.hideMode = None
|
||||||
# Trigger actions when display is active again
|
# Trigger actions when display is active again
|
||||||
Receiver.send_message(u'maindisplay_active')
|
Receiver.send_message(u'maindisplay_active')
|
||||||
self.hide_mode = None
|
|
||||||
|
|
||||||
class AudioPlayer(QtCore.QObject):
|
class AudioPlayer(QtCore.QObject):
|
||||||
"""
|
"""
|
||||||
|
@ -789,6 +789,8 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.serviceName = name[len(name) - 1]
|
self.serviceName = name[len(name) - 1]
|
||||||
self.parent.addRecentFile(filename)
|
self.parent.addRecentFile(filename)
|
||||||
self.parent.serviceChanged(True, self.serviceName)
|
self.parent.serviceChanged(True, self.serviceName)
|
||||||
|
# Refresh Plugin lists
|
||||||
|
Receiver.send_message(u'plugin_list_refresh')
|
||||||
|
|
||||||
def validateItem(self, serviceItem):
|
def validateItem(self, serviceItem):
|
||||||
"""
|
"""
|
||||||
@ -1028,6 +1030,9 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
# ServiceManager started the drag and drop
|
# ServiceManager started the drag and drop
|
||||||
if plugin == u'ServiceManager':
|
if plugin == u'ServiceManager':
|
||||||
startpos, startCount = self.findServiceItem()
|
startpos, startCount = self.findServiceItem()
|
||||||
|
# If no items selected
|
||||||
|
if startpos == -1:
|
||||||
|
return
|
||||||
if item is None:
|
if item is None:
|
||||||
endpos = len(self.serviceItems)
|
endpos = len(self.serviceItems)
|
||||||
else:
|
else:
|
||||||
|
@ -331,10 +331,8 @@ class SlideController(QtGui.QWidget):
|
|||||||
QtCore.QObject.connect(self.PreviewListWidget,
|
QtCore.QObject.connect(self.PreviewListWidget,
|
||||||
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
|
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
|
||||||
if not self.isLive:
|
if not self.isLive:
|
||||||
if QtCore.QSettings().value(u'advanced/double click live',
|
QtCore.QObject.connect(self.PreviewListWidget,
|
||||||
QtCore.QVariant(False)).toBool():
|
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onGoLiveClick)
|
||||||
QtCore.QObject.connect(self.PreviewListWidget,
|
|
||||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onGoLive)
|
|
||||||
if isLive:
|
if isLive:
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
|
QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
|
||||||
@ -391,6 +389,8 @@ class SlideController(QtGui.QWidget):
|
|||||||
if self.isLive:
|
if self.isLive:
|
||||||
QtCore.QObject.connect(self.volumeSlider,
|
QtCore.QObject.connect(self.volumeSlider,
|
||||||
QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume)
|
QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume)
|
||||||
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
QtCore.SIGNAL(u'maindisplay_active'), self.updatePreview)
|
||||||
|
|
||||||
def screenSizeChanged(self):
|
def screenSizeChanged(self):
|
||||||
"""
|
"""
|
||||||
@ -823,16 +823,15 @@ class SlideController(QtGui.QWidget):
|
|||||||
row)
|
row)
|
||||||
|
|
||||||
def updatePreview(self):
|
def updatePreview(self):
|
||||||
|
log.debug(u'updatePreview %s ' %self.screens.current[u'primary'])
|
||||||
if not 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
|
# Grab now, but try again in a couple of seconds if slide change
|
||||||
# is slow
|
# is slow
|
||||||
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
|
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
|
||||||
QtCore.QTimer.singleShot(2.5, self.grabMainDisplay)
|
QtCore.QTimer.singleShot(2.5, self.grabMainDisplay)
|
||||||
else:
|
else:
|
||||||
label = self.PreviewListWidget.cellWidget(
|
self.SlidePreview.setPixmap(
|
||||||
self.PreviewListWidget.currentRow(), 1)
|
QtGui.QPixmap.fromImage(self.display.preview()))
|
||||||
if label:
|
|
||||||
self.SlidePreview.setPixmap(label.pixmap())
|
|
||||||
|
|
||||||
def grabMainDisplay(self):
|
def grabMainDisplay(self):
|
||||||
winid = QtGui.QApplication.desktop().winId()
|
winid = QtGui.QApplication.desktop().winId()
|
||||||
@ -944,6 +943,14 @@ class SlideController(QtGui.QWidget):
|
|||||||
Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(),
|
Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(),
|
||||||
u'P:%s' % self.serviceItem.edit_id)
|
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):
|
def onGoLive(self):
|
||||||
"""
|
"""
|
||||||
If preview copy slide item to live
|
If preview copy slide item to live
|
||||||
|
@ -183,9 +183,14 @@ class ThemesTab(SettingsTab):
|
|||||||
|
|
||||||
def updateThemeList(self, theme_list):
|
def updateThemeList(self, theme_list):
|
||||||
"""
|
"""
|
||||||
Called from ThemeManager when the Themes have changed
|
Called from ThemeManager when the Themes have changed.
|
||||||
|
|
||||||
|
``theme_list``
|
||||||
|
The list of available themes::
|
||||||
|
|
||||||
|
[u'Bible Theme', u'Song Theme']
|
||||||
"""
|
"""
|
||||||
#reload as may have been triggered by the ThemeManager
|
# Reload as may have been triggered by the ThemeManager.
|
||||||
self.global_theme = unicode(QtCore.QSettings().value(
|
self.global_theme = unicode(QtCore.QSettings().value(
|
||||||
self.settingsSection + u'/global theme',
|
self.settingsSection + u'/global theme',
|
||||||
QtCore.QVariant(u'')).toString())
|
QtCore.QVariant(u'')).toString())
|
||||||
|
@ -133,7 +133,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
self.OSISLocationEdit.setFocus()
|
self.OSISLocationEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
|
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
|
||||||
if self.field(u'csv_booksfile').toString() == u'':
|
if not self.field(u'csv_booksfile').toString():
|
||||||
QtGui.QMessageBox.critical(self,
|
QtGui.QMessageBox.critical(self,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Invalid Books File'),
|
'Invalid Books File'),
|
||||||
@ -142,7 +142,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
'the Bible to use in the import.'))
|
'the Bible to use in the import.'))
|
||||||
self.BooksLocationEdit.setFocus()
|
self.BooksLocationEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif self.field(u'csv_versefile').toString() == u'':
|
elif not self.field(u'csv_versefile').toString():
|
||||||
QtGui.QMessageBox.critical(self,
|
QtGui.QMessageBox.critical(self,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Invalid Verse File'),
|
'Invalid Verse File'),
|
||||||
@ -153,7 +153,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
return False
|
return False
|
||||||
elif self.field(u'source_format').toInt()[0] == \
|
elif self.field(u'source_format').toInt()[0] == \
|
||||||
BibleFormat.OpenSong:
|
BibleFormat.OpenSong:
|
||||||
if self.field(u'opensong_file').toString() == u'':
|
if not self.field(u'opensong_file').toString():
|
||||||
QtGui.QMessageBox.critical(self,
|
QtGui.QMessageBox.critical(self,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Invalid OpenSong Bible'),
|
'Invalid OpenSong Bible'),
|
||||||
@ -168,7 +168,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
license_version = unicode(self.field(u'license_version').toString())
|
license_version = unicode(self.field(u'license_version').toString())
|
||||||
license_copyright = \
|
license_copyright = \
|
||||||
unicode(self.field(u'license_copyright').toString())
|
unicode(self.field(u'license_copyright').toString())
|
||||||
if license_version == u'':
|
if not license_version:
|
||||||
QtGui.QMessageBox.critical(self,
|
QtGui.QMessageBox.critical(self,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Empty Version Name'),
|
'Empty Version Name'),
|
||||||
@ -176,7 +176,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
'You need to specify a version name for your Bible.'))
|
'You need to specify a version name for your Bible.'))
|
||||||
self.VersionNameEdit.setFocus()
|
self.VersionNameEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif license_copyright == u'':
|
elif not license_copyright:
|
||||||
QtGui.QMessageBox.critical(self,
|
QtGui.QMessageBox.critical(self,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Empty Copyright'),
|
'Empty Copyright'),
|
||||||
@ -207,9 +207,11 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
The index of the combo box.
|
The index of the combo box.
|
||||||
"""
|
"""
|
||||||
self.BibleComboBox.clear()
|
self.BibleComboBox.clear()
|
||||||
for bible in self.web_bible_list[index].keys():
|
bibles = [unicode(translate('BiblesPlugin.ImportWizardForm', bible)) for
|
||||||
self.BibleComboBox.addItem(unicode(
|
bible in self.web_bible_list[index].keys()]
|
||||||
translate('BiblesPlugin.ImportWizardForm', bible)))
|
bibles.sort()
|
||||||
|
for bible in bibles:
|
||||||
|
self.BibleComboBox.addItem(bible)
|
||||||
|
|
||||||
def onOsisFileButtonClicked(self):
|
def onOsisFileButtonClicked(self):
|
||||||
"""
|
"""
|
||||||
@ -317,7 +319,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
"""
|
"""
|
||||||
Load the list of Crosswalk and BibleGateway bibles.
|
Load the list of Crosswalk and BibleGateway bibles.
|
||||||
"""
|
"""
|
||||||
#Load and store Crosswalk Bibles
|
# Load and store Crosswalk Bibles.
|
||||||
filepath = AppLocation.get_directory(AppLocation.PluginsDir)
|
filepath = AppLocation.get_directory(AppLocation.PluginsDir)
|
||||||
filepath = os.path.join(filepath, u'bibles', u'resources')
|
filepath = os.path.join(filepath, u'bibles', u'resources')
|
||||||
books_file = None
|
books_file = None
|
||||||
@ -341,7 +343,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
finally:
|
finally:
|
||||||
if books_file:
|
if books_file:
|
||||||
books_file.close()
|
books_file.close()
|
||||||
#Load and store BibleGateway Bibles
|
# Load and store BibleGateway Bibles.
|
||||||
books_file = None
|
books_file = None
|
||||||
try:
|
try:
|
||||||
self.web_bible_list[WebDownload.BibleGateway] = {}
|
self.web_bible_list[WebDownload.BibleGateway] = {}
|
||||||
@ -379,12 +381,18 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
|
|
||||||
def preImport(self):
|
def preImport(self):
|
||||||
|
bible_type = self.field(u'source_format').toInt()[0]
|
||||||
self.finishButton.setVisible(False)
|
self.finishButton.setVisible(False)
|
||||||
self.ImportProgressBar.setMinimum(0)
|
self.ImportProgressBar.setMinimum(0)
|
||||||
self.ImportProgressBar.setMaximum(1188)
|
self.ImportProgressBar.setMaximum(1188)
|
||||||
self.ImportProgressBar.setValue(0)
|
self.ImportProgressBar.setValue(0)
|
||||||
self.ImportProgressLabel.setText(
|
if bible_type == BibleFormat.WebDownload:
|
||||||
translate('BiblesPlugin.ImportWizardForm', 'Starting import...'))
|
self.ImportProgressLabel.setText(translate(
|
||||||
|
'BiblesPlugin.ImportWizardForm',
|
||||||
|
'Starting Registering bible...'))
|
||||||
|
else:
|
||||||
|
self.ImportProgressLabel.setText(translate(
|
||||||
|
'BiblesPlugin.ImportWizardForm', 'Starting import...'))
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
|
|
||||||
def performImport(self):
|
def performImport(self):
|
||||||
@ -395,26 +403,26 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
unicode(self.field(u'license_permissions').toString())
|
unicode(self.field(u'license_permissions').toString())
|
||||||
importer = None
|
importer = None
|
||||||
if bible_type == BibleFormat.OSIS:
|
if bible_type == BibleFormat.OSIS:
|
||||||
# Import an OSIS bible
|
# Import an OSIS bible.
|
||||||
importer = self.manager.import_bible(BibleFormat.OSIS,
|
importer = self.manager.import_bible(BibleFormat.OSIS,
|
||||||
name=license_version,
|
name=license_version,
|
||||||
filename=unicode(self.field(u'osis_location').toString())
|
filename=unicode(self.field(u'osis_location').toString())
|
||||||
)
|
)
|
||||||
elif bible_type == BibleFormat.CSV:
|
elif bible_type == BibleFormat.CSV:
|
||||||
# Import a CSV bible
|
# Import a CSV bible.
|
||||||
importer = self.manager.import_bible(BibleFormat.CSV,
|
importer = self.manager.import_bible(BibleFormat.CSV,
|
||||||
name=license_version,
|
name=license_version,
|
||||||
booksfile=unicode(self.field(u'csv_booksfile').toString()),
|
booksfile=unicode(self.field(u'csv_booksfile').toString()),
|
||||||
versefile=unicode(self.field(u'csv_versefile').toString())
|
versefile=unicode(self.field(u'csv_versefile').toString())
|
||||||
)
|
)
|
||||||
elif bible_type == BibleFormat.OpenSong:
|
elif bible_type == BibleFormat.OpenSong:
|
||||||
# Import an OpenSong bible
|
# Import an OpenSong bible.
|
||||||
importer = self.manager.import_bible(BibleFormat.OpenSong,
|
importer = self.manager.import_bible(BibleFormat.OpenSong,
|
||||||
name=license_version,
|
name=license_version,
|
||||||
filename=unicode(self.field(u'opensong_file').toString())
|
filename=unicode(self.field(u'opensong_file').toString())
|
||||||
)
|
)
|
||||||
elif bible_type == BibleFormat.WebDownload:
|
elif bible_type == BibleFormat.WebDownload:
|
||||||
# Import a bible from the web
|
# Import a bible from the web.
|
||||||
self.ImportProgressBar.setMaximum(1)
|
self.ImportProgressBar.setMaximum(1)
|
||||||
download_location = self.field(u'web_location').toInt()[0]
|
download_location = self.field(u'web_location').toInt()[0]
|
||||||
bible_version = unicode(self.BibleComboBox.currentText())
|
bible_version = unicode(self.BibleComboBox.currentText())
|
||||||
@ -438,8 +446,14 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
self.manager.save_meta_data(license_version, license_version,
|
self.manager.save_meta_data(license_version, license_version,
|
||||||
license_copyright, license_permissions)
|
license_copyright, license_permissions)
|
||||||
self.manager.reload_bibles()
|
self.manager.reload_bibles()
|
||||||
self.ImportProgressLabel.setText(
|
if bible_type == BibleFormat.WebDownload:
|
||||||
translate('BiblesPlugin.ImportWizardForm', 'Finished import.'))
|
self.ImportProgressLabel.setText(
|
||||||
|
translate('BiblesPlugin.ImportWizardForm', 'Registered '
|
||||||
|
'bible. Please note, that verses will be downloaded on\n'
|
||||||
|
'demand and thus an internet connection is required.'))
|
||||||
|
else:
|
||||||
|
self.ImportProgressLabel.setText(translate(
|
||||||
|
'BiblesPlugin.ImportWizardForm', 'Finished import.'))
|
||||||
else:
|
else:
|
||||||
self.ImportProgressLabel.setText(
|
self.ImportProgressLabel.setText(
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
|
@ -110,9 +110,9 @@ class BiblesTab(SettingsTab):
|
|||||||
self.BibleThemeComboBox.setObjectName(u'BibleThemeComboBox')
|
self.BibleThemeComboBox.setObjectName(u'BibleThemeComboBox')
|
||||||
self.BibleThemeComboBox.addItem(QtCore.QString())
|
self.BibleThemeComboBox.addItem(QtCore.QString())
|
||||||
self.BibleThemeLayout.addWidget(self.BibleThemeComboBox)
|
self.BibleThemeLayout.addWidget(self.BibleThemeComboBox)
|
||||||
self.BibleDualCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox)
|
self.BibleSecondCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox)
|
||||||
self.BibleDualCheckBox.setObjectName(u'BibleDualCheckBox')
|
self.BibleSecondCheckBox.setObjectName(u'BibleSecondCheckBox')
|
||||||
self.VerseDisplayLayout.addWidget(self.BibleDualCheckBox, 3, 0, 1, 1)
|
self.VerseDisplayLayout.addWidget(self.BibleSecondCheckBox, 3, 0, 1, 1)
|
||||||
self.VerseDisplayLayout.addWidget(self.BibleThemeWidget, 4, 0, 1, 1)
|
self.VerseDisplayLayout.addWidget(self.BibleThemeWidget, 4, 0, 1, 1)
|
||||||
self.ChangeNoteLabel = QtGui.QLabel(self.VerseDisplayGroupBox)
|
self.ChangeNoteLabel = QtGui.QLabel(self.VerseDisplayGroupBox)
|
||||||
self.ChangeNoteLabel.setObjectName(u'ChangeNoteLabel')
|
self.ChangeNoteLabel.setObjectName(u'ChangeNoteLabel')
|
||||||
@ -143,8 +143,8 @@ class BiblesTab(SettingsTab):
|
|||||||
self.LayoutStyleComboBox, QtCore.SIGNAL(u'activated(int)'),
|
self.LayoutStyleComboBox, QtCore.SIGNAL(u'activated(int)'),
|
||||||
self.onLayoutStyleComboBoxChanged)
|
self.onLayoutStyleComboBoxChanged)
|
||||||
QtCore.QObject.connect(
|
QtCore.QObject.connect(
|
||||||
self.BibleDualCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
self.BibleSecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
||||||
self.onBibleDualCheckBox)
|
self.onBibleSecondCheckBox)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
|
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
|
||||||
|
|
||||||
@ -176,8 +176,8 @@ class BiblesTab(SettingsTab):
|
|||||||
translate('BiblesPlugin.BiblesTab', '[ And ]'))
|
translate('BiblesPlugin.BiblesTab', '[ And ]'))
|
||||||
self.ChangeNoteLabel.setText(translate('BiblesPlugin.BiblesTab',
|
self.ChangeNoteLabel.setText(translate('BiblesPlugin.BiblesTab',
|
||||||
'Note:\nChanges do not affect verses already in the service.'))
|
'Note:\nChanges do not affect verses already in the service.'))
|
||||||
self.BibleDualCheckBox.setText(
|
self.BibleSecondCheckBox.setText(
|
||||||
translate('BiblesPlugin.BiblesTab', 'Display dual Bible verses'))
|
translate('BiblesPlugin.BiblesTab', 'Display second Bible verses'))
|
||||||
|
|
||||||
def onBibleThemeComboBoxChanged(self):
|
def onBibleThemeComboBoxChanged(self):
|
||||||
self.bible_theme = self.BibleThemeComboBox.currentText()
|
self.bible_theme = self.BibleThemeComboBox.currentText()
|
||||||
@ -190,15 +190,15 @@ class BiblesTab(SettingsTab):
|
|||||||
|
|
||||||
def onNewChaptersCheckBoxChanged(self, check_state):
|
def onNewChaptersCheckBoxChanged(self, check_state):
|
||||||
self.show_new_chapters = False
|
self.show_new_chapters = False
|
||||||
# we have a set value convert to True/False
|
# We have a set value convert to True/False.
|
||||||
if check_state == QtCore.Qt.Checked:
|
if check_state == QtCore.Qt.Checked:
|
||||||
self.show_new_chapters = True
|
self.show_new_chapters = True
|
||||||
|
|
||||||
def onBibleDualCheckBox(self, check_state):
|
def onBibleSecondCheckBox(self, check_state):
|
||||||
self.dual_bibles = False
|
self.second_bibles = False
|
||||||
# we have a set value convert to True/False
|
# We have a set value convert to True/False.
|
||||||
if check_state == QtCore.Qt.Checked:
|
if check_state == QtCore.Qt.Checked:
|
||||||
self.dual_bibles = True
|
self.second_bibles = True
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
settings = QtCore.QSettings()
|
settings = QtCore.QSettings()
|
||||||
@ -211,12 +211,12 @@ class BiblesTab(SettingsTab):
|
|||||||
u'verse layout style', QtCore.QVariant(0)).toInt()[0]
|
u'verse layout style', QtCore.QVariant(0)).toInt()[0]
|
||||||
self.bible_theme = unicode(
|
self.bible_theme = unicode(
|
||||||
settings.value(u'bible theme', QtCore.QVariant(u'')).toString())
|
settings.value(u'bible theme', QtCore.QVariant(u'')).toString())
|
||||||
self.dual_bibles = settings.value(
|
self.second_bibles = settings.value(
|
||||||
u'dual bibles', QtCore.QVariant(True)).toBool()
|
u'second bibles', QtCore.QVariant(True)).toBool()
|
||||||
self.NewChaptersCheckBox.setChecked(self.show_new_chapters)
|
self.NewChaptersCheckBox.setChecked(self.show_new_chapters)
|
||||||
self.DisplayStyleComboBox.setCurrentIndex(self.display_style)
|
self.DisplayStyleComboBox.setCurrentIndex(self.display_style)
|
||||||
self.LayoutStyleComboBox.setCurrentIndex(self.layout_style)
|
self.LayoutStyleComboBox.setCurrentIndex(self.layout_style)
|
||||||
self.BibleDualCheckBox.setChecked(self.dual_bibles)
|
self.BibleSecondCheckBox.setChecked(self.second_bibles)
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
@ -228,13 +228,18 @@ class BiblesTab(SettingsTab):
|
|||||||
QtCore.QVariant(self.display_style))
|
QtCore.QVariant(self.display_style))
|
||||||
settings.setValue(u'verse layout style',
|
settings.setValue(u'verse layout style',
|
||||||
QtCore.QVariant(self.layout_style))
|
QtCore.QVariant(self.layout_style))
|
||||||
settings.setValue(u'dual bibles', QtCore.QVariant(self.dual_bibles))
|
settings.setValue(u'second bibles', QtCore.QVariant(self.second_bibles))
|
||||||
settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme))
|
settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme))
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
def updateThemeList(self, theme_list):
|
def updateThemeList(self, theme_list):
|
||||||
"""
|
"""
|
||||||
Called from ThemeManager when the Themes have changed
|
Called from ThemeManager when the Themes have changed.
|
||||||
|
|
||||||
|
``theme_list``
|
||||||
|
The list of available themes::
|
||||||
|
|
||||||
|
[u'Bible Theme', u'Song Theme']
|
||||||
"""
|
"""
|
||||||
self.BibleThemeComboBox.clear()
|
self.BibleThemeComboBox.clear()
|
||||||
self.BibleThemeComboBox.addItem(u'')
|
self.BibleThemeComboBox.addItem(u'')
|
||||||
@ -243,7 +248,7 @@ class BiblesTab(SettingsTab):
|
|||||||
index = self.BibleThemeComboBox.findText(
|
index = self.BibleThemeComboBox.findText(
|
||||||
unicode(self.bible_theme), QtCore.Qt.MatchExactly)
|
unicode(self.bible_theme), QtCore.Qt.MatchExactly)
|
||||||
if index == -1:
|
if index == -1:
|
||||||
# Not Found
|
# Not Found.
|
||||||
index = 0
|
index = 0
|
||||||
self.bible_theme = u''
|
self.bible_theme = u''
|
||||||
self.BibleThemeComboBox.setCurrentIndex(index)
|
self.BibleThemeComboBox.setCurrentIndex(index)
|
||||||
|
@ -44,24 +44,28 @@ class BibleMeta(BaseModel):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Testament(BaseModel):
|
class Testament(BaseModel):
|
||||||
"""
|
"""
|
||||||
Bible Testaments
|
Bible Testaments
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Book(BaseModel):
|
class Book(BaseModel):
|
||||||
"""
|
"""
|
||||||
Song model
|
Song model
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Verse(BaseModel):
|
class Verse(BaseModel):
|
||||||
"""
|
"""
|
||||||
Topic model
|
Topic model
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def init_schema(url):
|
def init_schema(url):
|
||||||
"""
|
"""
|
||||||
Setup a bible database connection and initialise the database schema.
|
Setup a bible database connection and initialise the database schema.
|
||||||
@ -240,7 +244,7 @@ class BibleDB(QtCore.QObject, Manager):
|
|||||||
and the value is the verse text.
|
and the value is the verse text.
|
||||||
"""
|
"""
|
||||||
log.debug(u'create_chapter %s,%s', book_id, chapter)
|
log.debug(u'create_chapter %s,%s', book_id, chapter)
|
||||||
# text list has book and chapter as first two elements of the array
|
# Text list has book and chapter as first two elements of the array.
|
||||||
for verse_number, verse_text in textlist.iteritems():
|
for verse_number, verse_text in textlist.iteritems():
|
||||||
verse = Verse.populate(
|
verse = Verse.populate(
|
||||||
book_id = book_id,
|
book_id = book_id,
|
||||||
|
@ -364,12 +364,11 @@ class HTTPBible(BibleDB):
|
|||||||
if self.proxy_server:
|
if self.proxy_server:
|
||||||
self.create_meta(u'proxy server', self.proxy_server)
|
self.create_meta(u'proxy server', self.proxy_server)
|
||||||
if self.proxy_username:
|
if self.proxy_username:
|
||||||
# store the proxy userid
|
# Store the proxy userid.
|
||||||
self.create_meta(u'proxy username', self.proxy_username)
|
self.create_meta(u'proxy username', self.proxy_username)
|
||||||
if self.proxy_password:
|
if self.proxy_password:
|
||||||
# store the proxy password
|
# Store the proxy password.
|
||||||
self.create_meta(u'proxy password', self.proxy_password)
|
self.create_meta(u'proxy password', self.proxy_password)
|
||||||
self.wizard.incrementProgressBar('Registered.')
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_verses(self, reference_list):
|
def get_verses(self, reference_list):
|
||||||
@ -417,7 +416,7 @@ class HTTPBible(BibleDB):
|
|||||||
## to request ac and get Acts back.
|
## to request ac and get Acts back.
|
||||||
bookname = search_results.book
|
bookname = search_results.book
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
# check to see if book/chapter exists
|
# Check to see if book/chapter exists.
|
||||||
db_book = self.get_book(bookname)
|
db_book = self.get_book(bookname)
|
||||||
self.create_chapter(db_book.id, search_results.chapter,
|
self.create_chapter(db_book.id, search_results.chapter,
|
||||||
search_results.verselist)
|
search_results.verselist)
|
||||||
|
@ -257,17 +257,34 @@ class BibleManager(object):
|
|||||||
'Book Chapter:Verse-Chapter:Verse'))
|
'Book Chapter:Verse-Chapter:Verse'))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def verse_search(self, bible, text):
|
def verse_search(self, bible, second_bible, text):
|
||||||
"""
|
"""
|
||||||
Does a verse search for the given bible and text.
|
Does a verse search for the given bible and text.
|
||||||
|
|
||||||
``bible``
|
``bible``
|
||||||
The bible to seach in (unicode).
|
The bible to seach in (unicode).
|
||||||
|
|
||||||
|
``second_bible``
|
||||||
|
The second bible (unicode). We do not search in this bible.
|
||||||
|
|
||||||
``text``
|
``text``
|
||||||
The text to search for (unicode).
|
The text to search for (unicode).
|
||||||
"""
|
"""
|
||||||
log.debug(u'BibleManager.verse_search("%s", "%s")', bible, text)
|
log.debug(u'BibleManager.verse_search("%s", "%s")', bible, text)
|
||||||
|
# Check if the bible or second_bible is a web bible.
|
||||||
|
webbible = self.db_cache[bible].get_object(BibleMeta,
|
||||||
|
u'download source')
|
||||||
|
second_webbible = u''
|
||||||
|
if second_bible:
|
||||||
|
second_webbible = self.db_cache[second_bible].get_object(BibleMeta,
|
||||||
|
u'download source')
|
||||||
|
if webbible or second_webbible:
|
||||||
|
QtGui.QMessageBox.information(self.parent.mediaItem,
|
||||||
|
translate('BiblesPlugin.BibleManager',
|
||||||
|
'Web Bible cannot be used'),
|
||||||
|
translate('BiblesPlugin.BibleManager', 'Text Search is not '
|
||||||
|
'available with Web Bibles.'))
|
||||||
|
return None
|
||||||
if text:
|
if text:
|
||||||
return self.db_cache[bible].verse_search(text)
|
return self.db_cache[bible].verse_search(text)
|
||||||
else:
|
else:
|
||||||
@ -317,4 +334,3 @@ class BibleManager(object):
|
|||||||
"""
|
"""
|
||||||
for bible in self.db_cache:
|
for bible in self.db_cache:
|
||||||
self.db_cache[bible].finalise()
|
self.db_cache[bible].finalise()
|
||||||
|
|
||||||
|
@ -47,21 +47,22 @@ class BibleListView(BaseListWithDnD):
|
|||||||
self.parent().onListViewResize(event.size().width(),
|
self.parent().onListViewResize(event.size().width(),
|
||||||
event.size().width())
|
event.size().width())
|
||||||
|
|
||||||
|
|
||||||
class BibleMediaItem(MediaManagerItem):
|
class BibleMediaItem(MediaManagerItem):
|
||||||
"""
|
"""
|
||||||
This is the custom media manager item for Bibles.
|
This is the custom media manager item for Bibles.
|
||||||
"""
|
"""
|
||||||
log.info(u'Bible Media Item loaded')
|
log.info(u'Bible Media Item loaded')
|
||||||
|
|
||||||
def __init__(self, parent, icon, title):
|
def __init__(self, parent, plugin, icon):
|
||||||
self.PluginNameShort = u'Bible'
|
self.PluginNameShort = u'Bible'
|
||||||
self.pluginNameVisible = translate('BiblesPlugin.MediaItem', 'Bible')
|
self.pluginNameVisible = translate('BiblesPlugin.MediaItem', 'Bible')
|
||||||
self.IconPath = u'songs/song'
|
self.IconPath = u'songs/song'
|
||||||
self.ListViewWithDnD_class = BibleListView
|
self.ListViewWithDnD_class = BibleListView
|
||||||
MediaManagerItem.__init__(self, parent, icon, title)
|
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||||
# place to store the search results for both bibles
|
# Place to store the search results for both bibles.
|
||||||
self.search_results = {}
|
self.search_results = {}
|
||||||
self.dual_search_results = {}
|
self.second_search_results = {}
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles)
|
QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles)
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.SearchTabWidget.sizePolicy().hasHeightForWidth())
|
self.SearchTabWidget.sizePolicy().hasHeightForWidth())
|
||||||
self.SearchTabWidget.setSizePolicy(sizePolicy)
|
self.SearchTabWidget.setSizePolicy(sizePolicy)
|
||||||
self.SearchTabWidget.setObjectName(u'SearchTabWidget')
|
self.SearchTabWidget.setObjectName(u'SearchTabWidget')
|
||||||
# Add the Quick Search tab
|
# Add the Quick Search tab.
|
||||||
self.QuickTab = QtGui.QWidget()
|
self.QuickTab = QtGui.QWidget()
|
||||||
self.QuickTab.setObjectName(u'QuickTab')
|
self.QuickTab.setObjectName(u'QuickTab')
|
||||||
self.QuickLayout = QtGui.QGridLayout(self.QuickTab)
|
self.QuickLayout = QtGui.QGridLayout(self.QuickTab)
|
||||||
@ -144,7 +145,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
QuickSpacerItem = QtGui.QSpacerItem(20, 35, QtGui.QSizePolicy.Minimum,
|
QuickSpacerItem = QtGui.QSpacerItem(20, 35, QtGui.QSizePolicy.Minimum,
|
||||||
QtGui.QSizePolicy.Expanding)
|
QtGui.QSizePolicy.Expanding)
|
||||||
self.QuickLayout.addItem(QuickSpacerItem, 6, 2, 1, 1)
|
self.QuickLayout.addItem(QuickSpacerItem, 6, 2, 1, 1)
|
||||||
# Add the Advanced Search tab
|
# Add the Advanced Search tab.
|
||||||
self.AdvancedTab = QtGui.QWidget()
|
self.AdvancedTab = QtGui.QWidget()
|
||||||
self.AdvancedTab.setObjectName(u'AdvancedTab')
|
self.AdvancedTab.setObjectName(u'AdvancedTab')
|
||||||
self.AdvancedLayout = QtGui.QGridLayout(self.AdvancedTab)
|
self.AdvancedLayout = QtGui.QGridLayout(self.AdvancedTab)
|
||||||
@ -226,7 +227,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.AdvancedLayout.addWidget(self.AdvancedMessage, 8, 0, 1, 3)
|
self.AdvancedLayout.addWidget(self.AdvancedMessage, 8, 0, 1, 3)
|
||||||
self.SearchTabWidget.addTab(self.AdvancedTab,
|
self.SearchTabWidget.addTab(self.AdvancedTab,
|
||||||
translate('BiblesPlugin.MediaItem', 'Advanced'))
|
translate('BiblesPlugin.MediaItem', 'Advanced'))
|
||||||
# Add the search tab widget to the page layout
|
# Add the search tab widget to the page layout.
|
||||||
self.pageLayout.addWidget(self.SearchTabWidget)
|
self.pageLayout.addWidget(self.SearchTabWidget)
|
||||||
# Combo Boxes
|
# Combo Boxes
|
||||||
QtCore.QObject.connect(self.AdvancedVersionComboBox,
|
QtCore.QObject.connect(self.AdvancedVersionComboBox,
|
||||||
@ -239,6 +240,10 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedFromVerse)
|
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedFromVerse)
|
||||||
QtCore.QObject.connect(self.AdvancedToChapter,
|
QtCore.QObject.connect(self.AdvancedToChapter,
|
||||||
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedToChapter)
|
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedToChapter)
|
||||||
|
QtCore.QObject.connect(self.QuickSearchComboBox,
|
||||||
|
QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter)
|
||||||
|
QtCore.QObject.connect(self.QuickVersionComboBox,
|
||||||
|
QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter)
|
||||||
# Buttons
|
# Buttons
|
||||||
QtCore.QObject.connect(self.AdvancedSearchButton,
|
QtCore.QObject.connect(self.AdvancedSearchButton,
|
||||||
QtCore.SIGNAL(u'pressed()'), self.onAdvancedSearchButton)
|
QtCore.SIGNAL(u'pressed()'), self.onAdvancedSearchButton)
|
||||||
@ -270,7 +275,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
|
|
||||||
def configUpdated(self):
|
def configUpdated(self):
|
||||||
log.debug(u'configUpdated')
|
log.debug(u'configUpdated')
|
||||||
if QtCore.QSettings().value(self.settingsSection + u'/dual bibles',
|
if QtCore.QSettings().value(self.settingsSection + u'/second bibles',
|
||||||
QtCore.QVariant(True)).toBool():
|
QtCore.QVariant(True)).toBool():
|
||||||
self.AdvancedSecondBibleLabel.setVisible(True)
|
self.AdvancedSecondBibleLabel.setVisible(True)
|
||||||
self.AdvancedSecondBibleComboBox.setVisible(True)
|
self.AdvancedSecondBibleComboBox.setVisible(True)
|
||||||
@ -287,7 +292,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.QuickVersionLabel.setText(
|
self.QuickVersionLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Version:'))
|
translate('BiblesPlugin.MediaItem', 'Version:'))
|
||||||
self.QuickSecondVersionLabel.setText(
|
self.QuickSecondVersionLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Dual:'))
|
translate('BiblesPlugin.MediaItem', 'Second:'))
|
||||||
self.QuickSearchLabel.setText(
|
self.QuickSearchLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Search type:'))
|
translate('BiblesPlugin.MediaItem', 'Search type:'))
|
||||||
self.QuickSearchLabel.setText(
|
self.QuickSearchLabel.setText(
|
||||||
@ -299,7 +304,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.AdvancedVersionLabel.setText(
|
self.AdvancedVersionLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Version:'))
|
translate('BiblesPlugin.MediaItem', 'Version:'))
|
||||||
self.AdvancedSecondBibleLabel.setText(
|
self.AdvancedSecondBibleLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Dual:'))
|
translate('BiblesPlugin.MediaItem', 'Second:'))
|
||||||
self.AdvancedBookLabel.setText(
|
self.AdvancedBookLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Book:'))
|
translate('BiblesPlugin.MediaItem', 'Book:'))
|
||||||
self.AdvancedChapterLabel.setText(
|
self.AdvancedChapterLabel.setText(
|
||||||
@ -331,6 +336,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
log.debug(u'bible manager initialise')
|
log.debug(u'bible manager initialise')
|
||||||
self.parent.manager.media = self
|
self.parent.manager.media = self
|
||||||
self.loadBibles()
|
self.loadBibles()
|
||||||
|
self.updateAutoCompleter()
|
||||||
self.configUpdated()
|
self.configUpdated()
|
||||||
log.debug(u'bible manager initialise complete')
|
log.debug(u'bible manager initialise complete')
|
||||||
|
|
||||||
@ -338,7 +344,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.QuickMessage.setText(text)
|
self.QuickMessage.setText(text)
|
||||||
self.AdvancedMessage.setText(text)
|
self.AdvancedMessage.setText(text)
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
# minor delay to get the events processed
|
# Minor delay to get the events processed.
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
def onListViewResize(self, width, height):
|
def onListViewResize(self, width, height):
|
||||||
@ -358,13 +364,15 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
translate('BiblesPlugin.MediaItem', 'No Book Found'),
|
translate('BiblesPlugin.MediaItem', 'No Book Found'),
|
||||||
translate('BiblesPlugin.MediaItem',
|
translate('BiblesPlugin.MediaItem',
|
||||||
'No matching book could be found in this Bible.'))
|
'No matching book could be found in this Bible.'))
|
||||||
|
self.AdvancedSearchButton.setEnabled(True)
|
||||||
|
|
||||||
def onImportClick(self):
|
def onImportClick(self):
|
||||||
if not hasattr(self, u'import_wizard'):
|
if not hasattr(self, u'import_wizard'):
|
||||||
self.import_wizard = BibleImportForm(self, self.parent.manager,
|
self.import_wizard = BibleImportForm(self, self.parent.manager,
|
||||||
self.parent)
|
self.parent)
|
||||||
self.import_wizard.exec_()
|
# If the import was not canceled then reload.
|
||||||
self.reloadBibles()
|
if self.import_wizard.exec_():
|
||||||
|
self.reloadBibles()
|
||||||
|
|
||||||
def loadBibles(self):
|
def loadBibles(self):
|
||||||
log.debug(u'Loading Bibles')
|
log.debug(u'Loading Bibles')
|
||||||
@ -374,8 +382,10 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.AdvancedSecondBibleComboBox.clear()
|
self.AdvancedSecondBibleComboBox.clear()
|
||||||
self.QuickSecondBibleComboBox.addItem(u'')
|
self.QuickSecondBibleComboBox.addItem(u'')
|
||||||
self.AdvancedSecondBibleComboBox.addItem(u'')
|
self.AdvancedSecondBibleComboBox.addItem(u'')
|
||||||
|
# Get all bibles and sort the list.
|
||||||
bibles = self.parent.manager.get_bibles().keys()
|
bibles = self.parent.manager.get_bibles().keys()
|
||||||
# load bibles into the combo boxes
|
bibles.sort()
|
||||||
|
# Load the bibles into the combo boxes.
|
||||||
first = True
|
first = True
|
||||||
for bible in bibles:
|
for bible in bibles:
|
||||||
if bible:
|
if bible:
|
||||||
@ -393,6 +403,15 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.loadBibles()
|
self.loadBibles()
|
||||||
|
|
||||||
def initialiseBible(self, bible):
|
def initialiseBible(self, bible):
|
||||||
|
"""
|
||||||
|
This initialises the given bible, which means that its book names and
|
||||||
|
their chapter numbers is added to the combo boxes on the
|
||||||
|
'Advanced Search' Tab. This is not of any importance of the
|
||||||
|
'Quick Search' Tab.
|
||||||
|
|
||||||
|
``bible``
|
||||||
|
The bible to initialise (unicode).
|
||||||
|
"""
|
||||||
log.debug(u'initialiseBible %s', bible)
|
log.debug(u'initialiseBible %s', bible)
|
||||||
book_data = self.parent.manager.get_books(bible)
|
book_data = self.parent.manager.get_books(bible)
|
||||||
self.AdvancedBookComboBox.clear()
|
self.AdvancedBookComboBox.clear()
|
||||||
@ -423,6 +442,25 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.adjustComboBox(1, verse_count, self.AdvancedFromVerse)
|
self.adjustComboBox(1, verse_count, self.AdvancedFromVerse)
|
||||||
self.adjustComboBox(1, verse_count, self.AdvancedToVerse)
|
self.adjustComboBox(1, verse_count, self.AdvancedToVerse)
|
||||||
|
|
||||||
|
def updateAutoCompleter(self):
|
||||||
|
"""
|
||||||
|
This updates the bible book completion list for the search field. The
|
||||||
|
completion depends on the bible. It is only updated when we are doing a
|
||||||
|
verse search, otherwise the auto completion list is removed.
|
||||||
|
"""
|
||||||
|
books = []
|
||||||
|
# We have to do a 'Verse Search'.
|
||||||
|
if self.QuickSearchComboBox.currentIndex() == 0:
|
||||||
|
bibles = self.parent.manager.get_bibles()
|
||||||
|
bible = unicode(self.QuickVersionComboBox.currentText())
|
||||||
|
if bible:
|
||||||
|
book_data = bibles[bible].get_books()
|
||||||
|
books = [book.name for book in book_data]
|
||||||
|
books.sort()
|
||||||
|
completer = QtGui.QCompleter(books)
|
||||||
|
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
|
||||||
|
self.QuickSearchEdit.setCompleter(completer)
|
||||||
|
|
||||||
def onAdvancedVersionComboBox(self):
|
def onAdvancedVersionComboBox(self):
|
||||||
self.initialiseBible(
|
self.initialiseBible(
|
||||||
unicode(self.AdvancedVersionComboBox.currentText()))
|
unicode(self.AdvancedVersionComboBox.currentText()))
|
||||||
@ -482,6 +520,17 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
|
|
||||||
def adjustComboBox(self, range_from, range_to, combo, restore=False):
|
def adjustComboBox(self, range_from, range_to, combo, restore=False):
|
||||||
"""
|
"""
|
||||||
|
Adjusts the given como box to the given values.
|
||||||
|
|
||||||
|
``range_from``
|
||||||
|
The first number of the range (int).
|
||||||
|
|
||||||
|
``range_to``
|
||||||
|
The last number of the range (int).
|
||||||
|
|
||||||
|
``combo``
|
||||||
|
The combo box itself (QComboBox).
|
||||||
|
|
||||||
``restore``
|
``restore``
|
||||||
If True, then the combo's currentText will be restored after
|
If True, then the combo's currentText will be restored after
|
||||||
adjusting (if possible).
|
adjusting (if possible).
|
||||||
@ -490,16 +539,19 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
if restore:
|
if restore:
|
||||||
old_text = unicode(combo.currentText())
|
old_text = unicode(combo.currentText())
|
||||||
combo.clear()
|
combo.clear()
|
||||||
for i in range(int(range_from), int(range_to) + 1):
|
for i in range(range_from, range_to + 1):
|
||||||
combo.addItem(unicode(i))
|
combo.addItem(unicode(i))
|
||||||
if restore and combo.findText(old_text) != -1:
|
if restore and combo.findText(old_text) != -1:
|
||||||
combo.setCurrentIndex(combo.findText(old_text))
|
combo.setCurrentIndex(combo.findText(old_text))
|
||||||
|
|
||||||
def onAdvancedSearchButton(self):
|
def onAdvancedSearchButton(self):
|
||||||
|
"""
|
||||||
|
Does an advanced search and saves the search results.
|
||||||
|
"""
|
||||||
log.debug(u'Advanced Search Button pressed')
|
log.debug(u'Advanced Search Button pressed')
|
||||||
self.AdvancedSearchButton.setEnabled(False)
|
self.AdvancedSearchButton.setEnabled(False)
|
||||||
bible = unicode(self.AdvancedVersionComboBox.currentText())
|
bible = unicode(self.AdvancedVersionComboBox.currentText())
|
||||||
dual_bible = unicode(self.AdvancedSecondBibleComboBox.currentText())
|
second_bible = unicode(self.AdvancedSecondBibleComboBox.currentText())
|
||||||
book = unicode(self.AdvancedBookComboBox.currentText())
|
book = unicode(self.AdvancedBookComboBox.currentText())
|
||||||
chapter_from = int(self.AdvancedFromChapter.currentText())
|
chapter_from = int(self.AdvancedFromChapter.currentText())
|
||||||
chapter_to = int(self.AdvancedToChapter.currentText())
|
chapter_to = int(self.AdvancedToChapter.currentText())
|
||||||
@ -508,74 +560,81 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
versetext = u'%s %s:%s-%s:%s' % (book, chapter_from, verse_from,
|
versetext = u'%s %s:%s-%s:%s' % (book, chapter_from, verse_from,
|
||||||
chapter_to, verse_to)
|
chapter_to, verse_to)
|
||||||
self.search_results = self.parent.manager.get_verses(bible, versetext)
|
self.search_results = self.parent.manager.get_verses(bible, versetext)
|
||||||
if dual_bible:
|
if second_bible:
|
||||||
self.dual_search_results = self.parent.manager.get_verses(
|
self.second_search_results = self.parent.manager.get_verses(
|
||||||
dual_bible, versetext)
|
second_bible, versetext)
|
||||||
if self.ClearAdvancedSearchComboBox.currentIndex() == 0:
|
if self.ClearAdvancedSearchComboBox.currentIndex() == 0:
|
||||||
self.listView.clear()
|
self.listView.clear()
|
||||||
if self.listView.count() != 0:
|
if self.listView.count() != 0:
|
||||||
|
# Check if the first item is a second bible item or not.
|
||||||
bitem = self.listView.item(0)
|
bitem = self.listView.item(0)
|
||||||
item_dual_bible = self._decodeQtObject(bitem, 'dual_bible')
|
item_second_bible = self._decodeQtObject(bitem, 'second_bible')
|
||||||
if item_dual_bible and dual_bible or not item_dual_bible and \
|
if item_second_bible and second_bible or not item_second_bible and \
|
||||||
not dual_bible:
|
not second_bible:
|
||||||
self.displayResults(bible, dual_bible)
|
self.displayResults(bible, second_bible)
|
||||||
elif QtGui.QMessageBox.critical(self,
|
elif QtGui.QMessageBox.critical(self,
|
||||||
translate('BiblePlugin.MediaItem', 'Error'),
|
translate('BiblePlugin.MediaItem', 'Error'),
|
||||||
translate('BiblePlugin.MediaItem', 'You cannot combine single '
|
translate('BiblePlugin.MediaItem', 'You cannot combine single '
|
||||||
'and dual bible verses. Do you want to delete your search '
|
'and second bible verses. Do you want to delete your search '
|
||||||
'results and start a new search?'),
|
'results and start a new search?'),
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
||||||
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
|
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
|
||||||
self.listView.clear()
|
self.listView.clear()
|
||||||
self.displayResults(bible, dual_bible)
|
self.displayResults(bible, second_bible)
|
||||||
else:
|
else:
|
||||||
self.displayResults(bible, dual_bible)
|
self.displayResults(bible, second_bible)
|
||||||
self.AdvancedSearchButton.setEnabled(True)
|
self.AdvancedSearchButton.setEnabled(True)
|
||||||
|
|
||||||
def onQuickSearchButton(self):
|
def onQuickSearchButton(self):
|
||||||
|
"""
|
||||||
|
Does a quick search and saves the search results. Quick search can
|
||||||
|
either be "Verse Search" or "Text Search".
|
||||||
|
"""
|
||||||
log.debug(u'Quick Search Button pressed')
|
log.debug(u'Quick Search Button pressed')
|
||||||
self.QuickSearchButton.setEnabled(False)
|
self.QuickSearchButton.setEnabled(False)
|
||||||
bible = unicode(self.QuickVersionComboBox.currentText())
|
bible = unicode(self.QuickVersionComboBox.currentText())
|
||||||
dual_bible = unicode(self.QuickSecondBibleComboBox.currentText())
|
second_bible = unicode(self.QuickSecondBibleComboBox.currentText())
|
||||||
text = unicode(self.QuickSearchEdit.text())
|
text = unicode(self.QuickSearchEdit.text())
|
||||||
if self.QuickSearchComboBox.currentIndex() == 0:
|
if self.QuickSearchComboBox.currentIndex() == 0:
|
||||||
# We are doing a 'Verse Search'.
|
# We are doing a 'Verse Search'.
|
||||||
self.search_results = self.parent.manager.get_verses(bible, text)
|
self.search_results = self.parent.manager.get_verses(bible, text)
|
||||||
if dual_bible and self.search_results:
|
if second_bible and self.search_results:
|
||||||
self.dual_search_results = self.parent.manager.get_verses(
|
self.second_search_results = self.parent.manager.get_verses(
|
||||||
dual_bible, text)
|
second_bible, text)
|
||||||
else:
|
else:
|
||||||
# We are doing a ' Text Search'.
|
# We are doing a 'Text Search'.
|
||||||
bibles = self.parent.manager.get_bibles()
|
bibles = self.parent.manager.get_bibles()
|
||||||
self.search_results = self.parent.manager.verse_search(bible, text)
|
self.search_results = self.parent.manager.verse_search(bible,
|
||||||
if dual_bible and self.search_results:
|
second_bible, text)
|
||||||
|
if second_bible and self.search_results:
|
||||||
text = []
|
text = []
|
||||||
for verse in self.search_results:
|
for verse in self.search_results:
|
||||||
text.append((verse.book.name, verse.chapter, verse.verse,
|
text.append((verse.book.name, verse.chapter, verse.verse,
|
||||||
verse.verse))
|
verse.verse))
|
||||||
self.dual_search_results = bibles[dual_bible].get_verses(text)
|
self.second_search_results = \
|
||||||
|
bibles[second_bible].get_verses(text)
|
||||||
if self.ClearQuickSearchComboBox.currentIndex() == 0:
|
if self.ClearQuickSearchComboBox.currentIndex() == 0:
|
||||||
self.listView.clear()
|
self.listView.clear()
|
||||||
if self.listView.count() != 0 and self.search_results:
|
if self.listView.count() != 0 and self.search_results:
|
||||||
bitem = self.listView.item(0)
|
bitem = self.listView.item(0)
|
||||||
item_dual_bible = self._decodeQtObject(bitem, 'dual_bible')
|
item_second_bible = self._decodeQtObject(bitem, 'second_bible')
|
||||||
if item_dual_bible and dual_bible or not item_dual_bible and \
|
if item_second_bible and second_bible or not item_second_bible and \
|
||||||
not dual_bible:
|
not second_bible:
|
||||||
self.displayResults(bible, dual_bible)
|
self.displayResults(bible, second_bible)
|
||||||
elif QtGui.QMessageBox.critical(self,
|
elif QtGui.QMessageBox.critical(self,
|
||||||
translate('BiblePlugin.MediaItem', 'Error'),
|
translate('BiblePlugin.MediaItem', 'Error'),
|
||||||
translate('BiblePlugin.MediaItem', 'You cannot combine single '
|
translate('BiblePlugin.MediaItem', 'You cannot combine single '
|
||||||
'and dual bible verses. Do you want to delete your search '
|
'and second bible verses. Do you want to delete your search '
|
||||||
'results and start a new search?'),
|
'results and start a new search?'),
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
||||||
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
|
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
|
||||||
self.listView.clear()
|
self.listView.clear()
|
||||||
self.displayResults(bible, dual_bible)
|
self.displayResults(bible, second_bible)
|
||||||
elif self.search_results:
|
elif self.search_results:
|
||||||
self.displayResults(bible, dual_bible)
|
self.displayResults(bible, second_bible)
|
||||||
self.QuickSearchButton.setEnabled(True)
|
self.QuickSearchButton.setEnabled(True)
|
||||||
|
|
||||||
def displayResults(self, bible, dual_bible=u''):
|
def displayResults(self, bible, second_bible=u''):
|
||||||
"""
|
"""
|
||||||
Displays the search results in the media manager. All data needed for
|
Displays the search results in the media manager. All data needed for
|
||||||
further action is saved for/in each row.
|
further action is saved for/in each row.
|
||||||
@ -583,38 +642,41 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
version = self.parent.manager.get_meta_data(bible, u'Version')
|
version = self.parent.manager.get_meta_data(bible, u'Version')
|
||||||
copyright = self.parent.manager.get_meta_data(bible, u'Copyright')
|
copyright = self.parent.manager.get_meta_data(bible, u'Copyright')
|
||||||
permissions = self.parent.manager.get_meta_data(bible, u'Permissions')
|
permissions = self.parent.manager.get_meta_data(bible, u'Permissions')
|
||||||
if dual_bible:
|
if second_bible:
|
||||||
dual_version = self.parent.manager.get_meta_data(dual_bible,
|
second_version = self.parent.manager.get_meta_data(second_bible,
|
||||||
u'Version')
|
u'Version')
|
||||||
dual_copyright = self.parent.manager.get_meta_data(dual_bible,
|
second_copyright = self.parent.manager.get_meta_data(second_bible,
|
||||||
u'Copyright')
|
u'Copyright')
|
||||||
dual_permissions = self.parent.manager.get_meta_data(dual_bible,
|
second_permissions = self.parent.manager.get_meta_data(second_bible,
|
||||||
u'Permissions')
|
u'Permissions')
|
||||||
if not dual_permissions:
|
if not second_permissions:
|
||||||
dual_permissions = u''
|
second_permissions = u''
|
||||||
# We count the number of rows which are maybe already present.
|
|
||||||
start_count = self.listView.count()
|
|
||||||
for count, verse in enumerate(self.search_results):
|
for count, verse in enumerate(self.search_results):
|
||||||
if dual_bible:
|
if second_bible:
|
||||||
vdict = {
|
try:
|
||||||
'book': QtCore.QVariant(verse.book.name),
|
vdict = {
|
||||||
'chapter': QtCore.QVariant(verse.chapter),
|
'book': QtCore.QVariant(verse.book.name),
|
||||||
'verse': QtCore.QVariant(verse.verse),
|
'chapter': QtCore.QVariant(verse.chapter),
|
||||||
'bible': QtCore.QVariant(bible),
|
'verse': QtCore.QVariant(verse.verse),
|
||||||
'version': QtCore.QVariant(version.value),
|
'bible': QtCore.QVariant(bible),
|
||||||
'copyright': QtCore.QVariant(copyright.value),
|
'version': QtCore.QVariant(version.value),
|
||||||
'permissions': QtCore.QVariant(permissions.value),
|
'copyright': QtCore.QVariant(copyright.value),
|
||||||
'text': QtCore.QVariant(verse.text),
|
'permissions': QtCore.QVariant(permissions.value),
|
||||||
'dual_bible': QtCore.QVariant(dual_bible),
|
'text': QtCore.QVariant(verse.text),
|
||||||
'dual_version': QtCore.QVariant(dual_version.value),
|
'second_bible': QtCore.QVariant(second_bible),
|
||||||
'dual_copyright': QtCore.QVariant(dual_copyright.value),
|
'second_version': QtCore.QVariant(second_version.value),
|
||||||
'dual_permissions': QtCore.QVariant(dual_permissions.value),
|
'second_copyright': QtCore.QVariant(
|
||||||
'dual_text': QtCore.QVariant(
|
second_copyright.value),
|
||||||
self.dual_search_results[count].text)
|
'second_permissions': QtCore.QVariant(
|
||||||
}
|
second_permissions.value),
|
||||||
|
'second_text': QtCore.QVariant(
|
||||||
|
self.second_search_results[count].text)
|
||||||
|
}
|
||||||
|
except IndexError:
|
||||||
|
break
|
||||||
bible_text = u' %s %d:%d (%s, %s)' % (verse.book.name,
|
bible_text = u' %s %d:%d (%s, %s)' % (verse.book.name,
|
||||||
verse.chapter, verse.verse, version.value,
|
verse.chapter, verse.verse, version.value,
|
||||||
dual_version.value)
|
second_version.value)
|
||||||
else:
|
else:
|
||||||
vdict = {
|
vdict = {
|
||||||
'book': QtCore.QVariant(verse.book.name),
|
'book': QtCore.QVariant(verse.book.name),
|
||||||
@ -625,22 +687,20 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
'copyright': QtCore.QVariant(copyright.value),
|
'copyright': QtCore.QVariant(copyright.value),
|
||||||
'permissions': QtCore.QVariant(permissions.value),
|
'permissions': QtCore.QVariant(permissions.value),
|
||||||
'text': QtCore.QVariant(verse.text),
|
'text': QtCore.QVariant(verse.text),
|
||||||
'dual_bible': QtCore.QVariant(u''),
|
'second_bible': QtCore.QVariant(u''),
|
||||||
'dual_version': QtCore.QVariant(u''),
|
'second_version': QtCore.QVariant(u''),
|
||||||
'dual_copyright': QtCore.QVariant(u''),
|
'second_copyright': QtCore.QVariant(u''),
|
||||||
'dual_permissions': QtCore.QVariant(u''),
|
'second_permissions': QtCore.QVariant(u''),
|
||||||
'dual_text': QtCore.QVariant(u'')
|
'second_text': QtCore.QVariant(u'')
|
||||||
}
|
}
|
||||||
bible_text = u' %s %d:%d (%s)' % (verse.book.name,
|
bible_text = u'%s %d:%d (%s)' % (verse.book.name,
|
||||||
verse.chapter, verse.verse, version.value)
|
verse.chapter, verse.verse, version.value)
|
||||||
bible_verse = QtGui.QListWidgetItem(bible_text)
|
bible_verse = QtGui.QListWidgetItem(bible_text)
|
||||||
bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(vdict))
|
bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(vdict))
|
||||||
self.listView.addItem(bible_verse)
|
self.listView.addItem(bible_verse)
|
||||||
row = self.listView.setCurrentRow(count + start_count)
|
self.listView.selectAll()
|
||||||
if row:
|
|
||||||
row.setSelected(True)
|
|
||||||
self.search_results = {}
|
self.search_results = {}
|
||||||
self.dual_search_results = {}
|
self.second_search_results = {}
|
||||||
|
|
||||||
def _decodeQtObject(self, bitem, key):
|
def _decodeQtObject(self, bitem, key):
|
||||||
reference = bitem.data(QtCore.Qt.UserRole)
|
reference = bitem.data(QtCore.Qt.UserRole)
|
||||||
@ -651,7 +711,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
obj = obj.toPyObject()
|
obj = obj.toPyObject()
|
||||||
return unicode(obj)
|
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
|
Generates and formats the slides for the service item as well as the
|
||||||
service item's title.
|
service item's title.
|
||||||
@ -661,7 +721,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
if len(items) == 0:
|
if len(items) == 0:
|
||||||
return False
|
return False
|
||||||
bible_text = u''
|
bible_text = u''
|
||||||
old_chapter = u''
|
old_chapter = -1
|
||||||
raw_footer = []
|
raw_footer = []
|
||||||
raw_slides = []
|
raw_slides = []
|
||||||
raw_title = []
|
raw_title = []
|
||||||
@ -676,22 +736,22 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
copyright = self._decodeQtObject(bitem, 'copyright')
|
copyright = self._decodeQtObject(bitem, 'copyright')
|
||||||
permissions = self._decodeQtObject(bitem, 'permissions')
|
permissions = self._decodeQtObject(bitem, 'permissions')
|
||||||
text = self._decodeQtObject(bitem, 'text')
|
text = self._decodeQtObject(bitem, 'text')
|
||||||
dual_bible = self._decodeQtObject(bitem, 'dual_bible')
|
second_bible = self._decodeQtObject(bitem, 'second_bible')
|
||||||
dual_version = self._decodeQtObject(bitem, 'dual_version')
|
second_version = self._decodeQtObject(bitem, 'second_version')
|
||||||
dual_copyright = self._decodeQtObject(bitem, 'dual_copyright')
|
second_copyright = self._decodeQtObject(bitem, 'second_copyright')
|
||||||
dual_permissions = self._decodeQtObject(bitem, 'dual_permissions')
|
second_permissions = self._decodeQtObject(bitem, 'second_permissions')
|
||||||
dual_text = self._decodeQtObject(bitem, 'dual_text')
|
second_text = self._decodeQtObject(bitem, 'second_text')
|
||||||
verse_text = self.formatVerse(old_chapter, chapter, verse)
|
verse_text = self.formatVerse(old_chapter, chapter, verse)
|
||||||
footer = u'%s (%s %s %s)' % (book, version, copyright, permissions)
|
footer = u'%s (%s %s %s)' % (book, version, copyright, permissions)
|
||||||
if footer not in raw_footer:
|
if footer not in raw_footer:
|
||||||
raw_footer.append(footer)
|
raw_footer.append(footer)
|
||||||
if dual_bible:
|
if second_bible:
|
||||||
footer = u'%s (%s %s %s)' % (book, dual_version, dual_copyright,
|
footer = u'%s (%s %s %s)' % (book, second_version,
|
||||||
dual_permissions)
|
second_copyright, second_permissions)
|
||||||
if footer not in raw_footer:
|
if footer not in raw_footer:
|
||||||
raw_footer.append(footer)
|
raw_footer.append(footer)
|
||||||
bible_text = u'%s %s\n\n%s %s' % (verse_text, text, verse_text,
|
bible_text = u'%s %s\n\n%s %s' % (verse_text, text, verse_text,
|
||||||
dual_text)
|
second_text)
|
||||||
raw_slides.append(bible_text)
|
raw_slides.append(bible_text)
|
||||||
bible_text = u''
|
bible_text = u''
|
||||||
# If we are 'Verse Per Slide' then create a new slide.
|
# If we are 'Verse Per Slide' then create a new slide.
|
||||||
@ -719,7 +779,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
raw_slides.append(bible_text)
|
raw_slides.append(bible_text)
|
||||||
bible_text = u''
|
bible_text = u''
|
||||||
# Service Item: Capabilities
|
# Service Item: Capabilities
|
||||||
if self.parent.settings_tab.layout_style == 2 and not dual_bible:
|
if self.parent.settings_tab.layout_style == 2 and not second_bible:
|
||||||
# Split the line but do not replace line breaks in renderer.
|
# Split the line but do not replace line breaks in renderer.
|
||||||
service_item.add_capability(ItemCapabilities.NoLineBreaks)
|
service_item.add_capability(ItemCapabilities.NoLineBreaks)
|
||||||
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
||||||
@ -749,6 +809,12 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
This methode is called, when we have to change the title, because
|
This methode is called, when we have to change the title, because
|
||||||
we are at the end of a verse range. E. g. if we want to add
|
we are at the end of a verse range. E. g. if we want to add
|
||||||
Genesis 1:1-6 as well as Daniel 2:14.
|
Genesis 1:1-6 as well as Daniel 2:14.
|
||||||
|
|
||||||
|
``start_item``
|
||||||
|
The first item of a range.
|
||||||
|
|
||||||
|
``old_item``
|
||||||
|
The last item of a range.
|
||||||
"""
|
"""
|
||||||
old_bitem = self.listView.item(old_item.row())
|
old_bitem = self.listView.item(old_item.row())
|
||||||
old_chapter = int(self._decodeQtObject(old_bitem, 'chapter'))
|
old_chapter = int(self._decodeQtObject(old_bitem, 'chapter'))
|
||||||
@ -758,18 +824,18 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
start_chapter = int(self._decodeQtObject(start_bitem, 'chapter'))
|
start_chapter = int(self._decodeQtObject(start_bitem, 'chapter'))
|
||||||
start_verse = int(self._decodeQtObject(start_bitem, 'verse'))
|
start_verse = int(self._decodeQtObject(start_bitem, 'verse'))
|
||||||
start_bible = self._decodeQtObject(start_bitem, 'bible')
|
start_bible = self._decodeQtObject(start_bitem, 'bible')
|
||||||
start_dual_bible = self._decodeQtObject(start_bitem, 'dual_bible')
|
start_second_bible = self._decodeQtObject(start_bitem, 'second_bible')
|
||||||
if start_dual_bible:
|
if start_second_bible:
|
||||||
if start_verse == old_verse and start_chapter == old_chapter:
|
if start_verse == old_verse and start_chapter == old_chapter:
|
||||||
title = u'%s %s:%s (%s, %s)' % (start_book, start_chapter,
|
title = u'%s %s:%s (%s, %s)' % (start_book, start_chapter,
|
||||||
start_verse, start_bible, start_dual_bible)
|
start_verse, start_bible, start_second_bible)
|
||||||
elif start_chapter == old_chapter:
|
elif start_chapter == old_chapter:
|
||||||
title = u'%s %s:%s-%s (%s, %s)' % (start_book, start_chapter,
|
title = u'%s %s:%s-%s (%s, %s)' % (start_book, start_chapter,
|
||||||
start_verse, old_verse, start_bible, start_dual_bible)
|
start_verse, old_verse, start_bible, start_second_bible)
|
||||||
else:
|
else:
|
||||||
title = u'%s %s:%s-%s:%s (%s, %s)' % (start_book, start_chapter,
|
title = u'%s %s:%s-%s:%s (%s, %s)' % (start_book, start_chapter,
|
||||||
start_verse, old_chapter, old_verse, start_bible,
|
start_verse, old_chapter, old_verse, start_bible,
|
||||||
start_dual_bible)
|
start_second_bible)
|
||||||
else:
|
else:
|
||||||
if start_verse == old_verse and start_chapter == old_chapter:
|
if start_verse == old_verse and start_chapter == old_chapter:
|
||||||
title = u'%s %s:%s (%s)' % (start_book, start_chapter,
|
title = u'%s %s:%s (%s)' % (start_book, start_chapter,
|
||||||
@ -785,34 +851,62 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
def checkTitle(self, item, old_item):
|
def checkTitle(self, item, old_item):
|
||||||
"""
|
"""
|
||||||
This methode checks if we are at the end of an verse range. If that is
|
This methode checks if we are at the end of an verse range. If that is
|
||||||
the case, we return True, else False. E. g. if we added Genesis 1:1-6,
|
the case, we return True, otherwise False. E. g. if we added
|
||||||
but the next verse is Daniel 2:14.
|
Genesis 1:1-6, but the next verse is Daniel 2:14, we return True.
|
||||||
|
|
||||||
|
``item``
|
||||||
|
The item we are dealing with at the moment.
|
||||||
|
|
||||||
|
``old_item``
|
||||||
|
The item we were previously dealing with.
|
||||||
"""
|
"""
|
||||||
|
# Get all the necessary meta data.
|
||||||
bitem = self.listView.item(item.row())
|
bitem = self.listView.item(item.row())
|
||||||
book = self._decodeQtObject(bitem, 'book')
|
book = self._decodeQtObject(bitem, 'book')
|
||||||
chapter = int(self._decodeQtObject(bitem, 'chapter'))
|
chapter = int(self._decodeQtObject(bitem, 'chapter'))
|
||||||
verse = int(self._decodeQtObject(bitem, 'verse'))
|
verse = int(self._decodeQtObject(bitem, 'verse'))
|
||||||
bible = self._decodeQtObject(bitem, 'bible')
|
bible = self._decodeQtObject(bitem, 'bible')
|
||||||
dual_bible = self._decodeQtObject(bitem, 'dual_bible')
|
second_bible = self._decodeQtObject(bitem, 'second_bible')
|
||||||
old_bitem = self.listView.item(old_item.row())
|
old_bitem = self.listView.item(old_item.row())
|
||||||
old_book = self._decodeQtObject(old_bitem, 'book')
|
old_book = self._decodeQtObject(old_bitem, 'book')
|
||||||
old_chapter = int(self._decodeQtObject(old_bitem, 'chapter'))
|
old_chapter = int(self._decodeQtObject(old_bitem, 'chapter'))
|
||||||
old_verse = int(self._decodeQtObject(old_bitem, 'verse'))
|
old_verse = int(self._decodeQtObject(old_bitem, 'verse'))
|
||||||
old_bible = self._decodeQtObject(old_bitem, 'bible')
|
old_bible = self._decodeQtObject(old_bitem, 'bible')
|
||||||
old_dual_bible = self._decodeQtObject(old_bitem, 'dual_bible')
|
old_second_bible = self._decodeQtObject(old_bitem, 'second_bible')
|
||||||
if old_bible != bible or old_dual_bible != dual_bible or \
|
if old_bible != bible or old_second_bible != second_bible or \
|
||||||
old_book != book:
|
old_book != book:
|
||||||
|
# The bible, second bible or book has changed.
|
||||||
return True
|
return True
|
||||||
elif old_verse + 1 != verse and old_chapter == chapter:
|
elif old_verse + 1 != verse and old_chapter == chapter:
|
||||||
|
# We are still in the same chapter, but a verse has been skipped.
|
||||||
return True
|
return True
|
||||||
elif old_chapter + 1 == chapter and (verse != 1 or
|
elif old_chapter + 1 == chapter and (verse != 1 or
|
||||||
old_verse != self.parent.manager.get_verse_count(
|
old_verse != self.parent.manager.get_verse_count(
|
||||||
old_bible, old_book, old_chapter)):
|
old_bible, old_book, old_chapter)):
|
||||||
|
# We are in the following chapter, but the last verse was not the
|
||||||
|
# last verse of the chapter or the current verse is not the
|
||||||
|
# first one of the chapter.
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def formatVerse(self, old_chapter, chapter, verse):
|
def formatVerse(self, old_chapter, chapter, verse):
|
||||||
|
"""
|
||||||
|
Formats and returns the text, each verse starts with, for the given
|
||||||
|
chapter and verse. The text is either surrounded by round, square,
|
||||||
|
curly brackets or no brackets at all. For example::
|
||||||
|
|
||||||
|
u'{su}1:1{/su}'
|
||||||
|
|
||||||
|
``old_chapter``
|
||||||
|
The previous verse's chapter number (int).
|
||||||
|
|
||||||
|
``chapter``
|
||||||
|
The chapter number (int).
|
||||||
|
|
||||||
|
``verse``
|
||||||
|
The verse number (int).
|
||||||
|
"""
|
||||||
if not self.parent.settings_tab.show_new_chapters or \
|
if not self.parent.settings_tab.show_new_chapters or \
|
||||||
old_chapter != chapter:
|
old_chapter != chapter:
|
||||||
verse_text = u'%s:%s' % (chapter, verse)
|
verse_text = u'%s:%s' % (chapter, verse)
|
||||||
|
@ -46,7 +46,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
|||||||
Constructor
|
Constructor
|
||||||
"""
|
"""
|
||||||
QtGui.QDialog.__init__(self, parent)
|
QtGui.QDialog.__init__(self, parent)
|
||||||
#self.parent = parent
|
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
# Connecting signals and slots
|
# Connecting signals and slots
|
||||||
self.previewButton = QtGui.QPushButton()
|
self.previewButton = QtGui.QPushButton()
|
||||||
@ -124,8 +123,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
|||||||
self.slideListView.addItem(slide[1])
|
self.slideListView.addItem(slide[1])
|
||||||
theme = self.customSlide.theme_name
|
theme = self.customSlide.theme_name
|
||||||
id = self.themeComboBox.findText(theme, QtCore.Qt.MatchExactly)
|
id = self.themeComboBox.findText(theme, QtCore.Qt.MatchExactly)
|
||||||
|
# No theme match
|
||||||
if id == -1:
|
if id == -1:
|
||||||
id = 0 # Not Found
|
id = 0
|
||||||
self.themeComboBox.setCurrentIndex(id)
|
self.themeComboBox.setCurrentIndex(id)
|
||||||
else:
|
else:
|
||||||
self.themeComboBox.setCurrentIndex(0)
|
self.themeComboBox.setCurrentIndex(0)
|
||||||
@ -264,7 +264,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
|||||||
self.titleEdit.setFocus()
|
self.titleEdit.setFocus()
|
||||||
return False, translate('CustomPlugin.EditCustomForm',
|
return False, translate('CustomPlugin.EditCustomForm',
|
||||||
'You need to type in a title.')
|
'You need to type in a title.')
|
||||||
# We must have one slide.
|
# We must have at least one slide.
|
||||||
if self.slideListView.count() == 0:
|
if self.slideListView.count() == 0:
|
||||||
return False, translate('CustomPlugin.EditCustomForm',
|
return False, translate('CustomPlugin.EditCustomForm',
|
||||||
'You need to add at least one slide')
|
'You need to add at least one slide')
|
||||||
|
@ -67,7 +67,7 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
|
|||||||
|
|
||||||
def onSplitButtonPressed(self):
|
def onSplitButtonPressed(self):
|
||||||
"""
|
"""
|
||||||
Splits a slide in two slides.
|
Adds a slide split at the cursor.
|
||||||
"""
|
"""
|
||||||
if self.slideTextEdit.textCursor().columnNumber() != 0:
|
if self.slideTextEdit.textCursor().columnNumber() != 0:
|
||||||
self.slideTextEdit.insertPlainText(u'\n')
|
self.slideTextEdit.insertPlainText(u'\n')
|
||||||
|
@ -43,6 +43,7 @@ import logging
|
|||||||
|
|
||||||
from xml.dom.minidom import Document
|
from xml.dom.minidom import Document
|
||||||
from xml.etree.ElementTree import ElementTree, XML, dump
|
from xml.etree.ElementTree import ElementTree, XML, dump
|
||||||
|
from lxml import etree, objectify
|
||||||
from xml.parsers.expat import ExpatError
|
from xml.parsers.expat import ExpatError
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -55,14 +56,14 @@ class CustomXMLBuilder(object):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
Set up the song builder.
|
Set up the custom builder.
|
||||||
"""
|
"""
|
||||||
# Create the minidom document
|
# Create the minidom document
|
||||||
self.custom_xml = Document()
|
self.custom_xml = Document()
|
||||||
|
|
||||||
def new_document(self):
|
def new_document(self):
|
||||||
"""
|
"""
|
||||||
Create a new song XML document.
|
Create a new custom XML document.
|
||||||
"""
|
"""
|
||||||
# Create the <song> base element
|
# Create the <song> base element
|
||||||
self.song = self.custom_xml.createElement(u'song')
|
self.song = self.custom_xml.createElement(u'song')
|
||||||
@ -72,7 +73,7 @@ class CustomXMLBuilder(object):
|
|||||||
def add_lyrics_to_song(self):
|
def add_lyrics_to_song(self):
|
||||||
"""
|
"""
|
||||||
Set up and add a ``<lyrics>`` tag which contains the lyrics of the
|
Set up and add a ``<lyrics>`` tag which contains the lyrics of the
|
||||||
song.
|
custom item.
|
||||||
"""
|
"""
|
||||||
# Create the main <lyrics> element
|
# Create the main <lyrics> element
|
||||||
self.lyrics = self.custom_xml.createElement(u'lyrics')
|
self.lyrics = self.custom_xml.createElement(u'lyrics')
|
||||||
@ -93,7 +94,6 @@ class CustomXMLBuilder(object):
|
|||||||
``content``
|
``content``
|
||||||
The actual text of the verse to be stored.
|
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 = self.custom_xml.createElement(u'verse')
|
||||||
verse.setAttribute(u'type', type)
|
verse.setAttribute(u'type', type)
|
||||||
verse.setAttribute(u'label', number)
|
verse.setAttribute(u'label', number)
|
||||||
@ -102,7 +102,7 @@ class CustomXMLBuilder(object):
|
|||||||
cds = self.custom_xml.createCDATASection(content)
|
cds = self.custom_xml.createCDATASection(content)
|
||||||
verse.appendChild(cds)
|
verse.appendChild(cds)
|
||||||
|
|
||||||
def dump_xml(self):
|
def _dump_xml(self):
|
||||||
"""
|
"""
|
||||||
Debugging aid to dump XML so that we can see what we have.
|
Debugging aid to dump XML so that we can see what we have.
|
||||||
"""
|
"""
|
||||||
@ -110,29 +110,30 @@ class CustomXMLBuilder(object):
|
|||||||
|
|
||||||
def extract_xml(self):
|
def extract_xml(self):
|
||||||
"""
|
"""
|
||||||
Extract our newly created XML song.
|
Extract our newly created XML custom.
|
||||||
"""
|
"""
|
||||||
return self.custom_xml.toxml(u'utf-8')
|
return self.custom_xml.toxml(u'utf-8')
|
||||||
|
|
||||||
|
|
||||||
class CustomXMLParser(object):
|
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')
|
log.info(u'CustomXMLParser Loaded')
|
||||||
|
|
||||||
def __init__(self, xml):
|
def __init__(self, xml):
|
||||||
"""
|
"""
|
||||||
Set up our song XML parser.
|
Set up our custom XML parser.
|
||||||
|
|
||||||
``xml``
|
``xml``
|
||||||
The XML of the song to be parsed.
|
The XML of the custom to be parsed.
|
||||||
"""
|
"""
|
||||||
self.custom_xml = None
|
self.custom_xml = None
|
||||||
|
if xml[:5] == u'<?xml':
|
||||||
|
xml = xml[38:]
|
||||||
try:
|
try:
|
||||||
self.custom_xml = ElementTree(
|
self.custom_xml = objectify.fromstring(xml)
|
||||||
element=XML(unicode(xml).encode('unicode-escape')))
|
except etree.XMLSyntaxError:
|
||||||
except ExpatError:
|
|
||||||
log.exception(u'Invalid xml %s', xml)
|
log.exception(u'Invalid xml %s', xml)
|
||||||
|
|
||||||
def get_verses(self):
|
def get_verses(self):
|
||||||
@ -146,11 +147,10 @@ class CustomXMLParser(object):
|
|||||||
if element.tag == u'verse':
|
if element.tag == u'verse':
|
||||||
if element.text is None:
|
if element.text is None:
|
||||||
element.text = u''
|
element.text = u''
|
||||||
verse_list.append([element.attrib,
|
verse_list.append([element.attrib, unicode(element.text)])
|
||||||
unicode(element.text).decode('unicode-escape')])
|
|
||||||
return verse_list
|
return verse_list
|
||||||
|
|
||||||
def dump_xml(self):
|
def _dump_xml(self):
|
||||||
"""
|
"""
|
||||||
Debugging aid to dump XML so that we can see what we have.
|
Debugging aid to dump XML so that we can see what we have.
|
||||||
"""
|
"""
|
||||||
|
@ -74,9 +74,9 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
def initialise(self):
|
def initialise(self):
|
||||||
self.loadCustomListView(self.manager.get_all_objects(
|
self.loadCustomListView(self.manager.get_all_objects(
|
||||||
CustomSlide, order_by_ref=CustomSlide.title))
|
CustomSlide, order_by_ref=CustomSlide.title))
|
||||||
#Called to redisplay the song list screen edith from a search
|
# Called to redisplay the custom list screen edith from a search
|
||||||
#or from the exit of the Song edit dialog. If remote editing is active
|
# or from the exit of the Custom edit dialog. If remote editing is
|
||||||
#Trigger it and clean up so it will not update again.
|
# active trigger it and clean up so it will not update again.
|
||||||
if self.remoteTriggered == u'L':
|
if self.remoteTriggered == u'L':
|
||||||
self.onAddClick()
|
self.onAddClick()
|
||||||
if self.remoteTriggered == u'P':
|
if self.remoteTriggered == u'P':
|
||||||
@ -144,7 +144,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
for row in row_list:
|
for row in row_list:
|
||||||
self.listView.takeItem(row)
|
self.listView.takeItem(row)
|
||||||
|
|
||||||
def generateSlideData(self, service_item, item=None):
|
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
||||||
raw_slides = []
|
raw_slides = []
|
||||||
raw_footer = []
|
raw_footer = []
|
||||||
slide = None
|
slide = None
|
||||||
|
@ -154,7 +154,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
||||||
self.listView.addItem(item_name)
|
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()
|
items = self.listView.selectedIndexes()
|
||||||
if items:
|
if items:
|
||||||
service_item.title = unicode(
|
service_item.title = unicode(
|
||||||
@ -163,6 +163,8 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
||||||
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
||||||
service_item.add_capability(ItemCapabilities.AllowsAdditions)
|
service_item.add_capability(ItemCapabilities.AllowsAdditions)
|
||||||
|
# force a nonexistent theme
|
||||||
|
service_item.theme = -1
|
||||||
for item in items:
|
for item in items:
|
||||||
bitem = self.listView.item(item.row())
|
bitem = self.listView.item(item.row())
|
||||||
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
||||||
|
@ -116,7 +116,7 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
self.parent.liveController.display.video(filename, 0, True)
|
self.parent.liveController.display.video(filename, 0, True)
|
||||||
self.resetButton.setVisible(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:
|
if item is None:
|
||||||
item = self.listView.currentItem()
|
item = self.listView.currentItem()
|
||||||
if item is None:
|
if item is None:
|
||||||
|
@ -238,7 +238,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
SettingsManager.set_list(self.settingsSection,
|
SettingsManager.set_list(self.settingsSection,
|
||||||
self.settingsSection, self.getFileList())
|
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
|
Load the relevant information for displaying the presentation
|
||||||
in the slidecontroller. In the case of powerpoints, an image
|
in the slidecontroller. In the case of powerpoints, an image
|
||||||
|
@ -650,8 +650,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
self.song.title = unicode(self.TitleEditItem.text())
|
self.song.title = unicode(self.TitleEditItem.text())
|
||||||
self.song.alternate_title = unicode(self.AlternativeEdit.text())
|
self.song.alternate_title = unicode(self.AlternativeEdit.text())
|
||||||
self.song.copyright = unicode(self.CopyrightEditItem.text())
|
self.song.copyright = unicode(self.CopyrightEditItem.text())
|
||||||
self.song.search_title = self.song.title + u'@' + \
|
if self.song.alternate_title:
|
||||||
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.comments = unicode(self.CommentsEdit.toPlainText())
|
||||||
self.song.verse_order = unicode(self.VerseOrderEdit.text())
|
self.song.verse_order = unicode(self.VerseOrderEdit.text())
|
||||||
self.song.ccli_number = unicode(self.CCLNumberEdit.text())
|
self.song.ccli_number = unicode(self.CCLNumberEdit.text())
|
||||||
@ -662,6 +665,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
Book.name == book_name)
|
Book.name == book_name)
|
||||||
else:
|
else:
|
||||||
self.song.book = None
|
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():
|
if self._validate_song():
|
||||||
self.processLyrics()
|
self.processLyrics()
|
||||||
self.processTitle()
|
self.processTitle()
|
||||||
|
@ -507,8 +507,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
|
|||||||
filenames=self.getListOfFiles(
|
filenames=self.getListOfFiles(
|
||||||
self.songBeamerFileListWidget)
|
self.songBeamerFileListWidget)
|
||||||
)
|
)
|
||||||
success = importer.do_import()
|
if importer.do_import():
|
||||||
if success:
|
|
||||||
# reload songs
|
# reload songs
|
||||||
self.importProgressLabel.setText(
|
self.importProgressLabel.setText(
|
||||||
translate('SongsPlugin.SongImportForm', 'Finished import.'))
|
translate('SongsPlugin.SongImportForm', 'Finished import.'))
|
||||||
|
@ -62,6 +62,36 @@ class VerseType(object):
|
|||||||
elif verse_type == VerseType.Other:
|
elif verse_type == VerseType.Other:
|
||||||
return translate('SongsPlugin.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
|
@staticmethod
|
||||||
def from_string(verse_type):
|
def from_string(verse_type):
|
||||||
"""
|
"""
|
||||||
@ -92,7 +122,6 @@ class VerseType(object):
|
|||||||
unicode(VerseType.to_string(VerseType.Other)).lower():
|
unicode(VerseType.to_string(VerseType.Other)).lower():
|
||||||
return VerseType.Other
|
return VerseType.Other
|
||||||
|
|
||||||
|
from xml import LyricsXML, SongXMLBuilder, SongXMLParser, OpenLyricsParser
|
||||||
from xml import LyricsXML, SongXMLBuilder, SongXMLParser
|
|
||||||
from songstab import SongsTab
|
from songstab import SongsTab
|
||||||
from mediaitem import SongMediaItem
|
from mediaitem import SongMediaItem
|
||||||
|
@ -32,7 +32,7 @@ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \
|
|||||||
ItemCapabilities, translate, check_item_selected
|
ItemCapabilities, translate, check_item_selected
|
||||||
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
|
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
|
||||||
SongImportForm
|
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
|
from openlp.plugins.songs.lib.db import Author, Song
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -53,8 +53,8 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
self.ListViewWithDnD_class = SongListView
|
self.ListViewWithDnD_class = SongListView
|
||||||
MediaManagerItem.__init__(self, parent, self, icon)
|
MediaManagerItem.__init__(self, parent, self, icon)
|
||||||
self.edit_song_form = EditSongForm(self, self.parent.manager)
|
self.edit_song_form = EditSongForm(self, self.parent.manager)
|
||||||
|
self.openLyrics = OpenLyricsParser(self.parent.manager)
|
||||||
self.singleServiceItem = False
|
self.singleServiceItem = False
|
||||||
#self.edit_song_form = EditSongForm(self.parent.manager, self)
|
|
||||||
self.song_maintenance_form = SongMaintenanceForm(
|
self.song_maintenance_form = SongMaintenanceForm(
|
||||||
self.parent.manager, self)
|
self.parent.manager, self)
|
||||||
# Holds information about whether the edit is remotly triggered and
|
# Holds information about whether the edit is remotly triggered and
|
||||||
@ -114,6 +114,8 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
self.SearchButtonLayout.addWidget(self.ClearTextButton)
|
self.SearchButtonLayout.addWidget(self.ClearTextButton)
|
||||||
self.pageLayout.addLayout(self.SearchButtonLayout)
|
self.pageLayout.addLayout(self.SearchButtonLayout)
|
||||||
# Signals and slots
|
# Signals and slots
|
||||||
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
QtCore.SIGNAL(u'plugin_list_refresh'), self.onSearchTextButtonClick)
|
||||||
QtCore.QObject.connect(self.SearchTextEdit,
|
QtCore.QObject.connect(self.SearchTextEdit,
|
||||||
QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick)
|
QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick)
|
||||||
QtCore.QObject.connect(self.SearchTextButton,
|
QtCore.QObject.connect(self.SearchTextButton,
|
||||||
@ -141,7 +143,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
self.updateServiceOnEdit = QtCore.QSettings().value(
|
self.updateServiceOnEdit = QtCore.QSettings().value(
|
||||||
self.settingsSection + u'/update service on edit',
|
self.settingsSection + u'/update service on edit',
|
||||||
QtCore.QVariant(u'False')).toBool()
|
QtCore.QVariant(u'False')).toBool()
|
||||||
self.AddSongFromServide = QtCore.QSettings().value(
|
self.addSongFromService = QtCore.QSettings().value(
|
||||||
self.settingsSection + u'/add song from service',
|
self.settingsSection + u'/add song from service',
|
||||||
QtCore.QVariant(u'True')).toBool()
|
QtCore.QVariant(u'True')).toBool()
|
||||||
|
|
||||||
@ -328,7 +330,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
self.parent.manager.delete_object(Song, item_id)
|
self.parent.manager.delete_object(Song, item_id)
|
||||||
self.onSearchTextButtonClick()
|
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))
|
log.debug(u'generateSlideData (%s:%s)' % (service_item, item))
|
||||||
raw_footer = []
|
raw_footer = []
|
||||||
author_list = u''
|
author_list = u''
|
||||||
@ -355,7 +357,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
if song.lyrics.startswith(u'<?xml version='):
|
if song.lyrics.startswith(u'<?xml version='):
|
||||||
songXML = SongXMLParser(song.lyrics)
|
songXML = SongXMLParser(song.lyrics)
|
||||||
verseList = songXML.get_verses()
|
verseList = songXML.get_verses()
|
||||||
#no verse list or only 1 space (in error)
|
# no verse list or only 1 space (in error)
|
||||||
if not song.verse_order or not song.verse_order.strip():
|
if not song.verse_order or not song.verse_order.strip():
|
||||||
for verse in verseList:
|
for verse in verseList:
|
||||||
verseTag = u'%s:%s' % (
|
verseTag = u'%s:%s' % (
|
||||||
@ -397,6 +399,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
]
|
]
|
||||||
service_item.data_string = {u'title':song.search_title,
|
service_item.data_string = {u'title':song.search_title,
|
||||||
u'authors':author_list}
|
u'authors':author_list}
|
||||||
|
service_item.xml_version = self.openLyrics.song_to_xml(song)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def serviceLoad(self, item):
|
def serviceLoad(self, item):
|
||||||
@ -406,21 +409,31 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
log.debug(u'serviceLoad')
|
log.debug(u'serviceLoad')
|
||||||
if item.data_string:
|
if item.data_string:
|
||||||
search_results = self.parent.manager.get_all_objects(Song,
|
search_results = self.parent.manager.get_all_objects(Song,
|
||||||
Song.search_title.like(u'%' +
|
Song.search_title ==
|
||||||
item.data_string[u'title'].split(u'@')[0] + u'%'),
|
item.data_string[u'title'].split(u'@')[0].lower() ,
|
||||||
Song.search_title.asc())
|
Song.search_title.asc())
|
||||||
author_list = item.data_string[u'authors'].split(u', ')
|
author_list = item.data_string[u'authors'].split(u', ')
|
||||||
editId = 0
|
editId = 0
|
||||||
uuid = 0
|
uuid = item._uuid
|
||||||
if search_results:
|
if search_results:
|
||||||
for song in search_results:
|
for song in search_results:
|
||||||
count = 0
|
count = 0
|
||||||
for author in song.authors:
|
for author in song.authors:
|
||||||
if author.display_name in author_list:
|
if author.display_name in author_list:
|
||||||
count += 1
|
count += 1
|
||||||
|
# All Authors the same
|
||||||
if count == len(author_list):
|
if count == len(author_list):
|
||||||
editId = song.id
|
editId = song.id
|
||||||
uuid = item._uuid
|
else:
|
||||||
|
# Authors different
|
||||||
|
if self.addSongFromService:
|
||||||
|
editId = self.openLyrics. \
|
||||||
|
xml_to_song(item.xml_version)
|
||||||
|
else:
|
||||||
|
# Title does not match
|
||||||
|
if self.addSongFromService:
|
||||||
|
editId = self.openLyrics.xml_to_song(item.xml_version)
|
||||||
|
# Update service with correct song id
|
||||||
if editId != 0:
|
if editId != 0:
|
||||||
Receiver.send_message(u'service_item_update',
|
Receiver.send_message(u'service_item_update',
|
||||||
u'%s:%s' %(editId, uuid))
|
u'%s:%s' %(editId, uuid))
|
||||||
|
@ -57,15 +57,17 @@ class SongBeamerTypes(object):
|
|||||||
u'Unknown': u'O'
|
u'Unknown': u'O'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SongBeamerImport(SongImport):
|
class SongBeamerImport(SongImport):
|
||||||
"""
|
"""
|
||||||
Import Song Beamer files(s)
|
Import Song Beamer files(s)
|
||||||
Song Beamer file format is text based
|
Song Beamer file format is text based
|
||||||
in the beginning are one or more control tags written
|
in the beginning are one or more control tags written
|
||||||
"""
|
"""
|
||||||
def __init__(self, master_manager, **kwargs):
|
def __init__(self, master_manager, **kwargs):
|
||||||
"""
|
"""
|
||||||
Initialise the import.
|
Initialise the import.
|
||||||
|
|
||||||
``master_manager``
|
``master_manager``
|
||||||
The song manager for the running OpenLP installation.
|
The song manager for the running OpenLP installation.
|
||||||
"""
|
"""
|
||||||
@ -88,6 +90,7 @@ class SongBeamerImport(SongImport):
|
|||||||
# TODO: check that it is a valid SongBeamer file
|
# TODO: check that it is a valid SongBeamer file
|
||||||
self.current_verse = u''
|
self.current_verse = u''
|
||||||
self.current_verse_type = u'V'
|
self.current_verse_type = u'V'
|
||||||
|
read_verses = False
|
||||||
self.file_name = os.path.split(file)[1]
|
self.file_name = os.path.split(file)[1]
|
||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
"Importing %s" % (self.file_name), 0)
|
"Importing %s" % (self.file_name), 0)
|
||||||
@ -100,134 +103,182 @@ class SongBeamerImport(SongImport):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
for line in self.songData:
|
for line in self.songData:
|
||||||
line = line.strip()
|
# Just make sure that the line is of the type 'Unicode'.
|
||||||
if line.startswith('#'):
|
line = unicode(line).strip()
|
||||||
log.debug(u'find tag: %s' % line)
|
if line.startswith(u'#') and not read_verses:
|
||||||
if not self.parse_tags(line):
|
self.parse_tags(line)
|
||||||
return False
|
elif line.startswith(u'---'):
|
||||||
elif line.startswith('---'):
|
if self.current_verse:
|
||||||
log.debug(u'find ---')
|
self.replace_html_tags()
|
||||||
if len(self.current_verse) > 0:
|
|
||||||
self.add_verse(self.current_verse,
|
self.add_verse(self.current_verse,
|
||||||
self.current_verse_type)
|
self.current_verse_type)
|
||||||
self.current_verse = u''
|
self.current_verse = u''
|
||||||
self.current_verse_type = u'V'
|
self.current_verse_type = u'V'
|
||||||
self.read_verse = True
|
read_verses = True
|
||||||
self.verse_start = True
|
verse_start = True
|
||||||
elif self.read_verse:
|
elif read_verses:
|
||||||
if self.verse_start:
|
if verse_start:
|
||||||
self.check_verse_marks(line)
|
verse_start = False
|
||||||
self.verse_start = False
|
if not self.check_verse_marks(line):
|
||||||
|
self.current_verse = u'%s\n' % line
|
||||||
else:
|
else:
|
||||||
self.current_verse += u'%s\n' % line
|
self.current_verse += u'%s\n' % line
|
||||||
if len(self.current_verse) > 0:
|
if self.current_verse:
|
||||||
|
self.replace_html_tags()
|
||||||
self.add_verse(self.current_verse, self.current_verse_type)
|
self.add_verse(self.current_verse, self.current_verse_type)
|
||||||
self.finish()
|
self.finish()
|
||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
"Importing %s" % (self.file_name))
|
"Importing %s" % (self.file_name))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def replace_html_tags(self):
|
||||||
|
"""
|
||||||
|
This can be called to replace SongBeamer's specific (html) tags with
|
||||||
|
OpenLP's specific (html) tags.
|
||||||
|
"""
|
||||||
|
tag_pairs = [
|
||||||
|
(u'<b>', u'{st}'),
|
||||||
|
(u'</b>', u'{/st}'),
|
||||||
|
(u'<i>', u'{it}'),
|
||||||
|
(u'</i>', u'{/it}'),
|
||||||
|
(u'<u>', u'{u}'),
|
||||||
|
(u'</u>', u'{/u}'),
|
||||||
|
(u'<br>', u'{st}'),
|
||||||
|
(u'</br>', u'{st}'),
|
||||||
|
(u'</ br>', u'{st}'),
|
||||||
|
(u'<p>', u'{p}'),
|
||||||
|
(u'</p>', u'{/p}'),
|
||||||
|
(u'<super>', u'{su}'),
|
||||||
|
(u'</super>', u'{/su}'),
|
||||||
|
(u'<sub>', u'{sb}'),
|
||||||
|
(u'</sub>', u'{/sb}'),
|
||||||
|
(u'<wordwrap>', u''),
|
||||||
|
(u'</wordwrap>', u''),
|
||||||
|
(u'<strike>', u''),
|
||||||
|
(u'</strike>', u'')
|
||||||
|
]
|
||||||
|
for pair in tag_pairs:
|
||||||
|
self.current_verse = self.current_verse.replace(pair[0], pair[1])
|
||||||
|
# TODO: check for unsupported tags (see wiki) and remove them as well.
|
||||||
|
|
||||||
def parse_tags(self, line):
|
def parse_tags(self, line):
|
||||||
tag_val = line.split('=')
|
"""
|
||||||
if len(tag_val[0]) == 0 or len(tag_val[1]) == 0:
|
Parses a meta data line.
|
||||||
return True
|
|
||||||
if tag_val[0] == '#(c)':
|
``line``
|
||||||
|
The line in the file. It should consist of a tag and a value
|
||||||
|
for this tag (unicode)::
|
||||||
|
|
||||||
|
u'#Title=Nearer my God to Thee'
|
||||||
|
"""
|
||||||
|
tag_val = line.split(u'=', 1)
|
||||||
|
if len(tag_val) == 1:
|
||||||
|
return
|
||||||
|
if not tag_val[0] or not tag_val[1]:
|
||||||
|
return
|
||||||
|
if tag_val[0] == u'#(c)':
|
||||||
self.add_copyright(tag_val[1])
|
self.add_copyright(tag_val[1])
|
||||||
elif tag_val[0] == '#AddCopyrightInfo':
|
elif tag_val[0] == u'#AddCopyrightInfo':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Author':
|
elif tag_val[0] == u'#Author':
|
||||||
#TODO split Authors
|
self.parse_author(tag_val[1])
|
||||||
self.add_author(tag_val[1])
|
elif tag_val[0] == u'#BackgroundImage':
|
||||||
elif tag_val[0] == '#BackgroundImage':
|
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Bible':
|
elif tag_val[0] == u'#Bible':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Categories':
|
elif tag_val[0] == u'#Categories':
|
||||||
self.topics = line.split(',')
|
self.topics = line.split(',')
|
||||||
elif tag_val[0] == '#CCLI':
|
elif tag_val[0] == u'#CCLI':
|
||||||
self.ccli_number = tag_val[1]
|
self.ccli_number = tag_val[1]
|
||||||
elif tag_val[0] == '#Chords':
|
elif tag_val[0] == u'#Chords':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#ChurchSongID':
|
elif tag_val[0] == u'#ChurchSongID':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#ColorChords':
|
elif tag_val[0] == u'#ColorChords':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Comments':
|
elif tag_val[0] == u'#Comments':
|
||||||
self.comments = tag_val[1]
|
self.comments = tag_val[1]
|
||||||
elif tag_val[0] == '#Editor':
|
elif tag_val[0] == u'#Editor':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Font':
|
elif tag_val[0] == u'#Font':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#FontLang2':
|
elif tag_val[0] == u'#FontLang2':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#FontSize':
|
elif tag_val[0] == u'#FontSize':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Format':
|
elif tag_val[0] == u'#Format':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Format_PreLine':
|
elif tag_val[0] == u'#Format_PreLine':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Format_PrePage':
|
elif tag_val[0] == u'#Format_PrePage':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#ID':
|
elif tag_val[0] == u'#ID':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Key':
|
elif tag_val[0] == u'#Key':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Keywords':
|
elif tag_val[0] == u'#Keywords':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#LangCount':
|
elif tag_val[0] == u'#LangCount':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Melody':
|
elif tag_val[0] == u'#Melody':
|
||||||
#TODO split Authors
|
self.parse_author(tag_val[1])
|
||||||
self.add_author(tag_val[1])
|
elif tag_val[0] == u'#NatCopyright':
|
||||||
elif tag_val[0] == '#NatCopyright':
|
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#OTitle':
|
elif tag_val[0] == u'#OTitle':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#OutlineColor':
|
elif tag_val[0] == u'#OutlineColor':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#OutlinedFont':
|
elif tag_val[0] == u'#OutlinedFont':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#QuickFind':
|
elif tag_val[0] == u'#QuickFind':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Rights':
|
elif tag_val[0] == u'#Rights':
|
||||||
song_book_pub = tag_val[1]
|
song_book_pub = tag_val[1]
|
||||||
elif tag_val[0] == '#Songbook':
|
elif tag_val[0] == u'#Songbook':
|
||||||
book_num = tag_val[1].split(' / ')
|
book_num = tag_val[1].split(' / ')
|
||||||
self.song_book_name = book_num[0]
|
self.song_book_name = book_num[0]
|
||||||
if len(book_num) == book_num[1]:
|
if len(book_num) == book_num[1]:
|
||||||
self.song_number = u''
|
self.song_number = u''
|
||||||
elif tag_val[0] == '#Speed':
|
elif tag_val[0] == u'#Speed':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#TextAlign':
|
elif tag_val[0] == u'#TextAlign':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Title':
|
elif tag_val[0] == u'#Title':
|
||||||
self.title = u'%s' % tag_val[1]
|
self.title = u'%s' % tag_val[1]
|
||||||
elif tag_val[0] == '#TitleAlign':
|
elif tag_val[0] == u'#TitleAlign':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#TitleFontSize':
|
elif tag_val[0] == u'#TitleFontSize':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#TitleLang2':
|
elif tag_val[0] == u'#TitleLang2':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#TitleLang3':
|
elif tag_val[0] == u'#TitleLang3':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#TitleLang4':
|
elif tag_val[0] == u'#TitleLang4':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Translation':
|
elif tag_val[0] == u'#Translation':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Transpose':
|
elif tag_val[0] == u'#Transpose':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#TransposeAccidental':
|
elif tag_val[0] == u'#TransposeAccidental':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == '#Version':
|
elif tag_val[0] == u'#Version':
|
||||||
pass
|
pass
|
||||||
else:
|
|
||||||
pass
|
|
||||||
return True
|
|
||||||
|
|
||||||
def check_verse_marks(self, line):
|
def check_verse_marks(self, line):
|
||||||
marks = line.split(' ')
|
"""
|
||||||
|
Check and add the verse's MarkType. Returns ``True`` if the given line
|
||||||
|
contains a correct verse mark otherwise ``False``.
|
||||||
|
|
||||||
|
``line``
|
||||||
|
The line to check for marks (unicode).
|
||||||
|
"""
|
||||||
|
marks = line.split(u' ')
|
||||||
if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes:
|
if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes:
|
||||||
self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]]
|
self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]]
|
||||||
if len(marks) == 2:
|
if len(marks) == 2:
|
||||||
#TODO: may check, because of only digits are allowed
|
# If we have a digit, we append it to current_verse_type.
|
||||||
self.current_verse_type += marks[1]
|
if marks[1].isdigit():
|
||||||
|
self.current_verse_type += marks[1]
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
@ -254,7 +254,8 @@ class SongImport(QtCore.QObject):
|
|||||||
All fields have been set to this song. Write it away
|
All fields have been set to this song. Write it away
|
||||||
"""
|
"""
|
||||||
if not self.authors:
|
if not self.authors:
|
||||||
self.authors.append(u'Author unknown')
|
self.authors.append(unicode(translate('SongsPlugin.SongImport',
|
||||||
|
'Author unknown')))
|
||||||
self.commit_song()
|
self.commit_song()
|
||||||
|
|
||||||
def commit_song(self):
|
def commit_song(self):
|
||||||
|
@ -39,8 +39,11 @@ The basic XML is of the format::
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
from lxml import etree, objectify
|
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__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -77,7 +80,6 @@ class SongXMLBuilder(object):
|
|||||||
``content``
|
``content``
|
||||||
The actual text of the verse to be stored.
|
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),
|
verse = etree.Element(u'verse', type = unicode(type),
|
||||||
label = unicode(number))
|
label = unicode(number))
|
||||||
verse.text = etree.CDATA(content)
|
verse.text = etree.CDATA(content)
|
||||||
@ -239,3 +241,153 @@ class LyricsXML(object):
|
|||||||
song_output = u'<?xml version="1.0" encoding="UTF-8"?>' + \
|
song_output = u'<?xml version="1.0" encoding="UTF-8"?>' + \
|
||||||
u'<song version="1.0">%s</song>' % lyrics_output
|
u'<song version="1.0">%s</song>' % lyrics_output
|
||||||
return song_output
|
return song_output
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
song_xml_parser = SongXMLParser(song.lyrics)
|
||||||
|
verse_list = song_xml_parser.get_verses()
|
||||||
|
song_xml = objectify.fromstring(
|
||||||
|
u'<song version="0.7" createdIn="OpenLP 2.0"/>')
|
||||||
|
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 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, 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)
|
||||||
|
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'<?xml':
|
||||||
|
xml = xml[38:]
|
||||||
|
song_xml = objectify.fromstring(xml)
|
||||||
|
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
|
||||||
|
try:
|
||||||
|
song.ccli_number = unicode(properties.ccliNo.text)
|
||||||
|
except:
|
||||||
|
song.ccli_number = u''
|
||||||
|
try:
|
||||||
|
theme_name = unicode(properties.themes.theme)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if theme_name:
|
||||||
|
song.theme_name = theme_name
|
||||||
|
else:
|
||||||
|
song.theme_name = u''
|
||||||
|
# Process Titles
|
||||||
|
for title in properties.titles.title:
|
||||||
|
if not song.title:
|
||||||
|
song.title = unicode(title.text)
|
||||||
|
song.search_title = unicode(song.title)
|
||||||
|
song.alternate_title = u''
|
||||||
|
else:
|
||||||
|
song.alternate_title = unicode(title.text)
|
||||||
|
song.search_title += u'@' + song.alternate_title
|
||||||
|
song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'',
|
||||||
|
unicode(song.search_title)).lower()
|
||||||
|
# Process Lyrics
|
||||||
|
sxml = SongXMLBuilder()
|
||||||
|
search_text = u''
|
||||||
|
for lyrics in song_xml.lyrics:
|
||||||
|
for verse in song_xml.lyrics.verse:
|
||||||
|
text = u''
|
||||||
|
for line in verse.lines.line:
|
||||||
|
line = unicode(line)
|
||||||
|
if not text:
|
||||||
|
text = line
|
||||||
|
else:
|
||||||
|
text += u'\n' + line
|
||||||
|
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')
|
||||||
|
song.comments = u''
|
||||||
|
song.song_number = u''
|
||||||
|
# Process Authors
|
||||||
|
for author in properties.authors.author:
|
||||||
|
self._process_author(author.text, song)
|
||||||
|
self.manager.save_object(song)
|
||||||
|
return song.id
|
||||||
|
|
||||||
|
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 _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)
|
||||||
|
|
||||||
|
def _process_author(self, name, song):
|
||||||
|
"""
|
||||||
|
Find or create an Author from display_name.
|
||||||
|
"""
|
||||||
|
name = unicode(name)
|
||||||
|
author = self.manager.get_object_filtered(Author,
|
||||||
|
Author.display_name == name)
|
||||||
|
if author:
|
||||||
|
# should only be one! so take the first
|
||||||
|
song.authors.append(author)
|
||||||
|
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)
|
||||||
|
song.authors.append(new_author)
|
||||||
|
Loading…
Reference in New Issue
Block a user