forked from openlp/openlp
Head
This commit is contained in:
commit
8a029daf11
@ -33,7 +33,8 @@ from urllib import quote_plus as urlquote
|
||||
|
||||
from PyQt4 import QtCore
|
||||
from sqlalchemy import Table, MetaData, Column, types, create_engine
|
||||
from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, DBAPIError
|
||||
from sqlalchemy.exc import SQLAlchemyError, InvalidRequestError, DBAPIError, \
|
||||
OperationalError
|
||||
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
|
||||
from sqlalchemy.pool import NullPool
|
||||
|
||||
|
@ -217,6 +217,9 @@ class EventReceiver(QtCore.QObject):
|
||||
Ask the plugin to process an individual service item after it has been
|
||||
loaded.
|
||||
|
||||
``{plugin}_config_updated``
|
||||
The config has changed so tell the plugin about it.
|
||||
|
||||
``alerts_text``
|
||||
Displays an alert message.
|
||||
|
||||
|
@ -166,7 +166,7 @@ class ImageManager(QtCore.QObject):
|
||||
self.height = current_screen[u'size'].height()
|
||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||
# stream to None.
|
||||
for key, image in self._cache.iteritems():
|
||||
for image in self._cache.values():
|
||||
self._reset_image(image)
|
||||
|
||||
def update_images(self, image_type, background):
|
||||
@ -176,7 +176,7 @@ class ImageManager(QtCore.QObject):
|
||||
log.debug(u'update_images')
|
||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||
# stream to None.
|
||||
for key, image in self._cache.iteritems():
|
||||
for image in self._cache.values():
|
||||
if image.source == image_type:
|
||||
image.background = background
|
||||
self._reset_image(image)
|
||||
@ -188,7 +188,7 @@ class ImageManager(QtCore.QObject):
|
||||
log.debug(u'update_images')
|
||||
# Mark the images as dirty for a rebuild by setting the image and byte
|
||||
# stream to None.
|
||||
for key, image in self._cache.iteritems():
|
||||
for image in self._cache.values():
|
||||
if image.source == image_type and image.name == name:
|
||||
image.background = background
|
||||
self._reset_image(image)
|
||||
|
@ -641,7 +641,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
if item:
|
||||
self.autoSelectId = item.data(QtCore.Qt.UserRole).toInt()[0]
|
||||
|
||||
def search(self, string):
|
||||
def search(self, string, showError=True):
|
||||
"""
|
||||
Performs a plugin specific search for items containing ``string``
|
||||
"""
|
||||
|
@ -173,6 +173,9 @@ class Plugin(QtCore.QObject):
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'%s_add_service_item' % self.name),
|
||||
self.processAddServiceEvent)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'%s_config_updated' % self.name),
|
||||
self.configUpdated)
|
||||
|
||||
def checkPreConditions(self):
|
||||
"""
|
||||
@ -395,3 +398,9 @@ class Plugin(QtCore.QObject):
|
||||
Add html code to htmlbuilder.
|
||||
"""
|
||||
return u''
|
||||
|
||||
def configUpdated(self):
|
||||
"""
|
||||
The plugin's config has changed
|
||||
"""
|
||||
pass
|
||||
|
@ -300,6 +300,7 @@ class ServiceItem(object):
|
||||
``path``
|
||||
Defaults to *None*. Any path data, usually for images.
|
||||
"""
|
||||
log.debug(u'set_from_service called with path %s' % path)
|
||||
header = serviceitem[u'serviceitem'][u'header']
|
||||
self.title = header[u'title']
|
||||
self.name = header[u'name']
|
||||
@ -325,7 +326,10 @@ class ServiceItem(object):
|
||||
if u'media_length' in header:
|
||||
self.media_length = header[u'media_length']
|
||||
if u'background_audio' in header:
|
||||
self.background_audio = header[u'background_audio']
|
||||
self.background_audio = []
|
||||
for filename in header[u'background_audio']:
|
||||
# Give them real file paths
|
||||
self.background_audio.append(os.path.join(path, filename))
|
||||
self.theme_overwritten = header.get(u'theme_overwritten', False)
|
||||
if self.service_item_type == ServiceItemType.Text:
|
||||
for slide in serviceitem[u'serviceitem'][u'data']:
|
||||
|
@ -53,13 +53,10 @@ class AdvancedTab(SettingsTab):
|
||||
self.defaultServiceMinute = 0
|
||||
self.defaultServiceName = unicode(translate('OpenLP.AdvancedTab',
|
||||
'Service %Y-%m-%d %H-%M',
|
||||
'This is the default default service name template, which can be '
|
||||
'found under Advanced in Settings, Configure OpenLP. Please do not '
|
||||
'include any of the following characters: /\\?*|<>\[\]":+\n'
|
||||
'You can use any of the directives as shown on page '
|
||||
'http://docs.python.org/library/datetime.html'
|
||||
'#strftime-strptime-behavior , but if possible, please keep '
|
||||
'the resulting string sortable by name.'))
|
||||
'This may not contain any of the following characters: '
|
||||
'/\\?*|<>\[\]":+\n'
|
||||
'See http://docs.python.org/library/datetime.html'
|
||||
'#strftime-strptime-behavior for more information.'))
|
||||
self.defaultImage = u':/graphics/openlp-splash-screen.png'
|
||||
self.defaultColor = u'#ffffff'
|
||||
self.icon_path = u':/system/system_settings.png'
|
||||
|
@ -295,7 +295,8 @@ class GeneralTab(SettingsTab):
|
||||
QtCore.QVariant(False)).toBool())
|
||||
self.timeoutSpinBox.setValue(settings.value(u'loop delay',
|
||||
QtCore.QVariant(5)).toInt()[0])
|
||||
self.monitorRadioButton.setChecked(not settings.value(u'override position',
|
||||
self.monitorRadioButton.setChecked(
|
||||
not settings.value(u'override position',
|
||||
QtCore.QVariant(False)).toBool())
|
||||
self.overrideRadioButton.setChecked(settings.value(u'override position',
|
||||
QtCore.QVariant(False)).toBool())
|
||||
@ -313,11 +314,14 @@ class GeneralTab(SettingsTab):
|
||||
u'audio repeat list', QtCore.QVariant(False)).toBool())
|
||||
settings.endGroup()
|
||||
self.monitorComboBox.setDisabled(self.overrideRadioButton.isChecked())
|
||||
self.displayOnMonitorCheck.setDisabled(self.overrideRadioButton.isChecked())
|
||||
self.displayOnMonitorCheck.setDisabled(
|
||||
self.overrideRadioButton.isChecked())
|
||||
self.customXValueEdit.setEnabled(self.overrideRadioButton.isChecked())
|
||||
self.customYValueEdit.setEnabled(self.overrideRadioButton.isChecked())
|
||||
self.customHeightValueEdit.setEnabled(self.overrideRadioButton.isChecked())
|
||||
self.customWidthValueEdit.setEnabled(self.overrideRadioButton.isChecked())
|
||||
self.customHeightValueEdit.setEnabled(
|
||||
self.overrideRadioButton.isChecked())
|
||||
self.customWidthValueEdit.setEnabled(
|
||||
self.overrideRadioButton.isChecked())
|
||||
self.display_changed = False
|
||||
settings.beginGroup(self.settingsSection)
|
||||
|
||||
|
@ -150,6 +150,11 @@ class MediaController(object):
|
||||
if self.curDisplayMediaPlayer[display] \
|
||||
.state == MediaState.Playing:
|
||||
return
|
||||
# no players are active anymore
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
if self.curDisplayMediaPlayer[display] \
|
||||
.state != MediaState.Paused:
|
||||
display.controller.seekSlider.setSliderPosition(0)
|
||||
self.timer.stop()
|
||||
|
||||
def get_media_display_css(self):
|
||||
@ -271,7 +276,8 @@ class MediaController(object):
|
||||
controller.mediabar.setVisible(value)
|
||||
if controller.isLive and controller.display:
|
||||
if self.curDisplayMediaPlayer and value:
|
||||
if self.curDisplayMediaPlayer[controller.display] != self.mediaPlayers[u'webkit']:
|
||||
if self.curDisplayMediaPlayer[controller.display] != \
|
||||
self.mediaPlayers[u'webkit']:
|
||||
controller.display.setTransparency(False)
|
||||
# Special controls: Here media type specific Controls will be enabled
|
||||
# (e.g. for DVD control, ...)
|
||||
@ -437,6 +443,7 @@ class MediaController(object):
|
||||
display.frame.evaluateJavaScript(u'show_blank("black");')
|
||||
self.curDisplayMediaPlayer[display].stop(display)
|
||||
self.curDisplayMediaPlayer[display].set_visible(display, False)
|
||||
controller.seekSlider.setSliderPosition(0)
|
||||
|
||||
def video_volume(self, msg):
|
||||
"""
|
||||
|
@ -57,7 +57,7 @@ ADDITIONAL_EXT = {
|
||||
|
||||
class PhononPlayer(MediaPlayer):
|
||||
"""
|
||||
A specialised version of the MediaPlayer class, which provides a Phonon
|
||||
A specialised version of the MediaPlayer class, which provides a Phonon
|
||||
display.
|
||||
"""
|
||||
|
||||
@ -192,6 +192,9 @@ class PhononPlayer(MediaPlayer):
|
||||
display.phononWidget.setVisible(status)
|
||||
|
||||
def update_ui(self, display):
|
||||
if display.mediaObject.state() == Phonon.PausedState and \
|
||||
self.state != MediaState.Paused:
|
||||
self.stop(display)
|
||||
controller = display.controller
|
||||
if controller.media_info.end_time > 0:
|
||||
if display.mediaObject.currentTime() > \
|
||||
|
@ -83,7 +83,7 @@ VIDEO_EXT = [
|
||||
|
||||
class VlcPlayer(MediaPlayer):
|
||||
"""
|
||||
A specialised version of the MediaPlayer class, which provides a QtWebKit
|
||||
A specialised version of the MediaPlayer class, which provides a VLC
|
||||
display.
|
||||
"""
|
||||
|
||||
@ -122,7 +122,7 @@ class VlcPlayer(MediaPlayer):
|
||||
display.vlcMediaPlayer.set_hwnd(int(display.vlcWidget.winId()))
|
||||
elif sys.platform == "darwin": # for MacOS
|
||||
display.vlcMediaPlayer.set_agl(int(display.vlcWidget.winId()))
|
||||
else:
|
||||
else:
|
||||
# for Linux using the X Server
|
||||
display.vlcMediaPlayer.set_xwindow(int(display.vlcWidget.winId()))
|
||||
self.hasOwnWidget = True
|
||||
@ -210,6 +210,8 @@ class VlcPlayer(MediaPlayer):
|
||||
display.vlcWidget.setVisible(status)
|
||||
|
||||
def update_ui(self, display):
|
||||
if display.vlcMedia.get_state() == vlc.State.Ended:
|
||||
self.stop(display)
|
||||
controller = display.controller
|
||||
if controller.media_info.end_time > 0:
|
||||
if display.vlcMediaPlayer.get_time() > \
|
||||
|
@ -126,7 +126,7 @@ VIDEO_JS = u"""
|
||||
vid.src = '';
|
||||
vid2.src = '';
|
||||
break;
|
||||
case 'length':
|
||||
case 'length':
|
||||
return vid.duration;
|
||||
case 'currentTime':
|
||||
return vid.currentTime;
|
||||
@ -134,6 +134,8 @@ VIDEO_JS = u"""
|
||||
// doesnt work currently
|
||||
vid.currentTime = varVal;
|
||||
break;
|
||||
case 'isEnded':
|
||||
return vid.ended;
|
||||
case 'setVisible':
|
||||
vid.style.visibility = varVal;
|
||||
break;
|
||||
@ -211,6 +213,8 @@ FLASH_JS = u"""
|
||||
case 'seek':
|
||||
// flashMovie.GotoFrame(varVal);
|
||||
break;
|
||||
case 'isEnded':
|
||||
return false;//TODO check flash end
|
||||
case 'setVisible':
|
||||
text.style.visibility = varVal;
|
||||
break;
|
||||
@ -254,7 +258,7 @@ AUDIO_EXT = [
|
||||
|
||||
class WebkitPlayer(MediaPlayer):
|
||||
"""
|
||||
A specialised version of the MediaPlayer class, which provides a QtWebKit
|
||||
A specialised version of the MediaPlayer class, which provides a QtWebKit
|
||||
display.
|
||||
"""
|
||||
|
||||
@ -356,7 +360,6 @@ class WebkitPlayer(MediaPlayer):
|
||||
display.frame.evaluateJavaScript(u'show_flash("stop");')
|
||||
else:
|
||||
display.frame.evaluateJavaScript(u'show_video("stop");')
|
||||
controller.seekSlider.setSliderPosition(0)
|
||||
self.state = MediaState.Stopped
|
||||
|
||||
def volume(self, display, vol):
|
||||
@ -408,6 +411,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
length = display.frame.evaluateJavaScript( \
|
||||
u'show_flash("length");').toInt()[0]
|
||||
else:
|
||||
if display.frame.evaluateJavaScript( \
|
||||
u'show_video("isEnded");').toString() == 'true':
|
||||
self.stop(display)
|
||||
(currentTime, ok) = display.frame.evaluateJavaScript( \
|
||||
u'show_video("currentTime");').toFloat()
|
||||
# check if conversion was ok and value is not 'NaN'
|
||||
|
@ -405,7 +405,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
# Only continue when we include the song's text.
|
||||
if not self.slideTextCheckBox.isChecked():
|
||||
return
|
||||
for index, item in enumerate(self.serviceManager.serviceItems):
|
||||
for item in self.serviceManager.serviceItems:
|
||||
# Trigger Audit requests
|
||||
Receiver.send_message(u'print_service_started',
|
||||
[item[u'service_item']])
|
||||
|
@ -461,7 +461,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
log.debug(temp_file_name)
|
||||
path_file_name = unicode(self.fileName())
|
||||
path, file_name = os.path.split(path_file_name)
|
||||
basename, extension = os.path.splitext(file_name)
|
||||
basename = os.path.splitext(file_name)[0]
|
||||
service_file_name = '%s.osd' % basename
|
||||
log.debug(u'ServiceManager.saveFile - %s', path_file_name)
|
||||
SettingsManager.set_last_dir(
|
||||
@ -483,8 +483,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
for i, filename in \
|
||||
enumerate(service_item[u'header'][u'background_audio']):
|
||||
new_file = os.path.join(u'audio',
|
||||
item[u'service_item']._uuid,
|
||||
os.path.split(filename)[1])
|
||||
item[u'service_item']._uuid, filename)
|
||||
audio_files.append((filename, new_file))
|
||||
service_item[u'header'][u'background_audio'][i] = new_file
|
||||
# Add the service item to the service.
|
||||
@ -610,16 +609,11 @@ class ServiceManager(QtGui.QWidget):
|
||||
time = time.replace(hour=service_hour, minute=service_minute)
|
||||
default_pattern = unicode(QtCore.QSettings().value(
|
||||
u'advanced/default service name',
|
||||
translate('OpenLP.AdvancedTab',
|
||||
'Service %Y-%m-%d %H-%M',
|
||||
'This is the default default service name template, which can '
|
||||
'be found under Advanced in Settings, Configure OpenLP. '
|
||||
'Please do not include any of the following characters: '
|
||||
'/\\?*|<>\[\]":+\n'
|
||||
'You can use any of the directives as shown on page '
|
||||
'http://docs.python.org/library/datetime.html'
|
||||
'#strftime-strptime-behavior , but if possible, please keep '
|
||||
'the resulting string sortable by name.')).toString())
|
||||
translate('OpenLP.AdvancedTab', 'Service %Y-%m-%d %H-%M',
|
||||
'This may not contain any of the following characters: '
|
||||
'/\\?*|<>\[\]":+\nSee http://docs.python.org/library/'
|
||||
'datetime.html#strftime-strptime-behavior for more '
|
||||
'information.')).toString())
|
||||
default_filename = time.strftime(default_pattern)
|
||||
else:
|
||||
default_filename = u''
|
||||
@ -1359,15 +1353,15 @@ class ServiceManager(QtGui.QWidget):
|
||||
Handle of the event pint passed
|
||||
"""
|
||||
link = event.mimeData()
|
||||
if event.mimeData().hasUrls():
|
||||
if link.hasUrls():
|
||||
event.setDropAction(QtCore.Qt.CopyAction)
|
||||
event.accept()
|
||||
for url in event.mimeData().urls():
|
||||
for url in link.urls():
|
||||
filename = unicode(url.toLocalFile())
|
||||
if filename.endswith(u'.osz'):
|
||||
self.onLoadServiceClicked(filename)
|
||||
elif event.mimeData().hasText():
|
||||
plugin = unicode(event.mimeData().text())
|
||||
elif link.hasText():
|
||||
plugin = unicode(link.text())
|
||||
item = self.serviceManagerList.itemAt(event.pos())
|
||||
# ServiceManager started the drag and drop
|
||||
if plugin == u'ServiceManager':
|
||||
|
@ -57,7 +57,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
def exec_(self):
|
||||
# load all the settings
|
||||
self.settingListWidget.clear()
|
||||
for tabIndex in range(0, self.stackedLayout.count() + 1):
|
||||
while self.stackedLayout.count():
|
||||
# take at 0 and the rest shuffle up.
|
||||
self.stackedLayout.takeAt(0)
|
||||
self.insertTab(self.generalTab, 0, PluginStatus.Active)
|
||||
|
@ -186,7 +186,7 @@ class SlideController(Controller):
|
||||
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
|
||||
shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown],
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.onSlideSelectedNext)
|
||||
category=self.category, triggers=self.onSlideSelectedNextAction)
|
||||
self.toolbar.addAction(self.nextItem)
|
||||
self.toolbar.addSeparator()
|
||||
if self.isLive:
|
||||
@ -563,7 +563,8 @@ class SlideController(Controller):
|
||||
Receiver.send_message('servicemanager_previous_item')
|
||||
elif keypressCommand == ServiceItemAction.PreviousLastSlide:
|
||||
# Go to the last slide of the previous item
|
||||
Receiver.send_message('servicemanager_previous_item', u'last slide')
|
||||
Receiver.send_message('servicemanager_previous_item',
|
||||
u'last slide')
|
||||
else:
|
||||
Receiver.send_message('servicemanager_next_item')
|
||||
self.keypress_loop = False
|
||||
@ -1139,6 +1140,13 @@ class SlideController(Controller):
|
||||
rect.y(), rect.width(), rect.height())
|
||||
self.slidePreview.setPixmap(winimg)
|
||||
|
||||
def onSlideSelectedNextAction(self, checked):
|
||||
"""
|
||||
Wrapper function from create_action so we can throw away the
|
||||
incorrect parameter
|
||||
"""
|
||||
self.onSlideSelectedNext()
|
||||
|
||||
def onSlideSelectedNext(self, wrap=None):
|
||||
"""
|
||||
Go to the next slide.
|
||||
@ -1183,7 +1191,8 @@ class SlideController(Controller):
|
||||
if self.slide_limits == SlideLimits.Wrap:
|
||||
row = self.previewListWidget.rowCount() - 1
|
||||
elif self.isLive and self.slide_limits == SlideLimits.Next:
|
||||
self.keypress_queue.append(ServiceItemAction.PreviousLastSlide)
|
||||
self.keypress_queue.append(
|
||||
ServiceItemAction.PreviousLastSlide)
|
||||
self._process_queue()
|
||||
return
|
||||
else:
|
||||
|
@ -153,7 +153,6 @@ class ThemeManager(QtGui.QWidget):
|
||||
Import new themes downloaded by the first time wizard
|
||||
"""
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
encoding = get_filesystem_encoding()
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.otz')
|
||||
for file in files:
|
||||
file = os.path.join(self.path, file)
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||
from openlp.core.lib.ui import create_action, UiStrings
|
||||
|
@ -183,13 +183,8 @@ def update_reference_separators():
|
||||
"""
|
||||
default_separators = unicode(translate('BiblesPlugin',
|
||||
':|v|V|verse|verses;;-|to;;,|and;;end',
|
||||
'This are 4 values seperated each by two semicolons representing the '
|
||||
'seperators for parsing references. This values are verse separators, '
|
||||
'range separators, list separators and end mark. Alternative values '
|
||||
'to be seperated by a vertical bar "|". In this case the first value '
|
||||
'is the default and used for the display format. If a semicolon should '
|
||||
'be used you have to give an alternative separator afterwards to allow '
|
||||
'OpenLP correct splitting of the translation.')).split(u';;')
|
||||
'Double-semicolon delimited separators for parsing references. '
|
||||
'Consult the developers for further information.')).split(u';;')
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(u'bibles')
|
||||
custom_separators = [
|
||||
|
@ -1025,12 +1025,13 @@ class BibleMediaItem(MediaManagerItem):
|
||||
return u'{su}[%s]{/su}' % verse_text
|
||||
return u'{su}%s{/su}' % verse_text
|
||||
|
||||
def search(self, string):
|
||||
def search(self, string, showError):
|
||||
"""
|
||||
Search for some Bible verses (by reference).
|
||||
"""
|
||||
bible = unicode(self.quickVersionComboBox.currentText())
|
||||
search_results = self.plugin.manager.get_verses(bible, string, False)
|
||||
search_results = self.plugin.manager.get_verses(bible, string, False,
|
||||
showError)
|
||||
if search_results:
|
||||
versetext = u' '.join([verse.text for verse in search_results])
|
||||
return [[string, versetext]]
|
||||
|
@ -177,7 +177,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
UiStrings().ConfirmDelete,
|
||||
translate('CustomPlugin.MediaItem',
|
||||
'Are you sure you want to delete the %n selected custom'
|
||||
' slides(s)?', '',
|
||||
' slide(s)?', '',
|
||||
QtCore.QCoreApplication.CodecForTr, len(items)),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
|
||||
QtGui.QMessageBox.No),
|
||||
@ -267,7 +267,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
self.searchTextEdit.clear()
|
||||
self.onSearchTextButtonClick()
|
||||
|
||||
def search(self, string):
|
||||
def search(self, string, showError):
|
||||
search_results = self.manager.get_all_objects(CustomSlide,
|
||||
or_(func.lower(CustomSlide.title).like(u'%' +
|
||||
string.lower() + u'%'),
|
||||
|
@ -189,7 +189,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
# Continue with the existing images.
|
||||
for bitem in items:
|
||||
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
||||
(path, name) = os.path.split(filename)
|
||||
name = os.path.split(filename)[1]
|
||||
service_item.add_from_image(filename, name, background)
|
||||
return True
|
||||
|
||||
@ -220,7 +220,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
bitem = self.listView.item(item.row())
|
||||
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
||||
if os.path.exists(filename):
|
||||
(path, name) = os.path.split(filename)
|
||||
name = os.path.split(filename)[1]
|
||||
if self.plugin.liveController.display.directImage(name,
|
||||
filename, background):
|
||||
self.resetAction.setVisible(True)
|
||||
@ -234,7 +234,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
'There was a problem replacing your background, '
|
||||
'the image file "%s" no longer exists.')) % filename)
|
||||
|
||||
def search(self, string):
|
||||
def search(self, string, showError):
|
||||
files = SettingsManager.load_list(self.settingsSection, u'images')
|
||||
results = []
|
||||
string = string.lower()
|
||||
|
@ -316,7 +316,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
media = filter(lambda x: os.path.splitext(x)[1] in ext, media)
|
||||
return media
|
||||
|
||||
def search(self, string):
|
||||
def search(self, string, showError):
|
||||
files = SettingsManager.load_list(self.settingsSection, u'media')
|
||||
results = []
|
||||
string = string.lower()
|
||||
|
@ -322,7 +322,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
return controller
|
||||
return None
|
||||
|
||||
def search(self, string):
|
||||
def search(self, string, showError):
|
||||
files = SettingsManager.load_list(
|
||||
self.settingsSection, u'presentations')
|
||||
results = []
|
||||
|
@ -4,12 +4,12 @@
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode #
|
||||
# Woldsund #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
|
||||
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
|
||||
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*****************************************************************************
|
||||
* OpenLP - Open Source Lyrics Projection *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Copyright (c) 2008-2010 Raoul Snyman *
|
||||
* Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael *
|
||||
* Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, *
|
||||
* Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, *
|
||||
* Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode *
|
||||
* Woldsund *
|
||||
* Copyright (c) 2008-2012 Raoul Snyman *
|
||||
* Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan *
|
||||
* Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, *
|
||||
* Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias *
|
||||
* Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, *
|
||||
* Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*****************************************************************************
|
||||
* OpenLP - Open Source Lyrics Projection *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Copyright (c) 2008-2010 Raoul Snyman *
|
||||
* Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael *
|
||||
* Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, *
|
||||
* Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, *
|
||||
* Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode *
|
||||
* Woldsund *
|
||||
* Copyright (c) 2008-2012 Raoul Snyman *
|
||||
* Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan *
|
||||
* Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, *
|
||||
* Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias *
|
||||
* Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, *
|
||||
* Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
@ -72,7 +72,9 @@ window.OpenLP = {
|
||||
);
|
||||
},
|
||||
loadController: function (event) {
|
||||
event.preventDefault();
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
$.getJSON(
|
||||
"/api/controller/live/text",
|
||||
function (data, status) {
|
||||
@ -91,6 +93,7 @@ window.OpenLP = {
|
||||
li.children("a").click(OpenLP.setSlide);
|
||||
ul.append(li);
|
||||
}
|
||||
OpenLP.currentItem = data.results.item;
|
||||
ul.listview("refresh");
|
||||
}
|
||||
);
|
||||
@ -208,9 +211,8 @@ window.OpenLP = {
|
||||
},
|
||||
showAlert: function (event) {
|
||||
event.preventDefault();
|
||||
var text = "{\"request\": {\"text\": \"" +
|
||||
$("#alert-text").val().replace(/\\/g, "\\\\").replace(/"/g, "\\\"") +
|
||||
"\"}}";
|
||||
var alert = OpenLP.escapeString($("#alert-text").val())
|
||||
var text = "{\"request\": {\"text\": \"" + alert + "\"}}";
|
||||
$.getJSON(
|
||||
"/api/alert",
|
||||
{"data": text},
|
||||
@ -221,9 +223,8 @@ window.OpenLP = {
|
||||
},
|
||||
search: function (event) {
|
||||
event.preventDefault();
|
||||
var text = "{\"request\": {\"text\": \"" +
|
||||
$("#search-text").val().replace(/\\/g, "\\\\").replace(/"/g, "\\\"") +
|
||||
"\"}}";
|
||||
var query = OpenLP.escapeString($("#search-text").val())
|
||||
var text = "{\"request\": {\"text\": \"" + query + "\"}}";
|
||||
$.getJSON(
|
||||
"/api/" + $("#search-plugin").val() + "/search",
|
||||
{"data": text},
|
||||
@ -280,6 +281,9 @@ window.OpenLP = {
|
||||
);
|
||||
$("#options").dialog("close");
|
||||
$.mobile.changePage("#service-manager");
|
||||
},
|
||||
escapeString: function (string) {
|
||||
return string.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")
|
||||
}
|
||||
}
|
||||
// Service Manager
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*****************************************************************************
|
||||
* OpenLP - Open Source Lyrics Projection *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Copyright (c) 2008-2010 Raoul Snyman *
|
||||
* Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael *
|
||||
* Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, *
|
||||
* Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, *
|
||||
* Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode *
|
||||
* Woldsund *
|
||||
* Copyright (c) 2008-2012 Raoul Snyman *
|
||||
* Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan *
|
||||
* Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, *
|
||||
* Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias *
|
||||
* Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, *
|
||||
* Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
@ -46,7 +46,7 @@ body {
|
||||
}
|
||||
|
||||
#clock {
|
||||
font-size: 40pt;
|
||||
font-size: 30pt;
|
||||
color: yellow;
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -4,12 +4,12 @@
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, #
|
||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
||||
# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode #
|
||||
# Woldsund #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
|
||||
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
|
||||
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
|
@ -1,12 +1,12 @@
|
||||
/*****************************************************************************
|
||||
* OpenLP - Open Source Lyrics Projection *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* Copyright (c) 2008-2010 Raoul Snyman *
|
||||
* Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael *
|
||||
* Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, *
|
||||
* Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, *
|
||||
* Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode *
|
||||
* Woldsund *
|
||||
* Copyright (c) 2008-2012 Raoul Snyman *
|
||||
* Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan *
|
||||
* Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, *
|
||||
* Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias *
|
||||
* Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, *
|
||||
* Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund *
|
||||
* ------------------------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
|
@ -111,15 +111,12 @@ the remotes.
|
||||
{"results": {"items": [{...}, {...}]}}
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import urlparse
|
||||
import re
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
from PyQt4 import QtCore, QtNetwork
|
||||
from mako.template import Template
|
||||
@ -314,11 +311,14 @@ class HttpConnection(object):
|
||||
"""
|
||||
log.debug(u'ready to read socket')
|
||||
if self.socket.canReadLine():
|
||||
data = self.socket.readLine()
|
||||
data = QtCore.QByteArray.fromPercentEncoding(data)
|
||||
data = unicode(data, 'utf8')
|
||||
log.debug(u'received: ' + data)
|
||||
words = data.split(u' ')
|
||||
data = str(self.socket.readLine())
|
||||
try:
|
||||
log.debug(u'received: ' + data)
|
||||
except UnicodeDecodeError:
|
||||
# Malicious request containing non-ASCII characters.
|
||||
self.close()
|
||||
return
|
||||
words = data.split(' ')
|
||||
response = None
|
||||
if words[0] == u'GET':
|
||||
url = urlparse.urlparse(words[1])
|
||||
@ -426,9 +426,19 @@ class HttpConnection(object):
|
||||
"""
|
||||
Send an alert.
|
||||
"""
|
||||
text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
|
||||
Receiver.send_message(u'alerts_text', [text])
|
||||
return HttpResponse(json.dumps({u'results': {u'success': True}}),
|
||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name("alerts")
|
||||
if plugin.status == PluginStatus.Active:
|
||||
try:
|
||||
text = json.loads(
|
||||
self.url_params[u'data'][0])[u'request'][u'text']
|
||||
except KeyError, ValueError:
|
||||
return HttpResponse(code=u'400 Bad Request')
|
||||
text = urllib.unquote(text)
|
||||
Receiver.send_message(u'alerts_text', [text])
|
||||
success = True
|
||||
else:
|
||||
success = False
|
||||
return HttpResponse(json.dumps({u'results': {u'success': success}}),
|
||||
{u'Content-Type': u'application/json'})
|
||||
|
||||
def controller(self, type, action):
|
||||
@ -463,9 +473,14 @@ class HttpConnection(object):
|
||||
item[u'selected'] = (self.parent.current_slide == index)
|
||||
data.append(item)
|
||||
json_data = {u'results': {u'slides': data}}
|
||||
if current_item:
|
||||
json_data[u'results'][u'item'] = self.parent.current_item._uuid
|
||||
else:
|
||||
if self.url_params and self.url_params.get(u'data'):
|
||||
data = json.loads(self.url_params[u'data'][0])
|
||||
try:
|
||||
data = json.loads(self.url_params[u'data'][0])
|
||||
except KeyError, ValueError:
|
||||
return HttpResponse(code=u'400 Bad Request')
|
||||
log.info(data)
|
||||
# This slot expects an int within a list.
|
||||
id = data[u'request'][u'id']
|
||||
@ -485,7 +500,10 @@ class HttpConnection(object):
|
||||
else:
|
||||
event += u'_item'
|
||||
if self.url_params and self.url_params.get(u'data'):
|
||||
data = json.loads(self.url_params[u'data'][0])
|
||||
try:
|
||||
data = json.loads(self.url_params[u'data'][0])
|
||||
except KeyError, ValueError:
|
||||
return HttpResponse(code=u'400 Bad Request')
|
||||
Receiver.send_message(event, data[u'request'][u'id'])
|
||||
else:
|
||||
Receiver.send_message(event)
|
||||
@ -518,11 +536,15 @@ class HttpConnection(object):
|
||||
``type``
|
||||
The plugin name to search in.
|
||||
"""
|
||||
text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
|
||||
try:
|
||||
text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
|
||||
except KeyError, ValueError:
|
||||
return HttpResponse(code=u'400 Bad Request')
|
||||
text = urllib.unquote(text)
|
||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||
if plugin.status == PluginStatus.Active and \
|
||||
plugin.mediaItem and plugin.mediaItem.hasSearch:
|
||||
results = plugin.mediaItem.search(text)
|
||||
results = plugin.mediaItem.search(text, False)
|
||||
else:
|
||||
results = []
|
||||
return HttpResponse(
|
||||
@ -533,20 +555,28 @@ class HttpConnection(object):
|
||||
"""
|
||||
Go live on an item of type ``type``.
|
||||
"""
|
||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||
try:
|
||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||
except KeyError, ValueError:
|
||||
return HttpResponse(code=u'400 Bad Request')
|
||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||
if plugin.status == PluginStatus.Active and plugin.mediaItem:
|
||||
plugin.mediaItem.goLive(id, remote=True)
|
||||
return HttpResponse(code=u'200 OK')
|
||||
|
||||
def add_to_service(self, type):
|
||||
"""
|
||||
Add item of type ``type`` to the end of the service.
|
||||
"""
|
||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||
try:
|
||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||
except KeyError, ValueError:
|
||||
return HttpResponse(code=u'400 Bad Request')
|
||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||
if plugin.status == PluginStatus.Active and plugin.mediaItem:
|
||||
item_id = plugin.mediaItem.createItemFromId(id)
|
||||
plugin.mediaItem.addToService(item_id, remote=True)
|
||||
return HttpResponse(code=u'200 OK')
|
||||
|
||||
def send_response(self, response):
|
||||
http = u'HTTP/1.1 %s\r\n' % response.code
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
from PyQt4 import QtCore, QtGui, QtNetwork
|
||||
|
||||
from openlp.core.lib import SettingsTab, translate
|
||||
from openlp.core.lib import SettingsTab, translate, Receiver
|
||||
|
||||
ZERO_URL = u'0.0.0.0'
|
||||
|
||||
@ -87,7 +87,8 @@ class RemoteTab(SettingsTab):
|
||||
self.qrLayout = QtGui.QVBoxLayout(self.androidAppGroupBox)
|
||||
self.qrLayout.setObjectName(u'qrLayout')
|
||||
self.qrCodeLabel = QtGui.QLabel(self.androidAppGroupBox)
|
||||
self.qrCodeLabel.setPixmap(QtGui.QPixmap(u':/remotes/android_app_qr.png'))
|
||||
self.qrCodeLabel.setPixmap(QtGui.QPixmap(
|
||||
u':/remotes/android_app_qr.png'))
|
||||
self.qrCodeLabel.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.qrCodeLabel.setObjectName(u'qrCodeLabel')
|
||||
self.qrLayout.addWidget(self.qrCodeLabel)
|
||||
@ -160,12 +161,20 @@ class RemoteTab(SettingsTab):
|
||||
self.setUrls()
|
||||
|
||||
def save(self):
|
||||
changed = False
|
||||
if QtCore.QSettings().value(self.settingsSection + u'/ip address',
|
||||
QtCore.QVariant(ZERO_URL).toString() != self.addressEdit.text() or
|
||||
QtCore.QSettings().value(self.settingsSection + u'/port',
|
||||
QtCore.QVariant(4316).toInt()[0]) != self.portSpinBox.value()):
|
||||
changed = True
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/port',
|
||||
QtCore.QVariant(self.portSpinBox.value()))
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/ip address',
|
||||
QtCore.QVariant(self.addressEdit.text()))
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/twelve hour',
|
||||
QtCore.QVariant(self.twelveHour))
|
||||
if changed:
|
||||
Receiver.send_message(u'remotes_config_updated')
|
||||
|
||||
def onTwelveHourCheckBoxChanged(self, check_state):
|
||||
self.twelveHour = False
|
||||
|
@ -86,3 +86,11 @@ class RemotesPlugin(Plugin):
|
||||
self.textStrings[StringContent.VisibleName] = {
|
||||
u'title': translate('RemotePlugin', 'Remote', 'container title')
|
||||
}
|
||||
|
||||
def configUpdated(self):
|
||||
"""
|
||||
Called when Config is changed to restart the server on new address or
|
||||
port
|
||||
"""
|
||||
self.finalise()
|
||||
self.initialise()
|
||||
|
@ -589,7 +589,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
verse_names.append(u'%s%s' % (
|
||||
VerseType.translated_tag(verse[0]), verse[1:]))
|
||||
verses_not_used = []
|
||||
for count, verse in enumerate(verses):
|
||||
for verse in verses:
|
||||
if not verse in order:
|
||||
verses_not_used.append(verse)
|
||||
self.warningLabel.setVisible(len(verses_not_used) > 0)
|
||||
@ -680,7 +680,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
self.verseListWidget.rowCount())
|
||||
if not result:
|
||||
return False
|
||||
item = int(self.songBookComboBox.currentIndex())
|
||||
text = unicode(self.songBookComboBox.currentText())
|
||||
if self.songBookComboBox.findText(text, QtCore.Qt.MatchExactly) < 0:
|
||||
if QtGui.QMessageBox.question(self,
|
||||
|
@ -159,6 +159,12 @@ class CCLIFileImport(SongImport):
|
||||
song_author = u''
|
||||
song_topics = u''
|
||||
for line in textList:
|
||||
if line.startswith(u'[S '):
|
||||
ccli, line = line.split(u']', 1)
|
||||
if ccli.startswith(u'[S A'):
|
||||
self.ccliNumber = ccli[4:].strip()
|
||||
else:
|
||||
self.ccliNumber = ccli[3:].strip()
|
||||
if line.startswith(u'Title='):
|
||||
self.title = line[6:].strip()
|
||||
elif line.startswith(u'Author='):
|
||||
@ -166,9 +172,7 @@ class CCLIFileImport(SongImport):
|
||||
elif line.startswith(u'Copyright='):
|
||||
self.copyright = line[10:].strip()
|
||||
elif line.startswith(u'Themes='):
|
||||
song_topics = line[7:].strip()
|
||||
elif line.startswith(u'[S A'):
|
||||
self.ccliNumber = line[4:-3].strip()
|
||||
song_topics = line[7:].strip().replace(u' | ', u'/t')
|
||||
elif line.startswith(u'Fields='):
|
||||
# Fields contain single line indicating verse, chorus, etc,
|
||||
# /t delimited, same as with words field. store seperately
|
||||
@ -193,6 +197,7 @@ class CCLIFileImport(SongImport):
|
||||
check_first_verse_line = True
|
||||
verse_text = unicode(words_list[counter])
|
||||
verse_text = verse_text.replace(u'/n', u'\n')
|
||||
verse_text = verse_text.replace(u' | ', u'\n')
|
||||
verse_lines = verse_text.split(u'\n', 1)
|
||||
if check_first_verse_line:
|
||||
if verse_lines[0].startswith(u'(PRE-CHORUS'):
|
||||
@ -243,7 +248,7 @@ class CCLIFileImport(SongImport):
|
||||
<Empty line>
|
||||
Song CCLI number
|
||||
# e.g. CCLI Number (e.g.CCLI-Liednummer: 2672885)
|
||||
Song copyright
|
||||
Song copyright (if it begins ©, otherwise after authors)
|
||||
# e.g. © 1999 Integrity's Hosanna! Music | LenSongs Publishing
|
||||
Song authors # e.g. Lenny LeBlanc | Paul Baloche
|
||||
Licencing info
|
||||
@ -322,11 +327,17 @@ class CCLIFileImport(SongImport):
|
||||
#line_number=2, copyright
|
||||
if line_number == 2:
|
||||
line_number += 1
|
||||
self.copyright = clean_line
|
||||
if clean_line.startswith(u'©'):
|
||||
self.copyright = clean_line
|
||||
else:
|
||||
song_author = clean_line
|
||||
#n=3, authors
|
||||
elif line_number == 3:
|
||||
line_number += 1
|
||||
song_author = clean_line
|
||||
if song_author:
|
||||
self.copyright = clean_line
|
||||
else:
|
||||
song_author = clean_line
|
||||
#line_number=4, comments lines before last line
|
||||
elif line_number == 4 and not clean_line.startswith(u'CCL'):
|
||||
self.comments += clean_line
|
||||
|
@ -36,7 +36,7 @@ from sqlalchemy.sql import or_
|
||||
|
||||
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
|
||||
translate, check_item_selected, PluginStatus, create_separated_list
|
||||
from openlp.core.lib.ui import UiStrings, create_action, create_widget_action
|
||||
from openlp.core.lib.ui import UiStrings, create_widget_action
|
||||
from openlp.core.utils import AppLocation
|
||||
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
|
||||
SongImportForm, SongExportForm
|
||||
@ -586,7 +586,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
Receiver.send_message(u'service_item_update',
|
||||
u'%s:%s:%s' % (editId, item._uuid, temporary))
|
||||
|
||||
def search(self, string):
|
||||
def search(self, string, showError):
|
||||
"""
|
||||
Search for some songs
|
||||
"""
|
||||
|
2081
resources/i18n/af.ts
2081
resources/i18n/af.ts
File diff suppressed because it is too large
Load Diff
2194
resources/i18n/cs.ts
2194
resources/i18n/cs.ts
File diff suppressed because it is too large
Load Diff
6878
resources/i18n/da.ts
Normal file
6878
resources/i18n/da.ts
Normal file
File diff suppressed because it is too large
Load Diff
2069
resources/i18n/de.ts
2069
resources/i18n/de.ts
File diff suppressed because it is too large
Load Diff
2423
resources/i18n/el.ts
2423
resources/i18n/el.ts
File diff suppressed because it is too large
Load Diff
4898
resources/i18n/en.ts
4898
resources/i18n/en.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3091
resources/i18n/es.ts
3091
resources/i18n/es.ts
File diff suppressed because it is too large
Load Diff
2069
resources/i18n/et.ts
2069
resources/i18n/et.ts
File diff suppressed because it is too large
Load Diff
6797
resources/i18n/fi.ts
Normal file
6797
resources/i18n/fi.ts
Normal file
File diff suppressed because it is too large
Load Diff
4181
resources/i18n/fr.ts
4181
resources/i18n/fr.ts
File diff suppressed because it is too large
Load Diff
2122
resources/i18n/hu.ts
2122
resources/i18n/hu.ts
File diff suppressed because it is too large
Load Diff
2534
resources/i18n/id.ts
2534
resources/i18n/id.ts
File diff suppressed because it is too large
Load Diff
6801
resources/i18n/it.ts
Normal file
6801
resources/i18n/it.ts
Normal file
File diff suppressed because it is too large
Load Diff
2939
resources/i18n/ja.ts
2939
resources/i18n/ja.ts
File diff suppressed because it is too large
Load Diff
2658
resources/i18n/ko.ts
2658
resources/i18n/ko.ts
File diff suppressed because it is too large
Load Diff
2943
resources/i18n/nb.ts
2943
resources/i18n/nb.ts
File diff suppressed because it is too large
Load Diff
3092
resources/i18n/nl.ts
3092
resources/i18n/nl.ts
File diff suppressed because it is too large
Load Diff
6799
resources/i18n/pl.ts
Normal file
6799
resources/i18n/pl.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3239
resources/i18n/ru.ts
3239
resources/i18n/ru.ts
File diff suppressed because it is too large
Load Diff
4566
resources/i18n/sq.ts
4566
resources/i18n/sq.ts
File diff suppressed because it is too large
Load Diff
2664
resources/i18n/sv.ts
2664
resources/i18n/sv.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -185,11 +185,11 @@ def download_translations():
|
||||
**Note:** URLs and headers need to remain strings, not unicode.
|
||||
"""
|
||||
global username, password
|
||||
if not username:
|
||||
username = raw_input(u'Transifex username: ')
|
||||
if not password:
|
||||
password = getpass(u'Transifex password: ')
|
||||
print_quiet(u'Download translation files from Transifex')
|
||||
if not username:
|
||||
username = raw_input(u' Transifex username: ')
|
||||
if not password:
|
||||
password = getpass(u' Transifex password: ')
|
||||
# First get the list of languages
|
||||
url = SERVER_URL + 'resource/ents/'
|
||||
base64string = base64.encodestring(
|
||||
|
Loading…
Reference in New Issue
Block a user