This commit is contained in:
Andreas Preikschat 2012-10-02 07:36:45 +02:00
commit 42dec84a31
58 changed files with 20948 additions and 9399 deletions

View File

@ -1 +1 @@
1.9.9-bzr1956
1.9.12

View File

@ -35,6 +35,7 @@ logging and a plugin framework are contained within the openlp.core module.
import os
import sys
import platform
import logging
from optparse import OptionParser
from traceback import format_exception
@ -102,8 +103,13 @@ class OpenLP(QtGui.QApplication):
Run the OpenLP application.
"""
self.eventLoopIsActive = False
# On Windows, the args passed into the constructor are
# ignored. Not very handy, so set the ones we want to use.
# On Windows, the args passed into the constructor are ignored. Not
# very handy, so set the ones we want to use. On Linux and FreeBSD, in
# order to set the WM_CLASS property for X11, we pass "OpenLP" in as a
# command line argument. This interferes with files being passed in as
# command line arguments, so we remove it from the list.
if 'OpenLP' in args:
args.remove('OpenLP')
self.args.extend(args)
# provide a listener for widgets to reqest a screen update.
QtCore.QObject.connect(Receiver.get_receiver(),
@ -248,6 +254,13 @@ def main(args=None):
# Parse command line options and deal with them.
# Use args supplied programatically if possible.
(options, args) = parser.parse_args(args) if args else parser.parse_args()
if options.portable:
app_path = AppLocation.get_directory(AppLocation.AppDir)
set_up_logging(os.path.abspath(os.path.join(app_path, u'..',
u'..', u'Other')))
log.info(u'Running portable')
else:
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
qt_args = []
if options.loglevel.lower() in ['d', 'debug']:
log.setLevel(logging.DEBUG)
@ -259,6 +272,9 @@ def main(args=None):
qt_args.extend(['-style', options.style])
# Throw the rest of the arguments at Qt, just in case.
qt_args.extend(args)
# Bug #1018855: Set the WM_CLASS property in X11
if platform.system() not in ['Windows', 'Darwin']:
qt_args.append('OpenLP')
# Initialise the resources
qInitResources()
# Now create and actually run the application.
@ -269,10 +285,6 @@ def main(args=None):
app.setApplicationName(u'OpenLPPortable')
Settings.setDefaultFormat(Settings.IniFormat)
# Get location OpenLPPortable.ini
app_path = AppLocation.get_directory(AppLocation.AppDir)
set_up_logging(os.path.abspath(os.path.join(app_path, u'..',
u'..', u'Other')))
log.info(u'Running portable')
portable_settings_file = os.path.abspath(os.path.join(app_path, u'..',
u'..', u'Data', u'OpenLP.ini'))
# Make this our settings file
@ -289,7 +301,6 @@ def main(args=None):
portable_settings.sync()
else:
app.setApplicationName(u'OpenLP')
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
app.setApplicationVersion(get_application_version()[u'version'])
# Instance check
if not options.testing:

View File

@ -256,7 +256,7 @@ class Renderer(object):
if not self.force_page:
self.display.buildHtml(serviceItem)
raw_html = serviceItem.get_rendered_frame(0)
self.display.text(raw_html)
self.display.text(raw_html, False)
preview = self.display.preview()
return preview
self.force_page = False
@ -365,7 +365,7 @@ class Renderer(object):
The theme information
"""
if not theme_data.font_main_override:
return QtCore.QRect(10, 0, self.width, self.footer_start)
return QtCore.QRect(10, 0, self.width - 20, self.footer_start)
else:
return QtCore.QRect(theme_data.font_main_x, theme_data.font_main_y,
theme_data.font_main_width - 1, theme_data.font_main_height - 1)
@ -406,7 +406,14 @@ class Renderer(object):
if theme_data.font_main_shadow:
self.page_width -= int(theme_data.font_main_shadow_size)
self.page_height -= int(theme_data.font_main_shadow_size)
# For the life of my I don't know why we have to completely kill the
# QWebView in order for the display to work properly, but we do. See
# bug #1041366 for an example of what happens if we take this out.
self.web = None
self.web = QtWebKit.QWebView()
self.web.setVisible(False)
self.web.resize(self.page_width, self.page_height)
self.web_frame = self.web.page().mainFrame()
# Adjust width and height to account for shadow. outline done in css.
html = u"""<!DOCTYPE html><html><head><script>
function show_text(newtext) {
@ -450,8 +457,7 @@ class Renderer(object):
previous_html, previous_raw, html_lines, lines, separator, u'')
else:
previous_raw = separator.join(lines)
if previous_raw:
formatted.append(previous_raw)
formatted.append(previous_raw)
log.debug(u'_paginate_slide - End')
return formatted

View File

@ -72,10 +72,10 @@ class Ui_AboutDialog(object):
self.licenseTabLayout.addWidget(self.licenseTextEdit)
self.aboutNotebook.addTab(self.licenseTab, u'')
self.aboutDialogLayout.addWidget(self.aboutNotebook)
self.contributeButton = create_button(None, u'contributeButton',
icon=u':/system/system_contribute.png')
self.volunteerButton = create_button(None, u'volunteerButton',
icon=u':/system/system_volunteer.png')
self.buttonBox = create_button_box(aboutDialog, u'buttonBox',
[u'close'], [self.contributeButton])
[u'close'], [self.volunteerButton])
self.aboutDialogLayout.addWidget(self.buttonBox)
self.retranslateUi(aboutDialog)
self.aboutNotebook.setCurrentIndex(0)
@ -96,7 +96,7 @@ class Ui_AboutDialog(object):
'\n'
'OpenLP is written and maintained by volunteers. If you would '
'like to see more free Christian software being written, please '
'consider contributing by using the button below.'
'consider volunteering by using the button below.'
))
self.aboutNotebook.setTabText(
self.aboutNotebook.indexOf(self.aboutTab), UiStrings().About)
@ -615,5 +615,5 @@ class Ui_AboutDialog(object):
self.aboutNotebook.setTabText(
self.aboutNotebook.indexOf(self.licenseTab),
translate('OpenLP.AboutForm', 'License'))
self.contributeButton.setText(translate('OpenLP.AboutForm',
'Contribute'))
self.volunteerButton.setText(translate('OpenLP.AboutForm',
'Volunteer'))

View File

@ -54,10 +54,10 @@ class AboutForm(QtGui.QDialog, Ui_AboutDialog):
build_text = u''
about_text = about_text.replace(u'<revision>', build_text)
self.aboutTextEdit.setPlainText(about_text)
QtCore.QObject.connect(self.contributeButton,
QtCore.SIGNAL(u'clicked()'), self.onContributeButtonClicked)
QtCore.QObject.connect(self.volunteerButton,
QtCore.SIGNAL(u'clicked()'), self.onVolunteerButtonClicked)
def onContributeButtonClicked(self):
def onVolunteerButtonClicked(self):
"""
Launch a web browser and go to the contribute page on the site.
"""

View File

@ -38,7 +38,7 @@ import sys
from openlp.core.lib import SettingsTab, translate, build_icon, Receiver
from openlp.core.lib.settings import Settings
from openlp.core.lib.ui import UiStrings
from openlp.core.utils import get_images_filter, AppLocation
from openlp.core.utils import get_images_filter, AppLocation, format_time
from openlp.core.lib import SlideLimits
log = logging.getLogger(__name__)
@ -527,7 +527,7 @@ class AdvancedTab(SettingsTab):
'Click "No" to stop loading OpenLP. allowing you to fix '
'the the problem.\n\n'
'Click "Yes" to reset the data directory to the default '
'location.' % self.currentDataPath),
'location.').replace('%s', self.currentDataPath),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
@ -545,6 +545,10 @@ class AdvancedTab(SettingsTab):
self.currentDataPath))
self.defaultColorButton.setStyleSheet(
u'background-color: %s' % self.defaultColor)
# Don't allow data directory move if running portable.
if Settings().value(u'advanced/is portable',
QtCore.QVariant(False)).toBool():
self.dataDirectoryGroupBox.hide()
def save(self):
"""
@ -608,18 +612,18 @@ class AdvancedTab(SettingsTab):
def generateServiceNameExample(self):
preset_is_valid = True
if self.serviceNameDay.currentIndex() == 7:
time = datetime.now()
local_time = datetime.now()
else:
now = datetime.now()
day_delta = self.serviceNameDay.currentIndex() - now.weekday()
if day_delta < 0:
day_delta += 7
time = now + timedelta(days=day_delta)
time = time.replace(hour = self.serviceNameTime.time().hour(),
local_time = time.replace(hour = self.serviceNameTime.time().hour(),
minute = self.serviceNameTime.time().minute())
try:
service_name_example = time.strftime(unicode(
self.serviceNameEdit.text()))
service_name_example = format_time(unicode(
self.serviceNameEdit.text()), local_time)
except ValueError:
preset_is_valid = False
service_name_example = translate('OpenLP.AdvancedTab',
@ -670,6 +674,7 @@ class AdvancedTab(SettingsTab):
options = QtGui.QFileDialog.ShowDirsOnly))
# Set the new data path.
if new_data_path:
new_data_path = os.path.normpath(new_data_path)
if self.currentDataPath.lower() == new_data_path.lower():
self.onDataDirectoryCancelButtonClicked()
return
@ -682,7 +687,7 @@ class AdvancedTab(SettingsTab):
'Are you sure you want to change the location of the OpenLP '
'data directory to:\n\n%s\n\n'
'The data directory will be changed when OpenLP is closed.'
% new_data_path),
).replace('%s', new_data_path),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
@ -746,7 +751,7 @@ class AdvancedTab(SettingsTab):
'The location you have selected \n\n%s\n\n'
'appears to contain OpenLP data files. Do you wish to replace '
'these files with the current data files?'
% os.path.abspath(data_path,)),
).replace('%s', os.path.abspath(data_path,)),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),

View File

@ -138,11 +138,16 @@ class MainDisplay(Display):
if Settings().value(u'advanced/x11 bypass wm',
QtCore.QVariant(True)).toBool():
windowFlags |= QtCore.Qt.X11BypassWindowManagerHint
# FIXME: QtCore.Qt.SplashScreen is workaround to make display screen
# stay always on top on Mac OS X. For details see bug 906926.
# It needs more investigation to fix it properly.
# TODO: The following combination of windowFlags works correctly
# on Mac OS X. For next OpenLP version we should test it on other
# platforms. For OpenLP 2.0 keep it only for OS X to not cause any
# regressions on other platforms.
if sys.platform == 'darwin':
windowFlags |= QtCore.Qt.SplashScreen
windowFlags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Window
# For primary screen ensure it stays above the OS X dock
# and menu bar
if self.screens.current[u'primary']:
self.setWindowState(QtCore.Qt.WindowFullScreen)
self.setWindowFlags(windowFlags)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setTransparency(False)
@ -224,20 +229,33 @@ class MainDisplay(Display):
self.__hideMouse()
log.debug(u'Finished MainDisplay setup')
def text(self, slide):
def text(self, slide, animate=True):
"""
Add the slide text from slideController
``slide``
The slide text to be displayed
``animate``
Perform transitions if applicable when setting the text
"""
log.debug(u'text to display')
# Wait for the webview to update before displaying text.
while not self.webLoaded:
Receiver.send_message(u'openlp_process_events')
self.setGeometry(self.screen[u'size'])
self.frame.evaluateJavaScript(u'show_text("%s")' %
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
if animate:
self.frame.evaluateJavaScript(u'show_text("%s")' %
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
else:
# This exists for https://bugs.launchpad.net/openlp/+bug/1016843
# For unknown reasons if evaluateJavaScript is called
# from the themewizard, then it causes a crash on
# Windows if there are many items in the service to re-render.
# Setting the div elements direct seems to solve the issue
self.frame.findFirstElement("#lyricsmain").setInnerXml(slide)
self.frame.findFirstElement("#lyricsoutline").setInnerXml(slide)
self.frame.findFirstElement("#lyricsshadow").setInnerXml(slide)
def alert(self, text, location):
"""
@ -580,7 +598,7 @@ class AudioPlayer(QtCore.QObject):
self.playlist.extend(map(Phonon.MediaSource, filenames))
def next(self):
if not self.repeat and self.currentIndex + 1 == len(self.playlist):
if not self.repeat and self.currentIndex + 1 >= len(self.playlist):
return
isPlaying = self.mediaObject.state() == Phonon.PlayingState
self.currentIndex += 1

View File

@ -210,6 +210,8 @@ class Ui_MainWindow(object):
icon=u':/system/system_exit.png',
shortcuts=[QtGui.QKeySequence(u'Alt+F4')],
category=UiStrings().File, triggers=mainWindow.close)
# Give QT Extra Hint that this is the Exit Menu Item
self.fileExitItem.setMenuRole(QtGui.QAction.QuitRole)
action_list.add_category(unicode(UiStrings().Import),
CategoryOrder.standardMenu)
self.importThemeItem = create_action(mainWindow,
@ -304,6 +306,8 @@ class Ui_MainWindow(object):
self.settingsConfigureItem = create_action(mainWindow,
u'settingsConfigureItem', icon=u':/system/system_settings.png',
category=UiStrings().Settings)
# Give QT Extra Hint that this is the Preferences Menu Item
self.settingsConfigureItem.setMenuRole(QtGui.QAction.PreferencesRole)
self.settingsImportItem = create_action(mainWindow,
u'settingsImportItem', category=UiStrings().Settings)
self.settingsExportItem = create_action(mainWindow,
@ -314,6 +318,8 @@ class Ui_MainWindow(object):
icon=u':/system/system_about.png',
shortcuts=[QtGui.QKeySequence(u'Ctrl+F1')],
category=UiStrings().Help, triggers=self.onAboutItemClicked)
# Give QT Extra Hint that this is an About Menu Item
self.aboutItem.setMenuRole(QtGui.QAction.AboutRole)
if os.name == u'nt':
self.localHelpFile = os.path.join(
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
@ -965,6 +971,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
setting_sections.extend([self.themesSettingsSection])
setting_sections.extend([self.displayTagsSection])
setting_sections.extend([self.headerSection])
setting_sections.extend([u'crashreport'])
# Add plugin sections.
for plugin in self.pluginManager.plugins:
setting_sections.extend([plugin.name])
@ -992,7 +999,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
'settings file.\n\n'
'Section [%s] is not valid \n\n'
'Processing has terminated and no changed have been made.'
% section),
).replace('%s', section),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Ok))
return
@ -1511,7 +1518,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
translate('OpenLP.MainWindow',
'Copying OpenLP data to new data directory location - %s '
'- Please wait for copy to finish'
% self.newDataPath))
).replace('%s', self.newDataPath))
dir_util.copy_tree(old_data_path, self.newDataPath)
log.info(u'Copy sucessful')
except (IOError, os.error, DistutilsFileError), why:
@ -1521,7 +1528,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
translate('OpenLP.MainWindow', 'New Data Directory Error'),
translate('OpenLP.MainWindow',
'OpenLP Data directory copy failed\n\n%s'
% unicode(why)),
).replace('%s', unicode(why)),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Ok))
return False

View File

@ -28,6 +28,7 @@
import logging
import os
import sys
from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, Receiver, translate
@ -43,7 +44,7 @@ log = logging.getLogger(__name__)
class MediaController(object):
"""
The implementation of the Media Controller. The Media Controller adds an own
class for every Player. Currently these are QtWebkit, Phonon and planed Vlc.
class for every Player. Currently these are QtWebkit, Phonon and Vlc.
"""
def __init__(self, parent):
@ -105,8 +106,12 @@ class MediaController(object):
AppLocation.get_directory(AppLocation.AppDir),
u'core', u'ui', u'media')
for filename in os.listdir(controller_dir):
if filename.endswith(u'player.py') and not \
filename == 'media_player.py':
# TODO vlc backend is not yet working on Mac OS X.
# For now just ignore vlc backend on Mac OS X.
if sys.platform == 'darwin' and filename == 'vlcplayer.py':
log.warn(u'Disabling vlc media player')
continue
if filename.endswith(u'player.py'):
path = os.path.join(controller_dir, filename)
if os.path.isfile(path):
modulename = u'openlp.core.ui.media.' + \
@ -114,7 +119,9 @@ class MediaController(object):
log.debug(u'Importing controller %s', modulename)
try:
__import__(modulename, globals(), locals(), [])
except ImportError:
# On some platforms importing vlc.py might cause
# also OSError exceptions. (e.g. Mac OS X)
except (ImportError, OSError):
log.warn(u'Failed to import %s on path %s',
modulename, path)
controller_classes = MediaPlayer.__subclasses__()
@ -287,7 +294,7 @@ class MediaController(object):
"""
player.resize(display)
def video(self, controller, file, muted, isBackground):
def video(self, controller, file, muted, isBackground, hidden=False):
"""
Loads and starts a video to run with the option of sound
"""
@ -333,11 +340,19 @@ class MediaController(object):
if controller.isLive and not controller.media_info.is_background:
display.frame.evaluateJavaScript(u'show_video( \
"setBackBoard", null, null, null,"visible");')
# now start playing
if controller.isLive and \
(Settings().value(u'general/auto unblank',
QtCore.QVariant(False)).toBool() or \
controller.media_info.is_background) or not controller.isLive:
# now start playing - Preview is autoplay!
autoplay = False
# Preview requested
if not controller.isLive:
autoplay = True
# Visible or background requested
elif not hidden or controller.media_info.is_background:
autoplay = True
# Unblank on load set
elif Settings().value(u'general/auto unblank',
QtCore.QVariant(False)).toBool():
autoplay = True
if autoplay:
if not self.video_play([controller]):
critical_error_message_box(
translate('MediaPlugin.MediaItem', 'Unsupported File'),

View File

@ -48,7 +48,48 @@ import sys
from inspect import getargspec
__version__ = "N/A"
build_date = "Thu Jun 14 15:22:46 2012"
build_date = "Fri Sep 28 22:48:50 2012"
if sys.version_info[0] > 2:
str = str
unicode = str
bytes = bytes
basestring = (str, bytes)
PYTHON3 = True
def str_to_bytes(s):
"""Translate string or bytes to bytes.
"""
if isinstance(s, str):
return bytes(s, sys.getfilesystemencoding())
else:
return s
def bytes_to_str(b):
"""Translate bytes to string.
"""
if isinstance(b, bytes):
return b.decode(sys.getfilesystemencoding())
else:
return b
else:
str = str
unicode = unicode
bytes = str
basestring = basestring
PYTHON3 = False
def str_to_bytes(s):
"""Translate string or bytes to bytes.
"""
if isinstance(s, unicode):
return s.encode(sys.getfilesystemencoding())
else:
return s
def bytes_to_str(b):
"""Translate bytes to unicode string.
"""
if isinstance(b, str):
return unicode(b, sys.getfilesystemencoding())
# Internal guard to prevent internal classes to be directly
# instanciated.
@ -220,7 +261,7 @@ def string_result(result, func, arguments):
"""
if result:
# make a python string copy
s = ctypes.string_at(result)
s = bytes_to_str(ctypes.string_at(result))
# free original string ptr
libvlc_free(result)
return s
@ -241,16 +282,32 @@ class FILE(ctypes.Structure):
pass
FILE_ptr = ctypes.POINTER(FILE)
PyFile_FromFile = ctypes.pythonapi.PyFile_FromFile
PyFile_FromFile.restype = ctypes.py_object
PyFile_FromFile.argtypes = [FILE_ptr,
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.CFUNCTYPE(ctypes.c_int, FILE_ptr)]
if PYTHON3:
PyFile_FromFd = ctypes.pythonapi.PyFile_FromFd
PyFile_FromFd.restype = ctypes.py_object
PyFile_FromFd.argtypes = [ctypes.c_int,
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.c_int,
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.c_int ]
PyFile_AsFile = ctypes.pythonapi.PyFile_AsFile
PyFile_AsFile.restype = FILE_ptr
PyFile_AsFile.argtypes = [ctypes.py_object]
PyFile_AsFd = ctypes.pythonapi.PyObject_AsFileDescriptor
PyFile_AsFd.restype = ctypes.c_int
PyFile_AsFd.argtypes = [ctypes.py_object]
else:
PyFile_FromFile = ctypes.pythonapi.PyFile_FromFile
PyFile_FromFile.restype = ctypes.py_object
PyFile_FromFile.argtypes = [FILE_ptr,
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.CFUNCTYPE(ctypes.c_int, FILE_ptr)]
PyFile_AsFile = ctypes.pythonapi.PyFile_AsFile
PyFile_AsFile.restype = FILE_ptr
PyFile_AsFile.argtypes = [ctypes.py_object]
# Generated enum types #
@ -1155,6 +1212,8 @@ class Instance(_Ctype):
# no parameters passed, for win32 and MacOS,
# specify the plugin_path if detected earlier
args = ['vlc', '--plugin-path=' + plugin_path]
if PYTHON3:
args = [ str_to_bytes(a) for a in args ]
return libvlc_new(len(args), args)
def media_player_new(self, uri=None):
@ -1195,12 +1254,12 @@ class Instance(_Ctype):
"""
if ':' in mrl and mrl.index(':') > 1:
# Assume it is a URL
m = libvlc_media_new_location(self, mrl)
m = libvlc_media_new_location(self, str_to_bytes(mrl))
else:
# Else it should be a local path.
m = libvlc_media_new_path(self, mrl)
m = libvlc_media_new_path(self, str_to_bytes(mrl))
for o in options:
libvlc_media_add_option(m, o)
libvlc_media_add_option(m, str_to_bytes(o))
m._instance = self
return m
@ -1664,6 +1723,9 @@ class LogIterator(_Ctype):
return i.contents
raise StopIteration
def __next__(self):
return self.next()
def free(self):
'''Frees memory allocated by L{log_get_iterator}().
@ -3125,18 +3187,6 @@ def libvlc_vprinterr(fmt, ap):
ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p)
return f(fmt, ap)
def libvlc_printerr(fmt, args):
'''Sets the LibVLC error status and message for the current thread.
Any previous error is overridden.
@param fmt: the format string.
@param args: the arguments.
@return: a nul terminated string in any case.
'''
f = _Cfunctions.get('libvlc_printerr', None) or \
_Cfunction('libvlc_printerr', ((1,), (1,),), None,
ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p)
return f(fmt, args)
def libvlc_new(argc, argv):
'''Create and initialize a libvlc instance.
This functions accept a list of "command line" arguments similar to the
@ -5828,11 +5878,12 @@ def libvlc_vlm_get_event_manager(p_instance):
return f(p_instance)
# 2 function(s) blacklisted:
# 3 function(s) blacklisted:
# libvlc_printerr
# libvlc_set_exit_handler
# libvlc_video_set_callbacks
# 18 function(s) not wrapped as methods:
# 17 function(s) not wrapped as methods:
# libvlc_audio_output_list_release
# libvlc_clearerr
# libvlc_clock
@ -5847,7 +5898,6 @@ def libvlc_vlm_get_event_manager(p_instance):
# libvlc_log_unsubscribe
# libvlc_module_description_list_release
# libvlc_new
# libvlc_printerr
# libvlc_track_description_list_release
# libvlc_track_description_release
# libvlc_vprinterr
@ -5908,7 +5958,7 @@ def libvlc_hex_version():
"""Return the libvlc version in hex or 0 if unavailable.
"""
try:
return _dot2int(libvlc_get_version().split()[0])
return _dot2int(bytes_to_str(libvlc_get_version()).split()[0])
except ValueError:
return 0
@ -5957,8 +6007,8 @@ if __name__ == '__main__':
"""Print libvlc version"""
try:
print('Build date: %s (%#x)' % (build_date, hex_version()))
print('LibVLC version: %s (%#x)' % (libvlc_get_version(), libvlc_hex_version()))
print('LibVLC compiler: %s' % libvlc_get_compiler())
print('LibVLC version: %s (%#x)' % (bytes_to_str(libvlc_get_version()), libvlc_hex_version()))
print('LibVLC compiler: %s' % bytes_to_str(libvlc_get_compiler()))
if plugin_path:
print('Plugin path: %s' % plugin_path)
except:
@ -5997,7 +6047,7 @@ if __name__ == '__main__':
player.video_set_marquee_int(VideoMarqueeOption.Refresh, 1000) # millisec (or sec?)
##t = '$L / $D or $P at $T'
t = '%Y-%m-%d %H:%M:%S'
player.video_set_marquee_string(VideoMarqueeOption.Text, t)
player.video_set_marquee_string(VideoMarqueeOption.Text, str_to_bytes(t))
# Some event manager examples. Note, the callback can be any Python
# callable and does not need to be decorated. Optionally, specify
@ -6017,7 +6067,7 @@ if __name__ == '__main__':
print_version()
media = player.get_media()
print('State: %s' % player.get_state())
print('Media: %s' % media.get_mrl())
print('Media: %s' % bytes_to_str(media.get_mrl()))
print('Track: %s/%s' % (player.video_get_track(), player.video_get_track_count()))
print('Current time: %s/%s' % (player.get_time(), media.get_duration()))
print('Position: %s' % player.get_position())
@ -6078,7 +6128,7 @@ if __name__ == '__main__':
print('Press q to quit, ? to get help.%s' % os.linesep)
while True:
k = getch().decode('utf8') # Python 3+
k = getch()
print('> %s' % k)
if k in keybindings:
keybindings[k]()

View File

@ -63,36 +63,32 @@ if VLC_AVAILABLE:
VLC_AVAILABLE = False
log.debug(u'VLC could not be loaded: %s' % version)
AUDIO_EXT = [
u'*.mp3'
, u'*.wav'
, u'*.ogg'
]
AUDIO_EXT = [u'*.mp3', u'*.wav', u'*.wma', u'*.ogg']
VIDEO_EXT = [
u'*.3gp'
, u'*.asf', u'*.wmv'
, u'*.au'
, u'*.avi'
, u'*.flv'
, u'*.mov'
, u'*.mp4'
, u'*.ogm'
, u'*.mkv', u'*.mka'
, u'*.ts', u'*.mpg'
, u'*.mpg', u'*.mp2'
, u'*.nsc'
, u'*.nsv'
, u'*.nut'
, u'*.ra', u'*.ram', u'*.rm', u'*.rv' ,u'*.rmbv'
, u'*.a52', u'*.dts', u'*.aac', u'*.flac' ,u'*.dv', u'*.vid'
, u'*.tta', u'*.tac'
, u'*.ty'
, u'*.dts'
, u'*.xa'
, u'*.iso'
, u'*.vob'
]
u'*.3gp',
u'*.asf', u'*.wmv',
u'*.au',
u'*.avi',
u'*.flv',
u'*.mov',
u'*.mp4',
u'*.ogm', u'*.ogv',
u'*.mkv', u'*.mka',
u'*.ts', u'*.mpg',
u'*.mpg', u'*.mp2',
u'*.nsc',
u'*.nsv',
u'*.nut',
u'*.ra', u'*.ram', u'*.rm', u'*.rv' ,u'*.rmbv',
u'*.a52', u'*.dts', u'*.aac', u'*.flac' ,u'*.dv', u'*.vid',
u'*.tta', u'*.tac',
u'*.ty',
u'*.dts',
u'*.xa',
u'*.iso',
u'*.vob'
]
class VlcPlayer(MediaPlayer):

View File

@ -47,7 +47,8 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
create_widget_action, find_and_set_in_combo_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.ui.printserviceform import PrintServiceForm
from openlp.core.utils import AppLocation, delete_file, split_filename
from openlp.core.utils import AppLocation, delete_file, split_filename, \
format_time
from openlp.core.utils.actions import ActionList, CategoryOrder
class ServiceManagerList(QtGui.QTreeWidget):
@ -379,6 +380,12 @@ class ServiceManager(QtGui.QWidget):
QtCore.QVariant(u'False')).toBool()
def supportedSuffixes(self, suffix):
"""
Adds Suffixes supported to the master list. Called from Plugins.
``suffix``
New Suffix to be supported
"""
self.suffixes.append(suffix)
def onNewServiceClicked(self):
@ -513,7 +520,7 @@ class ServiceManager(QtGui.QWidget):
'Service File Missing'))
message = unicode(translate('OpenLP.ServiceManager',
'File missing from service\n\n %s \n\n'
'Continue saving?' % path_from ))
'Continue saving?')) % path_from
answer = QtGui.QMessageBox.critical(self, title,
message,
QtGui.QMessageBox.StandardButtons(
@ -596,7 +603,7 @@ class ServiceManager(QtGui.QWidget):
service_day = Settings().value(
u'advanced/default service day', 7).toInt()[0]
if service_day == 7:
time = datetime.now()
local_time = datetime.now()
else:
service_hour = Settings().value(
u'advanced/default service hour', 11).toInt()[0]
@ -607,7 +614,7 @@ class ServiceManager(QtGui.QWidget):
if day_delta < 0:
day_delta += 7
time = now + timedelta(days=day_delta)
time = time.replace(hour=service_hour, minute=service_minute)
local_time = time.replace(hour=service_hour, minute=service_minute)
default_pattern = unicode(Settings().value(
u'advanced/default service name',
translate('OpenLP.AdvancedTab', 'Service %Y-%m-%d %H-%M',
@ -615,7 +622,7 @@ class ServiceManager(QtGui.QWidget):
'/\\?*|<>\[\]":+\nSee http://docs.python.org/library/'
'datetime.html#strftime-strptime-behavior for more '
'information.')).toString())
default_filename = time.strftime(default_pattern)
default_filename = format_time(default_pattern, local_time)
else:
default_filename = u''
directory = unicode(SettingsManager.get_last_dir(
@ -795,6 +802,10 @@ class ServiceManager(QtGui.QWidget):
self.repaintServiceList(item, -1)
def onServiceItemEditForm(self):
"""
Opens a dialog to edit the service item and update the service
display if changes are saved.
"""
item = self.findServiceItem()[0]
self.serviceItemEditForm.setServiceItem(
self.serviceItems[item][u'service_item'])
@ -805,7 +816,7 @@ class ServiceManager(QtGui.QWidget):
def previewLive(self, message):
"""
Called by the SlideController to request a preview item be made live
and allows the next preview to be updated if relevent.
and allows the next preview to be updated if relevant.
"""
uuid, row = message.split(u':')
for sitem in self.serviceItems:
@ -1082,12 +1093,12 @@ class ServiceManager(QtGui.QWidget):
"""
if serviceItem.is_command():
type = serviceItem._raw_frames[0][u'title'].split(u'.')[-1]
if type not in self.suffixes:
if type.lower() not in self.suffixes:
serviceItem.is_valid = False
def cleanUp(self):
"""
Empties the servicePath of temporary files.
Empties the servicePath of temporary files on system exit.
"""
log.debug(u'Cleaning up servicePath')
for file in os.listdir(self.servicePath):

View File

@ -286,19 +286,20 @@ class SlideController(Controller):
text=translate('OpenLP.SlideController', 'Pause Audio'),
tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
checked=False, visible=False, category=self.category,
triggers=self.onAudioPauseClicked)
context=QtCore.Qt.WindowShortcut,
shortcuts=[], triggers=self.onAudioPauseClicked)
self.audioMenu = QtGui.QMenu(
translate('OpenLP.SlideController', 'Background Audio'), self)
translate('OpenLP.SlideController', 'Background Audio'), self.toolbar)
self.audioPauseItem.setMenu(self.audioMenu)
self.audioPauseItem.setParent(self)
self.audioPauseItem.setParent(self.toolbar)
self.toolbar.widgetForAction(self.audioPauseItem).setPopupMode(
QtGui.QToolButton.MenuButtonPopup)
self.nextTrackItem = create_action(self, u'nextTrackItem',
text=UiStrings().NextTrack,
icon=u':/slides/media_playback_next.png', tooltip=translate(
'OpenLP.SlideController', 'Go to next audio track.'),
category=self.category, context=QtCore.Qt.WindowShortcut,
triggers=self.onNextTrackClicked)
category=self.category,
shortcuts=[], triggers=self.onNextTrackClicked)
self.audioMenu.addAction(self.nextTrackItem)
self.trackMenu = self.audioMenu.addMenu(
translate('OpenLP.SlideController', 'Tracks'))
@ -1346,7 +1347,7 @@ class SlideController(Controller):
"""
log.debug(u'SlideController onMediaStart')
file = os.path.join(item.get_frame_path(), item.get_frame_title())
self.mediaController.video(self, file, False, False)
self.mediaController.video(self, file, False, False, self.hideMode())
if not self.isLive or self.mediaController.withLivePreview:
self.previewDisplay.show()
self.slidePreview.hide()

View File

@ -157,7 +157,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
u'outlineColorButton', self.outlineColorButton)
self.mainAreaPage.registerField(
u'outlineSizeSpinBox', self.outlineSizeSpinBox)
self.mainAreaPage.registerField(u'shadowCheckBox', self.shadowCheckBox)
self.mainAreaPage.registerField(
u'shadowCheckBox', self.shadowCheckBox)
self.mainAreaPage.registerField(
u'mainBoldCheckBox', self.mainBoldCheckBox)
self.mainAreaPage.registerField(
@ -168,8 +169,10 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
u'shadowSizeSpinBox', self.shadowSizeSpinBox)
self.mainAreaPage.registerField(
u'footerSizeSpinBox', self.footerSizeSpinBox)
self.areaPositionPage.registerField(u'mainPositionX', self.mainXSpinBox)
self.areaPositionPage.registerField(u'mainPositionY', self.mainYSpinBox)
self.areaPositionPage.registerField(
u'mainPositionX', self.mainXSpinBox)
self.areaPositionPage.registerField(
u'mainPositionY', self.mainYSpinBox)
self.areaPositionPage.registerField(
u'mainPositionWidth', self.mainWidthSpinBox)
self.areaPositionPage.registerField(
@ -202,7 +205,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
"""
Updates the lines on a page on the wizard
"""
self.mainLineCountLabel.setText(unicode(translate('OpenLP.ThemeForm',
self.mainLineCountLabel.setText(unicode(translate(
'OpenLP.ThemeWizard',
'(approximately %d lines per slide)')) % int(lines))
def resizeEvent(self, event=None):
@ -224,6 +228,19 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.previewBoxLabel.setFixedSize(pixmapWidth + 2 * frameWidth,
pixmapHeight + 2 * frameWidth)
def validateCurrentPage(self):
background_image = BackgroundType.to_string(BackgroundType.Image)
if self.page(self.currentId()) == self.backgroundPage and \
self.theme.background_type == background_image and \
self.imageFileEdit.text().isEmpty():
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeWizard', 'Background Image Empty'),
translate('OpenLP.ThemeWizard', 'You have not selected a '
'background image. Please select one before continuing.'))
return False
else:
return True
def onCurrentIdChanged(self, pageId):
"""
Detects Page changes and updates as appropriate.
@ -521,7 +538,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
images_filter = u'%s;;%s (*.*) (*)' % (
images_filter, UiStrings().AllFiles)
filename = QtGui.QFileDialog.getOpenFileName(self,
translate('OpenLP.ThemeForm', 'Select Image'), u'',
translate('OpenLP.ThemeWizard', 'Select Image'), u'',
images_filter)
if filename:
self.theme.background_filename = unicode(filename)
@ -603,14 +620,14 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.theme.theme_name = unicode(self.field(u'name').toString())
if not self.theme.theme_name:
critical_error_message_box(
translate('OpenLP.ThemeForm', 'Theme Name Missing'),
translate('OpenLP.ThemeForm',
translate('OpenLP.ThemeWizard', 'Theme Name Missing'),
translate('OpenLP.ThemeWizard',
'There is no name for this theme. Please enter one.'))
return
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None':
critical_error_message_box(
translate('OpenLP.ThemeForm', 'Theme Name Invalid'),
translate('OpenLP.ThemeForm',
translate('OpenLP.ThemeWizard', 'Theme Name Invalid'),
translate('OpenLP.ThemeWizard',
'Invalid theme name. Please enter one.'))
return
saveFrom = None

View File

@ -257,6 +257,7 @@ class ThemeManager(QtGui.QWidget):
theme.set_default_header_footer()
self.themeForm.theme = theme
self.themeForm.exec_()
self.loadThemes()
def onRenameTheme(self):
"""
@ -281,7 +282,6 @@ class ThemeManager(QtGui.QWidget):
for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(old_theme_name):
plugin.renameTheme(old_theme_name, new_theme_name)
self.loadThemes()
self.mainwindow.renderer.update_theme(
new_theme_name, old_theme_name)
@ -314,6 +314,7 @@ class ThemeManager(QtGui.QWidget):
theme_data.theme_name = new_theme_name
theme_data.extend_image_filename(self.path)
self.saveTheme(theme_data, save_from, save_to)
self.loadThemes()
def onEditTheme(self):
"""
@ -331,6 +332,7 @@ class ThemeManager(QtGui.QWidget):
self.themeForm.exec_(True)
self.oldBackgroundImage = None
self.mainwindow.renderer.update_theme(theme.theme_name)
self.loadThemes()
def onDeleteTheme(self):
"""
@ -345,10 +347,10 @@ class ThemeManager(QtGui.QWidget):
row = self.themeListWidget.row(item)
self.themeListWidget.takeItem(row)
self.deleteTheme(theme)
self.mainwindow.renderer.update_theme(theme, only_delete=True)
# As we do not reload the themes, push out the change. Reload the
# list as the internal lists and events need to be triggered.
self._pushThemes()
self.mainwindow.renderer.update_theme(theme, only_delete=True)
def deleteTheme(self, theme):
"""
@ -516,7 +518,7 @@ class ThemeManager(QtGui.QWidget):
translate('OpenLP.ThemeManager', 'Theme Already Exists'),
translate('OpenLP.ThemeManager',
'Theme %s already exists. Do you want to replace it?'
% theme_name),
).replace('%s', theme_name),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No),
QtGui.QMessageBox.No)
@ -672,7 +674,6 @@ class ThemeManager(QtGui.QWidget):
theme.background_filename,
ImageSource.Theme, QtGui.QColor(theme.background_border_color))
self.mainwindow.imageManager.processUpdates()
self.loadThemes()
def _writeTheme(self, theme, image_from, image_to):
"""

View File

@ -136,7 +136,7 @@ class AppLocation(object):
else:
path = AppLocation.get_directory(AppLocation.DataDir)
check_directory_exists(path)
return path
return os.path.normpath(path)
@staticmethod
def get_section_data_path(section):
@ -469,10 +469,29 @@ def get_uno_instance(resolver):
return resolver.resolve(u'uno:socket,host=localhost,port=2002;' \
+ u'urp;StarOffice.ComponentContext')
def format_time(text, local_time):
"""
Workaround for Python built-in time formatting fuction time.strftime().
time.strftime() accepts only ascii characters. This function accepts
unicode string and passes individual % placeholders to time.strftime().
This ensures only ascii characters are passed to time.strftime().
``text``
The text to be processed.
``local_time``
The time to be used to add to the string. This is a time object
"""
def match_formatting(match):
return local_time.strftime(match.group())
return re.sub('\%[a-zA-Z]', match_formatting, text)
from languagemanager import LanguageManager
from actions import ActionList
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
u'ActionList', u'get_web_page', u'get_uno_command', u'get_uno_instance',
u'delete_file', u'clean_filename']
u'delete_file', u'clean_filename', u'format_time']

View File

@ -124,6 +124,8 @@ class BGExtract(object):
self._remove_elements(tag, 'div', 'footnotes')
self._remove_elements(tag, 'div', 'crossrefs')
self._remove_elements(tag, 'h3')
self._remove_elements(tag, 'h4')
self._remove_elements(tag, 'h5')
def _extract_verses(self, tags):
"""
@ -155,12 +157,59 @@ class BGExtract(object):
text = text.replace(old, new)
text = u' '.join(text.split())
if verse and text:
verses.append((int(verse.strip()), text))
verse = verse.strip()
try:
verse = int(verse)
except (TypeError, ValueError):
verse_parts = verse.split(u'-')
if len(verse_parts) > 1:
verse = int(verse_parts[0])
verses.append((verse, text))
verse_list = {}
for verse, text in verses[::-1]:
verse_list[verse] = text
return verse_list
def _extract_verses_old(self, div):
"""
Use the old style of parsing for those Bibles on BG who mysteriously
have not been migrated to the new (still broken) HTML.
``div``
The parent div.
"""
verse_list = {}
# Cater for inconsistent mark up in the first verse of a chapter.
first_verse = div.find(u'versenum')
if first_verse and first_verse.contents:
verse_list[1] = unicode(first_verse.contents[0])
for verse in div(u'sup', u'versenum'):
raw_verse_num = verse.next
clean_verse_num = 0
# Not all verses exist in all translations and may or may not be
# represented by a verse number. If they are not fine, if they are
# it will probably be in a format that breaks int(). We will then
# have no idea what garbage may be sucked in to the verse text so
# if we do not get a clean int() then ignore the verse completely.
try:
clean_verse_num = int(str(raw_verse_num))
except ValueError:
log.warn(u'Illegal verse number: %s', unicode(raw_verse_num))
if clean_verse_num:
verse_text = raw_verse_num.next
part = raw_verse_num.next.next
while not (isinstance(part, Tag) and
part.get(u'class') == u'versenum'):
# While we are still in the same verse grab all the text.
if isinstance(part, NavigableString):
verse_text += part
if isinstance(part.next, Tag) and part.next.name == u'div':
# Run out of verses so stop.
break
part = part.next
verse_list[clean_verse_num] = unicode(verse_text)
return verse_list
def get_bible_chapter(self, version, book_name, chapter):
"""
Access and decode Bibles via the BibleGateway website.
@ -189,7 +238,13 @@ class BGExtract(object):
Receiver.send_message(u'openlp_process_events')
div = soup.find('div', 'result-text-style-normal')
self._clean_soup(div)
verse_list = self._extract_verses(div.findAll('span', 'text'))
span_list = div.findAll('span', 'text')
log.debug('Span list: %s', span_list)
if not span_list:
# If we don't get any spans then we must have the old HTML format
verse_list = self._extract_verses_old(div)
else:
verse_list = self._extract_verses(span_list)
if not verse_list:
log.debug(u'No content found in the BibleGateway response.')
send_error_message(u'parse')

View File

@ -208,24 +208,16 @@ class BibleManager(object):
def delete_bible(self, name):
"""
Delete a bible completly.
Delete a bible completely.
``name``
The name of the bible.
"""
log.debug(u'BibleManager.delete_bible("%s")', name)
files = SettingsManager.get_files(self.settingsSection,
self.suffix)
if u'alternative_book_names.sqlite' in files:
files.remove(u'alternative_book_names.sqlite')
for filename in files:
bible = BibleDB(self.parent, path=self.path, file=filename)
# Remove the bible files
if name == bible.get_name():
bible.session.close()
if delete_file(os.path.join(self.path, filename)):
return True
return False
bible = self.db_cache[name]
bible.session.close()
bible.session = None
return delete_file(os.path.join(bible.path, bible.file))
def get_bibles(self):
"""

View File

@ -27,9 +27,10 @@
###############################################################################
import logging
from lxml import objectify
from lxml import etree, objectify
from openlp.core.lib import Receiver, translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
log = logging.getLogger(__name__)
@ -113,8 +114,15 @@ class OpenSongBible(BibleDB):
(db_book.name, int(chapter.attrib[u'n'].split()[-1])))
self.session.commit()
Receiver.send_message(u'openlp_process_events')
except etree.XMLSyntaxError as inst:
critical_error_message_box(
message=translate('BiblesPlugin.OpenSongImport',
'Incorrect Bible file type supplied. OpenSong Bibles may be '
'compressed. You must decompress them before import.'))
log.exception(inst)
success = False
except (IOError, AttributeError):
log.exception(u'Loading bible from OpenSong file failed')
log.exception(u'Loading Bible from OpenSong file failed')
success = False
finally:
if file:

View File

@ -49,6 +49,8 @@ class Ui_CustomSlideEditDialog(object):
self.retranslateUi(customSlideEditDialog)
def retranslateUi(self, customSlideEditDialog):
customSlideEditDialog.setWindowTitle(
translate('CustomPlugin.EditVerseForm', 'Edit Slide'))
self.splitButton.setText(UiStrings().Split)
self.splitButton.setToolTip(UiStrings().SplitToolTip)
self.insertButton.setText(

View File

@ -122,9 +122,9 @@ class RemoteTab(SettingsTab):
self.androidAppGroupBox.setTitle(
translate('RemotePlugin.RemoteTab', 'Android App'))
self.qrDescriptionLabel.setText(translate('RemotePlugin.RemoteTab',
'Scan the QR code or click <a '
'href="https://market.android.com/details?id=org.openlp.android">'
'download</a> to install the Android app from the Market.'))
'Scan the QR code or click <a href="https://play.google.com/store/'
'apps/details?id=org.openlp.android">download</a> to install the '
'Android app from Google Play.'))
def setUrls(self):
ipAddress = u'localhost'

View File

@ -528,9 +528,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for row in self.findVerseSplit.split(verse_list):
for match in row.split(u'---['):
for count, parts in enumerate(match.split(u']---\n')):
if len(parts) <= 1:
continue
if count == 0:
if len(parts) == 0:
continue
# handling carefully user inputted versetags
separator = parts.find(u':')
if separator >= 0:

View File

@ -67,7 +67,7 @@ class Ui_EditVerseDialog(object):
self.verseTypeLayout.addStretch()
self.dialogLayout.addLayout(self.verseTypeLayout)
self.buttonBox = create_button_box(editVerseDialog, u'buttonBox',
[u'cancel', u'save'])
[u'cancel', u'ok'])
self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(editVerseDialog)

View File

@ -185,22 +185,3 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
text = u'---[%s:1]---\n%s' % \
(VerseType.TranslatedNames[VerseType.Verse], text)
return text
def accept(self):
if self.hasSingleVerse:
value = unicode(self.getVerse()[0])
else:
log.debug(unicode(self.getVerse()[0]).split(u'\n'))
value = unicode(self.getVerse()[0]).split(u'\n')[1]
if not value:
lines = unicode(self.getVerse()[0]).split(u'\n')
index = 2
while index < len(lines) and not value:
value = lines[index]
index += 1
if not value:
critical_error_message_box(
message=translate('SongsPlugin.EditSongForm',
'You need to type some text in to the verse.'))
return False
QtGui.QDialog.accept(self)

View File

@ -483,8 +483,11 @@ class FoilPresenter(object):
# Process verse order
verse_order = []
verse_strophenr = []
for strophennummer in foilpresenterfolie.reihenfolge.strophennummer:
verse_strophenr.append(strophennummer)
try:
for strophennummer in foilpresenterfolie.reihenfolge.strophennummer:
verse_strophenr.append(strophennummer)
except AttributeError:
pass
# Currently we do not support different "parts"!
if u'0' in temp_verse_order:
for vers in temp_verse_order_backup:
@ -538,12 +541,17 @@ class FoilPresenter(object):
``song``
The song object.
"""
for title_string in foilpresenterfolie.titel.titelstring:
if not song.title:
song.title = self._child(title_string)
song.alternate_title = u''
else:
song.alternate_title = self._child(title_string)
try:
for title_string in foilpresenterfolie.titel.titelstring:
if not song.title:
song.title = self._child(title_string)
song.alternate_title = u''
else:
song.alternate_title = self._child(title_string)
except AttributeError:
# Use first line of first verse
first_line = self._child(foilpresenterfolie.strophen.strophe.text_)
song.title = first_line.split('\n')[0]
def _process_topics(self, foilpresenterfolie, song):
"""

View File

@ -103,7 +103,7 @@ class PowerSongImport(SongImport):
self.logError(unicode(translate('SongsPlugin.PowerSongImport',
'No songs to import.')),
unicode(translate('SongsPlugin.PowerSongImport',
'No %s files found.' % PS_string)))
'No %s files found.')) % PS_string)
return
self.importWizard.progressBar.setMaximum(len(self.importSource))
for file in self.importSource:
@ -122,8 +122,8 @@ class PowerSongImport(SongImport):
parse_error = True
self.logError(os.path.basename(file), unicode(
translate('SongsPlugin.PowerSongImport',
'Invalid %s file. Unexpected byte value.'
% PS_string)))
'Invalid %s file. Unexpected byte value.'))
% PS_string)
break
else:
if label == u'TITLE':
@ -141,14 +141,14 @@ class PowerSongImport(SongImport):
if not self.title:
self.logError(os.path.basename(file), unicode(
translate('SongsPlugin.PowerSongImport',
'Invalid %s file. Missing "TITLE" header.' % PS_string)))
'Invalid %s file. Missing "TITLE" header.')) % PS_string)
continue
# Check that file had COPYRIGHTLINE label
if not found_copyright:
self.logError(self.title, unicode(
translate('SongsPlugin.PowerSongImport',
'Invalid %s file. Missing "COPYRIGHTLINE" '
'header.' % PS_string)))
'header.')) % PS_string)
continue
# Check that file had at least one verse
if not self.verses:

View File

@ -91,7 +91,7 @@ class ZionWorxImport(SongImport):
self.logError(unicode(translate('SongsPlugin.ZionWorxImport',
'Error reading CSV file.')),
unicode(translate('SongsPlugin.ZionWorxImport',
'Line %d: %s' % (songs_reader.line_num, e))))
'Line %d: %s')) % (songs_reader.line_num, e))
return
num_records = len(records)
log.info(u'%s records found in CSV file' % num_records)
@ -111,7 +111,7 @@ class ZionWorxImport(SongImport):
self.logError(unicode(translate(
'SongsPlugin.ZionWorxImport', 'Record %d' % index)),
unicode(translate('SongsPlugin.ZionWorxImport',
'Decoding error: %s' % e)))
'Decoding error: %s')) % e)
continue
except TypeError, e:
self.logError(unicode(translate(
@ -130,7 +130,7 @@ class ZionWorxImport(SongImport):
title = self.title
if not self.finish():
self.logError(unicode(translate(
'SongsPlugin.ZionWorxImport', 'Record %d' % index))
'SongsPlugin.ZionWorxImport', 'Record %d')) % index
+ (u': "' + title + u'"' if title else u''))
def _decode(self, str):

View File

@ -147,6 +147,7 @@ class SongsPlugin(Plugin):
progressDialog = QtGui.QProgressDialog(
translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel,
0, maxSongs, self.formParent)
progressDialog.setWindowTitle(translate('SongsPlugin', 'Reindexing songs'))
progressDialog.setWindowModality(QtCore.Qt.WindowModal)
songs = self.manager.get_all_objects(Song)
for number, song in enumerate(songs):
@ -247,6 +248,7 @@ class SongsPlugin(Plugin):
return
progress = QtGui.QProgressDialog(self.formParent)
progress.setWindowModality(QtCore.Qt.WindowModal)
progress.setWindowTitle(translate('OpenLP.Ui', 'Importing Songs'))
progress.setLabelText(translate('OpenLP.Ui', 'Starting import...'))
progress.setCancelButton(None)
progress.setRange(0, len(song_dbs))

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

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

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

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

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

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

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

File diff suppressed because it is too large Load Diff

7362
resources/i18n/sk.ts Normal file

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

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -116,7 +116,7 @@
<file>system_help_contents.png</file>
<file>system_online_help.png</file>
<file>system_mediamanager.png</file>
<file>system_contribute.png</file>
<file>system_volunteer.png</file>
<file>system_servicemanager.png</file>
<file>system_thememanager.png</file>
<file>system_exit.png</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB