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