forked from openlp/openlp
r2072
This commit is contained in:
commit
42dec84a31
|
@ -1 +1 @@
|
||||||
1.9.9-bzr1956
|
1.9.12
|
||||||
|
|
|
@ -35,6 +35,7 @@ logging and a plugin framework are contained within the openlp.core module.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import platform
|
||||||
import logging
|
import logging
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
from traceback import format_exception
|
from traceback import format_exception
|
||||||
|
@ -102,8 +103,13 @@ class OpenLP(QtGui.QApplication):
|
||||||
Run the OpenLP application.
|
Run the OpenLP application.
|
||||||
"""
|
"""
|
||||||
self.eventLoopIsActive = False
|
self.eventLoopIsActive = False
|
||||||
# On Windows, the args passed into the constructor are
|
# On Windows, the args passed into the constructor are ignored. Not
|
||||||
# ignored. Not very handy, so set the ones we want to use.
|
# 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)
|
self.args.extend(args)
|
||||||
# provide a listener for widgets to reqest a screen update.
|
# provide a listener for widgets to reqest a screen update.
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
@ -248,6 +254,13 @@ def main(args=None):
|
||||||
# Parse command line options and deal with them.
|
# Parse command line options and deal with them.
|
||||||
# Use args supplied programatically if possible.
|
# Use args supplied programatically if possible.
|
||||||
(options, args) = parser.parse_args(args) if args else parser.parse_args()
|
(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 = []
|
qt_args = []
|
||||||
if options.loglevel.lower() in ['d', 'debug']:
|
if options.loglevel.lower() in ['d', 'debug']:
|
||||||
log.setLevel(logging.DEBUG)
|
log.setLevel(logging.DEBUG)
|
||||||
|
@ -259,6 +272,9 @@ def main(args=None):
|
||||||
qt_args.extend(['-style', options.style])
|
qt_args.extend(['-style', options.style])
|
||||||
# Throw the rest of the arguments at Qt, just in case.
|
# Throw the rest of the arguments at Qt, just in case.
|
||||||
qt_args.extend(args)
|
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
|
# Initialise the resources
|
||||||
qInitResources()
|
qInitResources()
|
||||||
# Now create and actually run the application.
|
# Now create and actually run the application.
|
||||||
|
@ -269,10 +285,6 @@ def main(args=None):
|
||||||
app.setApplicationName(u'OpenLPPortable')
|
app.setApplicationName(u'OpenLPPortable')
|
||||||
Settings.setDefaultFormat(Settings.IniFormat)
|
Settings.setDefaultFormat(Settings.IniFormat)
|
||||||
# Get location OpenLPPortable.ini
|
# 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'..',
|
portable_settings_file = os.path.abspath(os.path.join(app_path, u'..',
|
||||||
u'..', u'Data', u'OpenLP.ini'))
|
u'..', u'Data', u'OpenLP.ini'))
|
||||||
# Make this our settings file
|
# Make this our settings file
|
||||||
|
@ -289,7 +301,6 @@ def main(args=None):
|
||||||
portable_settings.sync()
|
portable_settings.sync()
|
||||||
else:
|
else:
|
||||||
app.setApplicationName(u'OpenLP')
|
app.setApplicationName(u'OpenLP')
|
||||||
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
|
|
||||||
app.setApplicationVersion(get_application_version()[u'version'])
|
app.setApplicationVersion(get_application_version()[u'version'])
|
||||||
# Instance check
|
# Instance check
|
||||||
if not options.testing:
|
if not options.testing:
|
||||||
|
|
|
@ -256,7 +256,7 @@ class Renderer(object):
|
||||||
if not self.force_page:
|
if not self.force_page:
|
||||||
self.display.buildHtml(serviceItem)
|
self.display.buildHtml(serviceItem)
|
||||||
raw_html = serviceItem.get_rendered_frame(0)
|
raw_html = serviceItem.get_rendered_frame(0)
|
||||||
self.display.text(raw_html)
|
self.display.text(raw_html, False)
|
||||||
preview = self.display.preview()
|
preview = self.display.preview()
|
||||||
return preview
|
return preview
|
||||||
self.force_page = False
|
self.force_page = False
|
||||||
|
@ -365,7 +365,7 @@ class Renderer(object):
|
||||||
The theme information
|
The theme information
|
||||||
"""
|
"""
|
||||||
if not theme_data.font_main_override:
|
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:
|
else:
|
||||||
return QtCore.QRect(theme_data.font_main_x, theme_data.font_main_y,
|
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)
|
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:
|
if theme_data.font_main_shadow:
|
||||||
self.page_width -= int(theme_data.font_main_shadow_size)
|
self.page_width -= int(theme_data.font_main_shadow_size)
|
||||||
self.page_height -= 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.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.
|
# Adjust width and height to account for shadow. outline done in css.
|
||||||
html = u"""<!DOCTYPE html><html><head><script>
|
html = u"""<!DOCTYPE html><html><head><script>
|
||||||
function show_text(newtext) {
|
function show_text(newtext) {
|
||||||
|
@ -450,7 +457,6 @@ class Renderer(object):
|
||||||
previous_html, previous_raw, html_lines, lines, separator, u'')
|
previous_html, previous_raw, html_lines, lines, separator, u'')
|
||||||
else:
|
else:
|
||||||
previous_raw = separator.join(lines)
|
previous_raw = separator.join(lines)
|
||||||
if previous_raw:
|
|
||||||
formatted.append(previous_raw)
|
formatted.append(previous_raw)
|
||||||
log.debug(u'_paginate_slide - End')
|
log.debug(u'_paginate_slide - End')
|
||||||
return formatted
|
return formatted
|
||||||
|
|
|
@ -72,10 +72,10 @@ class Ui_AboutDialog(object):
|
||||||
self.licenseTabLayout.addWidget(self.licenseTextEdit)
|
self.licenseTabLayout.addWidget(self.licenseTextEdit)
|
||||||
self.aboutNotebook.addTab(self.licenseTab, u'')
|
self.aboutNotebook.addTab(self.licenseTab, u'')
|
||||||
self.aboutDialogLayout.addWidget(self.aboutNotebook)
|
self.aboutDialogLayout.addWidget(self.aboutNotebook)
|
||||||
self.contributeButton = create_button(None, u'contributeButton',
|
self.volunteerButton = create_button(None, u'volunteerButton',
|
||||||
icon=u':/system/system_contribute.png')
|
icon=u':/system/system_volunteer.png')
|
||||||
self.buttonBox = create_button_box(aboutDialog, u'buttonBox',
|
self.buttonBox = create_button_box(aboutDialog, u'buttonBox',
|
||||||
[u'close'], [self.contributeButton])
|
[u'close'], [self.volunteerButton])
|
||||||
self.aboutDialogLayout.addWidget(self.buttonBox)
|
self.aboutDialogLayout.addWidget(self.buttonBox)
|
||||||
self.retranslateUi(aboutDialog)
|
self.retranslateUi(aboutDialog)
|
||||||
self.aboutNotebook.setCurrentIndex(0)
|
self.aboutNotebook.setCurrentIndex(0)
|
||||||
|
@ -96,7 +96,7 @@ class Ui_AboutDialog(object):
|
||||||
'\n'
|
'\n'
|
||||||
'OpenLP is written and maintained by volunteers. If you would '
|
'OpenLP is written and maintained by volunteers. If you would '
|
||||||
'like to see more free Christian software being written, please '
|
'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.setTabText(
|
||||||
self.aboutNotebook.indexOf(self.aboutTab), UiStrings().About)
|
self.aboutNotebook.indexOf(self.aboutTab), UiStrings().About)
|
||||||
|
@ -615,5 +615,5 @@ class Ui_AboutDialog(object):
|
||||||
self.aboutNotebook.setTabText(
|
self.aboutNotebook.setTabText(
|
||||||
self.aboutNotebook.indexOf(self.licenseTab),
|
self.aboutNotebook.indexOf(self.licenseTab),
|
||||||
translate('OpenLP.AboutForm', 'License'))
|
translate('OpenLP.AboutForm', 'License'))
|
||||||
self.contributeButton.setText(translate('OpenLP.AboutForm',
|
self.volunteerButton.setText(translate('OpenLP.AboutForm',
|
||||||
'Contribute'))
|
'Volunteer'))
|
||||||
|
|
|
@ -54,10 +54,10 @@ class AboutForm(QtGui.QDialog, Ui_AboutDialog):
|
||||||
build_text = u''
|
build_text = u''
|
||||||
about_text = about_text.replace(u'<revision>', build_text)
|
about_text = about_text.replace(u'<revision>', build_text)
|
||||||
self.aboutTextEdit.setPlainText(about_text)
|
self.aboutTextEdit.setPlainText(about_text)
|
||||||
QtCore.QObject.connect(self.contributeButton,
|
QtCore.QObject.connect(self.volunteerButton,
|
||||||
QtCore.SIGNAL(u'clicked()'), self.onContributeButtonClicked)
|
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.
|
Launch a web browser and go to the contribute page on the site.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -38,7 +38,7 @@ import sys
|
||||||
from openlp.core.lib import SettingsTab, translate, build_icon, Receiver
|
from openlp.core.lib import SettingsTab, translate, build_icon, Receiver
|
||||||
from openlp.core.lib.settings import Settings
|
from openlp.core.lib.settings import Settings
|
||||||
from openlp.core.lib.ui import UiStrings
|
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
|
from openlp.core.lib import SlideLimits
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -527,7 +527,7 @@ class AdvancedTab(SettingsTab):
|
||||||
'Click "No" to stop loading OpenLP. allowing you to fix '
|
'Click "No" to stop loading OpenLP. allowing you to fix '
|
||||||
'the the problem.\n\n'
|
'the the problem.\n\n'
|
||||||
'Click "Yes" to reset the data directory to the default '
|
'Click "Yes" to reset the data directory to the default '
|
||||||
'location.' % self.currentDataPath),
|
'location.').replace('%s', self.currentDataPath),
|
||||||
QtGui.QMessageBox.StandardButtons(
|
QtGui.QMessageBox.StandardButtons(
|
||||||
QtGui.QMessageBox.Yes |
|
QtGui.QMessageBox.Yes |
|
||||||
QtGui.QMessageBox.No),
|
QtGui.QMessageBox.No),
|
||||||
|
@ -545,6 +545,10 @@ class AdvancedTab(SettingsTab):
|
||||||
self.currentDataPath))
|
self.currentDataPath))
|
||||||
self.defaultColorButton.setStyleSheet(
|
self.defaultColorButton.setStyleSheet(
|
||||||
u'background-color: %s' % self.defaultColor)
|
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):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
|
@ -608,18 +612,18 @@ class AdvancedTab(SettingsTab):
|
||||||
def generateServiceNameExample(self):
|
def generateServiceNameExample(self):
|
||||||
preset_is_valid = True
|
preset_is_valid = True
|
||||||
if self.serviceNameDay.currentIndex() == 7:
|
if self.serviceNameDay.currentIndex() == 7:
|
||||||
time = datetime.now()
|
local_time = datetime.now()
|
||||||
else:
|
else:
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
day_delta = self.serviceNameDay.currentIndex() - now.weekday()
|
day_delta = self.serviceNameDay.currentIndex() - now.weekday()
|
||||||
if day_delta < 0:
|
if day_delta < 0:
|
||||||
day_delta += 7
|
day_delta += 7
|
||||||
time = now + timedelta(days=day_delta)
|
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())
|
minute = self.serviceNameTime.time().minute())
|
||||||
try:
|
try:
|
||||||
service_name_example = time.strftime(unicode(
|
service_name_example = format_time(unicode(
|
||||||
self.serviceNameEdit.text()))
|
self.serviceNameEdit.text()), local_time)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
preset_is_valid = False
|
preset_is_valid = False
|
||||||
service_name_example = translate('OpenLP.AdvancedTab',
|
service_name_example = translate('OpenLP.AdvancedTab',
|
||||||
|
@ -670,6 +674,7 @@ class AdvancedTab(SettingsTab):
|
||||||
options = QtGui.QFileDialog.ShowDirsOnly))
|
options = QtGui.QFileDialog.ShowDirsOnly))
|
||||||
# Set the new data path.
|
# Set the new data path.
|
||||||
if new_data_path:
|
if new_data_path:
|
||||||
|
new_data_path = os.path.normpath(new_data_path)
|
||||||
if self.currentDataPath.lower() == new_data_path.lower():
|
if self.currentDataPath.lower() == new_data_path.lower():
|
||||||
self.onDataDirectoryCancelButtonClicked()
|
self.onDataDirectoryCancelButtonClicked()
|
||||||
return
|
return
|
||||||
|
@ -682,7 +687,7 @@ class AdvancedTab(SettingsTab):
|
||||||
'Are you sure you want to change the location of the OpenLP '
|
'Are you sure you want to change the location of the OpenLP '
|
||||||
'data directory to:\n\n%s\n\n'
|
'data directory to:\n\n%s\n\n'
|
||||||
'The data directory will be changed when OpenLP is closed.'
|
'The data directory will be changed when OpenLP is closed.'
|
||||||
% new_data_path),
|
).replace('%s', new_data_path),
|
||||||
QtGui.QMessageBox.StandardButtons(
|
QtGui.QMessageBox.StandardButtons(
|
||||||
QtGui.QMessageBox.Yes |
|
QtGui.QMessageBox.Yes |
|
||||||
QtGui.QMessageBox.No),
|
QtGui.QMessageBox.No),
|
||||||
|
@ -746,7 +751,7 @@ class AdvancedTab(SettingsTab):
|
||||||
'The location you have selected \n\n%s\n\n'
|
'The location you have selected \n\n%s\n\n'
|
||||||
'appears to contain OpenLP data files. Do you wish to replace '
|
'appears to contain OpenLP data files. Do you wish to replace '
|
||||||
'these files with the current data files?'
|
'these files with the current data files?'
|
||||||
% os.path.abspath(data_path,)),
|
).replace('%s', os.path.abspath(data_path,)),
|
||||||
QtGui.QMessageBox.StandardButtons(
|
QtGui.QMessageBox.StandardButtons(
|
||||||
QtGui.QMessageBox.Yes |
|
QtGui.QMessageBox.Yes |
|
||||||
QtGui.QMessageBox.No),
|
QtGui.QMessageBox.No),
|
||||||
|
|
|
@ -138,11 +138,16 @@ class MainDisplay(Display):
|
||||||
if Settings().value(u'advanced/x11 bypass wm',
|
if Settings().value(u'advanced/x11 bypass wm',
|
||||||
QtCore.QVariant(True)).toBool():
|
QtCore.QVariant(True)).toBool():
|
||||||
windowFlags |= QtCore.Qt.X11BypassWindowManagerHint
|
windowFlags |= QtCore.Qt.X11BypassWindowManagerHint
|
||||||
# FIXME: QtCore.Qt.SplashScreen is workaround to make display screen
|
# TODO: The following combination of windowFlags works correctly
|
||||||
# stay always on top on Mac OS X. For details see bug 906926.
|
# on Mac OS X. For next OpenLP version we should test it on other
|
||||||
# It needs more investigation to fix it properly.
|
# platforms. For OpenLP 2.0 keep it only for OS X to not cause any
|
||||||
|
# regressions on other platforms.
|
||||||
if sys.platform == 'darwin':
|
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.setWindowFlags(windowFlags)
|
||||||
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||||
self.setTransparency(False)
|
self.setTransparency(False)
|
||||||
|
@ -224,20 +229,33 @@ class MainDisplay(Display):
|
||||||
self.__hideMouse()
|
self.__hideMouse()
|
||||||
log.debug(u'Finished MainDisplay setup')
|
log.debug(u'Finished MainDisplay setup')
|
||||||
|
|
||||||
def text(self, slide):
|
def text(self, slide, animate=True):
|
||||||
"""
|
"""
|
||||||
Add the slide text from slideController
|
Add the slide text from slideController
|
||||||
|
|
||||||
``slide``
|
``slide``
|
||||||
The slide text to be displayed
|
The slide text to be displayed
|
||||||
|
|
||||||
|
``animate``
|
||||||
|
Perform transitions if applicable when setting the text
|
||||||
"""
|
"""
|
||||||
log.debug(u'text to display')
|
log.debug(u'text to display')
|
||||||
# Wait for the webview to update before displaying text.
|
# Wait for the webview to update before displaying text.
|
||||||
while not self.webLoaded:
|
while not self.webLoaded:
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
self.setGeometry(self.screen[u'size'])
|
self.setGeometry(self.screen[u'size'])
|
||||||
|
if animate:
|
||||||
self.frame.evaluateJavaScript(u'show_text("%s")' %
|
self.frame.evaluateJavaScript(u'show_text("%s")' %
|
||||||
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
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):
|
def alert(self, text, location):
|
||||||
"""
|
"""
|
||||||
|
@ -580,7 +598,7 @@ class AudioPlayer(QtCore.QObject):
|
||||||
self.playlist.extend(map(Phonon.MediaSource, filenames))
|
self.playlist.extend(map(Phonon.MediaSource, filenames))
|
||||||
|
|
||||||
def next(self):
|
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
|
return
|
||||||
isPlaying = self.mediaObject.state() == Phonon.PlayingState
|
isPlaying = self.mediaObject.state() == Phonon.PlayingState
|
||||||
self.currentIndex += 1
|
self.currentIndex += 1
|
||||||
|
|
|
@ -210,6 +210,8 @@ class Ui_MainWindow(object):
|
||||||
icon=u':/system/system_exit.png',
|
icon=u':/system/system_exit.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Alt+F4')],
|
shortcuts=[QtGui.QKeySequence(u'Alt+F4')],
|
||||||
category=UiStrings().File, triggers=mainWindow.close)
|
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),
|
action_list.add_category(unicode(UiStrings().Import),
|
||||||
CategoryOrder.standardMenu)
|
CategoryOrder.standardMenu)
|
||||||
self.importThemeItem = create_action(mainWindow,
|
self.importThemeItem = create_action(mainWindow,
|
||||||
|
@ -304,6 +306,8 @@ class Ui_MainWindow(object):
|
||||||
self.settingsConfigureItem = create_action(mainWindow,
|
self.settingsConfigureItem = create_action(mainWindow,
|
||||||
u'settingsConfigureItem', icon=u':/system/system_settings.png',
|
u'settingsConfigureItem', icon=u':/system/system_settings.png',
|
||||||
category=UiStrings().Settings)
|
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,
|
self.settingsImportItem = create_action(mainWindow,
|
||||||
u'settingsImportItem', category=UiStrings().Settings)
|
u'settingsImportItem', category=UiStrings().Settings)
|
||||||
self.settingsExportItem = create_action(mainWindow,
|
self.settingsExportItem = create_action(mainWindow,
|
||||||
|
@ -314,6 +318,8 @@ class Ui_MainWindow(object):
|
||||||
icon=u':/system/system_about.png',
|
icon=u':/system/system_about.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+F1')],
|
shortcuts=[QtGui.QKeySequence(u'Ctrl+F1')],
|
||||||
category=UiStrings().Help, triggers=self.onAboutItemClicked)
|
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':
|
if os.name == u'nt':
|
||||||
self.localHelpFile = os.path.join(
|
self.localHelpFile = os.path.join(
|
||||||
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
|
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.themesSettingsSection])
|
||||||
setting_sections.extend([self.displayTagsSection])
|
setting_sections.extend([self.displayTagsSection])
|
||||||
setting_sections.extend([self.headerSection])
|
setting_sections.extend([self.headerSection])
|
||||||
|
setting_sections.extend([u'crashreport'])
|
||||||
# Add plugin sections.
|
# Add plugin sections.
|
||||||
for plugin in self.pluginManager.plugins:
|
for plugin in self.pluginManager.plugins:
|
||||||
setting_sections.extend([plugin.name])
|
setting_sections.extend([plugin.name])
|
||||||
|
@ -992,7 +999,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||||
'settings file.\n\n'
|
'settings file.\n\n'
|
||||||
'Section [%s] is not valid \n\n'
|
'Section [%s] is not valid \n\n'
|
||||||
'Processing has terminated and no changed have been made.'
|
'Processing has terminated and no changed have been made.'
|
||||||
% section),
|
).replace('%s', section),
|
||||||
QtGui.QMessageBox.StandardButtons(
|
QtGui.QMessageBox.StandardButtons(
|
||||||
QtGui.QMessageBox.Ok))
|
QtGui.QMessageBox.Ok))
|
||||||
return
|
return
|
||||||
|
@ -1511,7 +1518,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||||
translate('OpenLP.MainWindow',
|
translate('OpenLP.MainWindow',
|
||||||
'Copying OpenLP data to new data directory location - %s '
|
'Copying OpenLP data to new data directory location - %s '
|
||||||
'- Please wait for copy to finish'
|
'- Please wait for copy to finish'
|
||||||
% self.newDataPath))
|
).replace('%s', self.newDataPath))
|
||||||
dir_util.copy_tree(old_data_path, self.newDataPath)
|
dir_util.copy_tree(old_data_path, self.newDataPath)
|
||||||
log.info(u'Copy sucessful')
|
log.info(u'Copy sucessful')
|
||||||
except (IOError, os.error, DistutilsFileError), why:
|
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', 'New Data Directory Error'),
|
||||||
translate('OpenLP.MainWindow',
|
translate('OpenLP.MainWindow',
|
||||||
'OpenLP Data directory copy failed\n\n%s'
|
'OpenLP Data directory copy failed\n\n%s'
|
||||||
% unicode(why)),
|
).replace('%s', unicode(why)),
|
||||||
QtGui.QMessageBox.StandardButtons(
|
QtGui.QMessageBox.StandardButtons(
|
||||||
QtGui.QMessageBox.Ok))
|
QtGui.QMessageBox.Ok))
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import OpenLPToolbar, Receiver, translate
|
from openlp.core.lib import OpenLPToolbar, Receiver, translate
|
||||||
|
@ -43,7 +44,7 @@ log = logging.getLogger(__name__)
|
||||||
class MediaController(object):
|
class MediaController(object):
|
||||||
"""
|
"""
|
||||||
The implementation of the Media Controller. The Media Controller adds an own
|
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):
|
def __init__(self, parent):
|
||||||
|
@ -105,8 +106,12 @@ class MediaController(object):
|
||||||
AppLocation.get_directory(AppLocation.AppDir),
|
AppLocation.get_directory(AppLocation.AppDir),
|
||||||
u'core', u'ui', u'media')
|
u'core', u'ui', u'media')
|
||||||
for filename in os.listdir(controller_dir):
|
for filename in os.listdir(controller_dir):
|
||||||
if filename.endswith(u'player.py') and not \
|
# TODO vlc backend is not yet working on Mac OS X.
|
||||||
filename == 'media_player.py':
|
# 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)
|
path = os.path.join(controller_dir, filename)
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
modulename = u'openlp.core.ui.media.' + \
|
modulename = u'openlp.core.ui.media.' + \
|
||||||
|
@ -114,7 +119,9 @@ class MediaController(object):
|
||||||
log.debug(u'Importing controller %s', modulename)
|
log.debug(u'Importing controller %s', modulename)
|
||||||
try:
|
try:
|
||||||
__import__(modulename, globals(), locals(), [])
|
__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',
|
log.warn(u'Failed to import %s on path %s',
|
||||||
modulename, path)
|
modulename, path)
|
||||||
controller_classes = MediaPlayer.__subclasses__()
|
controller_classes = MediaPlayer.__subclasses__()
|
||||||
|
@ -287,7 +294,7 @@ class MediaController(object):
|
||||||
"""
|
"""
|
||||||
player.resize(display)
|
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
|
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:
|
if controller.isLive and not controller.media_info.is_background:
|
||||||
display.frame.evaluateJavaScript(u'show_video( \
|
display.frame.evaluateJavaScript(u'show_video( \
|
||||||
"setBackBoard", null, null, null,"visible");')
|
"setBackBoard", null, null, null,"visible");')
|
||||||
# now start playing
|
# now start playing - Preview is autoplay!
|
||||||
if controller.isLive and \
|
autoplay = False
|
||||||
(Settings().value(u'general/auto unblank',
|
# Preview requested
|
||||||
QtCore.QVariant(False)).toBool() or \
|
if not controller.isLive:
|
||||||
controller.media_info.is_background) or 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]):
|
if not self.video_play([controller]):
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||||
|
|
|
@ -48,7 +48,48 @@ import sys
|
||||||
from inspect import getargspec
|
from inspect import getargspec
|
||||||
|
|
||||||
__version__ = "N/A"
|
__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
|
# Internal guard to prevent internal classes to be directly
|
||||||
# instanciated.
|
# instanciated.
|
||||||
|
@ -220,7 +261,7 @@ def string_result(result, func, arguments):
|
||||||
"""
|
"""
|
||||||
if result:
|
if result:
|
||||||
# make a python string copy
|
# make a python string copy
|
||||||
s = ctypes.string_at(result)
|
s = bytes_to_str(ctypes.string_at(result))
|
||||||
# free original string ptr
|
# free original string ptr
|
||||||
libvlc_free(result)
|
libvlc_free(result)
|
||||||
return s
|
return s
|
||||||
|
@ -241,16 +282,32 @@ class FILE(ctypes.Structure):
|
||||||
pass
|
pass
|
||||||
FILE_ptr = ctypes.POINTER(FILE)
|
FILE_ptr = ctypes.POINTER(FILE)
|
||||||
|
|
||||||
PyFile_FromFile = ctypes.pythonapi.PyFile_FromFile
|
if PYTHON3:
|
||||||
PyFile_FromFile.restype = ctypes.py_object
|
PyFile_FromFd = ctypes.pythonapi.PyFile_FromFd
|
||||||
PyFile_FromFile.argtypes = [FILE_ptr,
|
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_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.c_char_p,
|
ctypes.c_char_p,
|
||||||
ctypes.CFUNCTYPE(ctypes.c_int, FILE_ptr)]
|
ctypes.CFUNCTYPE(ctypes.c_int, FILE_ptr)]
|
||||||
|
|
||||||
PyFile_AsFile = ctypes.pythonapi.PyFile_AsFile
|
PyFile_AsFile = ctypes.pythonapi.PyFile_AsFile
|
||||||
PyFile_AsFile.restype = FILE_ptr
|
PyFile_AsFile.restype = FILE_ptr
|
||||||
PyFile_AsFile.argtypes = [ctypes.py_object]
|
PyFile_AsFile.argtypes = [ctypes.py_object]
|
||||||
|
|
||||||
# Generated enum types #
|
# Generated enum types #
|
||||||
|
|
||||||
|
@ -1155,6 +1212,8 @@ class Instance(_Ctype):
|
||||||
# no parameters passed, for win32 and MacOS,
|
# no parameters passed, for win32 and MacOS,
|
||||||
# specify the plugin_path if detected earlier
|
# specify the plugin_path if detected earlier
|
||||||
args = ['vlc', '--plugin-path=' + plugin_path]
|
args = ['vlc', '--plugin-path=' + plugin_path]
|
||||||
|
if PYTHON3:
|
||||||
|
args = [ str_to_bytes(a) for a in args ]
|
||||||
return libvlc_new(len(args), args)
|
return libvlc_new(len(args), args)
|
||||||
|
|
||||||
def media_player_new(self, uri=None):
|
def media_player_new(self, uri=None):
|
||||||
|
@ -1195,12 +1254,12 @@ class Instance(_Ctype):
|
||||||
"""
|
"""
|
||||||
if ':' in mrl and mrl.index(':') > 1:
|
if ':' in mrl and mrl.index(':') > 1:
|
||||||
# Assume it is a URL
|
# Assume it is a URL
|
||||||
m = libvlc_media_new_location(self, mrl)
|
m = libvlc_media_new_location(self, str_to_bytes(mrl))
|
||||||
else:
|
else:
|
||||||
# Else it should be a local path.
|
# 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:
|
for o in options:
|
||||||
libvlc_media_add_option(m, o)
|
libvlc_media_add_option(m, str_to_bytes(o))
|
||||||
m._instance = self
|
m._instance = self
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
@ -1664,6 +1723,9 @@ class LogIterator(_Ctype):
|
||||||
return i.contents
|
return i.contents
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
|
def __next__(self):
|
||||||
|
return self.next()
|
||||||
|
|
||||||
|
|
||||||
def free(self):
|
def free(self):
|
||||||
'''Frees memory allocated by L{log_get_iterator}().
|
'''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)
|
ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p)
|
||||||
return f(fmt, ap)
|
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):
|
def libvlc_new(argc, argv):
|
||||||
'''Create and initialize a libvlc instance.
|
'''Create and initialize a libvlc instance.
|
||||||
This functions accept a list of "command line" arguments similar to the
|
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)
|
return f(p_instance)
|
||||||
|
|
||||||
|
|
||||||
# 2 function(s) blacklisted:
|
# 3 function(s) blacklisted:
|
||||||
|
# libvlc_printerr
|
||||||
# libvlc_set_exit_handler
|
# libvlc_set_exit_handler
|
||||||
# libvlc_video_set_callbacks
|
# libvlc_video_set_callbacks
|
||||||
|
|
||||||
# 18 function(s) not wrapped as methods:
|
# 17 function(s) not wrapped as methods:
|
||||||
# libvlc_audio_output_list_release
|
# libvlc_audio_output_list_release
|
||||||
# libvlc_clearerr
|
# libvlc_clearerr
|
||||||
# libvlc_clock
|
# libvlc_clock
|
||||||
|
@ -5847,7 +5898,6 @@ def libvlc_vlm_get_event_manager(p_instance):
|
||||||
# libvlc_log_unsubscribe
|
# libvlc_log_unsubscribe
|
||||||
# libvlc_module_description_list_release
|
# libvlc_module_description_list_release
|
||||||
# libvlc_new
|
# libvlc_new
|
||||||
# libvlc_printerr
|
|
||||||
# libvlc_track_description_list_release
|
# libvlc_track_description_list_release
|
||||||
# libvlc_track_description_release
|
# libvlc_track_description_release
|
||||||
# libvlc_vprinterr
|
# libvlc_vprinterr
|
||||||
|
@ -5908,7 +5958,7 @@ def libvlc_hex_version():
|
||||||
"""Return the libvlc version in hex or 0 if unavailable.
|
"""Return the libvlc version in hex or 0 if unavailable.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return _dot2int(libvlc_get_version().split()[0])
|
return _dot2int(bytes_to_str(libvlc_get_version()).split()[0])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
@ -5957,8 +6007,8 @@ if __name__ == '__main__':
|
||||||
"""Print libvlc version"""
|
"""Print libvlc version"""
|
||||||
try:
|
try:
|
||||||
print('Build date: %s (%#x)' % (build_date, hex_version()))
|
print('Build date: %s (%#x)' % (build_date, hex_version()))
|
||||||
print('LibVLC version: %s (%#x)' % (libvlc_get_version(), libvlc_hex_version()))
|
print('LibVLC version: %s (%#x)' % (bytes_to_str(libvlc_get_version()), libvlc_hex_version()))
|
||||||
print('LibVLC compiler: %s' % libvlc_get_compiler())
|
print('LibVLC compiler: %s' % bytes_to_str(libvlc_get_compiler()))
|
||||||
if plugin_path:
|
if plugin_path:
|
||||||
print('Plugin path: %s' % plugin_path)
|
print('Plugin path: %s' % plugin_path)
|
||||||
except:
|
except:
|
||||||
|
@ -5997,7 +6047,7 @@ if __name__ == '__main__':
|
||||||
player.video_set_marquee_int(VideoMarqueeOption.Refresh, 1000) # millisec (or sec?)
|
player.video_set_marquee_int(VideoMarqueeOption.Refresh, 1000) # millisec (or sec?)
|
||||||
##t = '$L / $D or $P at $T'
|
##t = '$L / $D or $P at $T'
|
||||||
t = '%Y-%m-%d %H:%M:%S'
|
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
|
# Some event manager examples. Note, the callback can be any Python
|
||||||
# callable and does not need to be decorated. Optionally, specify
|
# callable and does not need to be decorated. Optionally, specify
|
||||||
|
@ -6017,7 +6067,7 @@ if __name__ == '__main__':
|
||||||
print_version()
|
print_version()
|
||||||
media = player.get_media()
|
media = player.get_media()
|
||||||
print('State: %s' % player.get_state())
|
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('Track: %s/%s' % (player.video_get_track(), player.video_get_track_count()))
|
||||||
print('Current time: %s/%s' % (player.get_time(), media.get_duration()))
|
print('Current time: %s/%s' % (player.get_time(), media.get_duration()))
|
||||||
print('Position: %s' % player.get_position())
|
print('Position: %s' % player.get_position())
|
||||||
|
@ -6078,7 +6128,7 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
print('Press q to quit, ? to get help.%s' % os.linesep)
|
print('Press q to quit, ? to get help.%s' % os.linesep)
|
||||||
while True:
|
while True:
|
||||||
k = getch().decode('utf8') # Python 3+
|
k = getch()
|
||||||
print('> %s' % k)
|
print('> %s' % k)
|
||||||
if k in keybindings:
|
if k in keybindings:
|
||||||
keybindings[k]()
|
keybindings[k]()
|
||||||
|
|
|
@ -63,36 +63,32 @@ if VLC_AVAILABLE:
|
||||||
VLC_AVAILABLE = False
|
VLC_AVAILABLE = False
|
||||||
log.debug(u'VLC could not be loaded: %s' % version)
|
log.debug(u'VLC could not be loaded: %s' % version)
|
||||||
|
|
||||||
AUDIO_EXT = [
|
AUDIO_EXT = [u'*.mp3', u'*.wav', u'*.wma', u'*.ogg']
|
||||||
u'*.mp3'
|
|
||||||
, u'*.wav'
|
|
||||||
, u'*.ogg'
|
|
||||||
]
|
|
||||||
|
|
||||||
VIDEO_EXT = [
|
VIDEO_EXT = [
|
||||||
u'*.3gp'
|
u'*.3gp',
|
||||||
, u'*.asf', u'*.wmv'
|
u'*.asf', u'*.wmv',
|
||||||
, u'*.au'
|
u'*.au',
|
||||||
, u'*.avi'
|
u'*.avi',
|
||||||
, u'*.flv'
|
u'*.flv',
|
||||||
, u'*.mov'
|
u'*.mov',
|
||||||
, u'*.mp4'
|
u'*.mp4',
|
||||||
, u'*.ogm'
|
u'*.ogm', u'*.ogv',
|
||||||
, u'*.mkv', u'*.mka'
|
u'*.mkv', u'*.mka',
|
||||||
, u'*.ts', u'*.mpg'
|
u'*.ts', u'*.mpg',
|
||||||
, u'*.mpg', u'*.mp2'
|
u'*.mpg', u'*.mp2',
|
||||||
, u'*.nsc'
|
u'*.nsc',
|
||||||
, u'*.nsv'
|
u'*.nsv',
|
||||||
, u'*.nut'
|
u'*.nut',
|
||||||
, u'*.ra', u'*.ram', u'*.rm', u'*.rv' ,u'*.rmbv'
|
u'*.ra', u'*.ram', u'*.rm', u'*.rv' ,u'*.rmbv',
|
||||||
, u'*.a52', u'*.dts', u'*.aac', u'*.flac' ,u'*.dv', u'*.vid'
|
u'*.a52', u'*.dts', u'*.aac', u'*.flac' ,u'*.dv', u'*.vid',
|
||||||
, u'*.tta', u'*.tac'
|
u'*.tta', u'*.tac',
|
||||||
, u'*.ty'
|
u'*.ty',
|
||||||
, u'*.dts'
|
u'*.dts',
|
||||||
, u'*.xa'
|
u'*.xa',
|
||||||
, u'*.iso'
|
u'*.iso',
|
||||||
, u'*.vob'
|
u'*.vob'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class VlcPlayer(MediaPlayer):
|
class VlcPlayer(MediaPlayer):
|
||||||
|
|
|
@ -47,7 +47,8 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
||||||
create_widget_action, find_and_set_in_combo_box
|
create_widget_action, find_and_set_in_combo_box
|
||||||
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
|
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
|
||||||
from openlp.core.ui.printserviceform import PrintServiceForm
|
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
|
from openlp.core.utils.actions import ActionList, CategoryOrder
|
||||||
|
|
||||||
class ServiceManagerList(QtGui.QTreeWidget):
|
class ServiceManagerList(QtGui.QTreeWidget):
|
||||||
|
@ -379,6 +380,12 @@ class ServiceManager(QtGui.QWidget):
|
||||||
QtCore.QVariant(u'False')).toBool()
|
QtCore.QVariant(u'False')).toBool()
|
||||||
|
|
||||||
def supportedSuffixes(self, suffix):
|
def supportedSuffixes(self, suffix):
|
||||||
|
"""
|
||||||
|
Adds Suffixes supported to the master list. Called from Plugins.
|
||||||
|
|
||||||
|
``suffix``
|
||||||
|
New Suffix to be supported
|
||||||
|
"""
|
||||||
self.suffixes.append(suffix)
|
self.suffixes.append(suffix)
|
||||||
|
|
||||||
def onNewServiceClicked(self):
|
def onNewServiceClicked(self):
|
||||||
|
@ -513,7 +520,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
'Service File Missing'))
|
'Service File Missing'))
|
||||||
message = unicode(translate('OpenLP.ServiceManager',
|
message = unicode(translate('OpenLP.ServiceManager',
|
||||||
'File missing from service\n\n %s \n\n'
|
'File missing from service\n\n %s \n\n'
|
||||||
'Continue saving?' % path_from ))
|
'Continue saving?')) % path_from
|
||||||
answer = QtGui.QMessageBox.critical(self, title,
|
answer = QtGui.QMessageBox.critical(self, title,
|
||||||
message,
|
message,
|
||||||
QtGui.QMessageBox.StandardButtons(
|
QtGui.QMessageBox.StandardButtons(
|
||||||
|
@ -596,7 +603,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
service_day = Settings().value(
|
service_day = Settings().value(
|
||||||
u'advanced/default service day', 7).toInt()[0]
|
u'advanced/default service day', 7).toInt()[0]
|
||||||
if service_day == 7:
|
if service_day == 7:
|
||||||
time = datetime.now()
|
local_time = datetime.now()
|
||||||
else:
|
else:
|
||||||
service_hour = Settings().value(
|
service_hour = Settings().value(
|
||||||
u'advanced/default service hour', 11).toInt()[0]
|
u'advanced/default service hour', 11).toInt()[0]
|
||||||
|
@ -607,7 +614,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
if day_delta < 0:
|
if day_delta < 0:
|
||||||
day_delta += 7
|
day_delta += 7
|
||||||
time = now + timedelta(days=day_delta)
|
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(
|
default_pattern = unicode(Settings().value(
|
||||||
u'advanced/default service name',
|
u'advanced/default service name',
|
||||||
translate('OpenLP.AdvancedTab', 'Service %Y-%m-%d %H-%M',
|
translate('OpenLP.AdvancedTab', 'Service %Y-%m-%d %H-%M',
|
||||||
|
@ -615,7 +622,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
'/\\?*|<>\[\]":+\nSee http://docs.python.org/library/'
|
'/\\?*|<>\[\]":+\nSee http://docs.python.org/library/'
|
||||||
'datetime.html#strftime-strptime-behavior for more '
|
'datetime.html#strftime-strptime-behavior for more '
|
||||||
'information.')).toString())
|
'information.')).toString())
|
||||||
default_filename = time.strftime(default_pattern)
|
default_filename = format_time(default_pattern, local_time)
|
||||||
else:
|
else:
|
||||||
default_filename = u''
|
default_filename = u''
|
||||||
directory = unicode(SettingsManager.get_last_dir(
|
directory = unicode(SettingsManager.get_last_dir(
|
||||||
|
@ -795,6 +802,10 @@ class ServiceManager(QtGui.QWidget):
|
||||||
self.repaintServiceList(item, -1)
|
self.repaintServiceList(item, -1)
|
||||||
|
|
||||||
def onServiceItemEditForm(self):
|
def onServiceItemEditForm(self):
|
||||||
|
"""
|
||||||
|
Opens a dialog to edit the service item and update the service
|
||||||
|
display if changes are saved.
|
||||||
|
"""
|
||||||
item = self.findServiceItem()[0]
|
item = self.findServiceItem()[0]
|
||||||
self.serviceItemEditForm.setServiceItem(
|
self.serviceItemEditForm.setServiceItem(
|
||||||
self.serviceItems[item][u'service_item'])
|
self.serviceItems[item][u'service_item'])
|
||||||
|
@ -805,7 +816,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
def previewLive(self, message):
|
def previewLive(self, message):
|
||||||
"""
|
"""
|
||||||
Called by the SlideController to request a preview item be made live
|
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':')
|
uuid, row = message.split(u':')
|
||||||
for sitem in self.serviceItems:
|
for sitem in self.serviceItems:
|
||||||
|
@ -1082,12 +1093,12 @@ class ServiceManager(QtGui.QWidget):
|
||||||
"""
|
"""
|
||||||
if serviceItem.is_command():
|
if serviceItem.is_command():
|
||||||
type = serviceItem._raw_frames[0][u'title'].split(u'.')[-1]
|
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
|
serviceItem.is_valid = False
|
||||||
|
|
||||||
def cleanUp(self):
|
def cleanUp(self):
|
||||||
"""
|
"""
|
||||||
Empties the servicePath of temporary files.
|
Empties the servicePath of temporary files on system exit.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Cleaning up servicePath')
|
log.debug(u'Cleaning up servicePath')
|
||||||
for file in os.listdir(self.servicePath):
|
for file in os.listdir(self.servicePath):
|
||||||
|
|
|
@ -286,19 +286,20 @@ class SlideController(Controller):
|
||||||
text=translate('OpenLP.SlideController', 'Pause Audio'),
|
text=translate('OpenLP.SlideController', 'Pause Audio'),
|
||||||
tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
|
tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
|
||||||
checked=False, visible=False, category=self.category,
|
checked=False, visible=False, category=self.category,
|
||||||
triggers=self.onAudioPauseClicked)
|
context=QtCore.Qt.WindowShortcut,
|
||||||
|
shortcuts=[], triggers=self.onAudioPauseClicked)
|
||||||
self.audioMenu = QtGui.QMenu(
|
self.audioMenu = QtGui.QMenu(
|
||||||
translate('OpenLP.SlideController', 'Background Audio'), self)
|
translate('OpenLP.SlideController', 'Background Audio'), self.toolbar)
|
||||||
self.audioPauseItem.setMenu(self.audioMenu)
|
self.audioPauseItem.setMenu(self.audioMenu)
|
||||||
self.audioPauseItem.setParent(self)
|
self.audioPauseItem.setParent(self.toolbar)
|
||||||
self.toolbar.widgetForAction(self.audioPauseItem).setPopupMode(
|
self.toolbar.widgetForAction(self.audioPauseItem).setPopupMode(
|
||||||
QtGui.QToolButton.MenuButtonPopup)
|
QtGui.QToolButton.MenuButtonPopup)
|
||||||
self.nextTrackItem = create_action(self, u'nextTrackItem',
|
self.nextTrackItem = create_action(self, u'nextTrackItem',
|
||||||
text=UiStrings().NextTrack,
|
text=UiStrings().NextTrack,
|
||||||
icon=u':/slides/media_playback_next.png', tooltip=translate(
|
icon=u':/slides/media_playback_next.png', tooltip=translate(
|
||||||
'OpenLP.SlideController', 'Go to next audio track.'),
|
'OpenLP.SlideController', 'Go to next audio track.'),
|
||||||
category=self.category, context=QtCore.Qt.WindowShortcut,
|
category=self.category,
|
||||||
triggers=self.onNextTrackClicked)
|
shortcuts=[], triggers=self.onNextTrackClicked)
|
||||||
self.audioMenu.addAction(self.nextTrackItem)
|
self.audioMenu.addAction(self.nextTrackItem)
|
||||||
self.trackMenu = self.audioMenu.addMenu(
|
self.trackMenu = self.audioMenu.addMenu(
|
||||||
translate('OpenLP.SlideController', 'Tracks'))
|
translate('OpenLP.SlideController', 'Tracks'))
|
||||||
|
@ -1346,7 +1347,7 @@ class SlideController(Controller):
|
||||||
"""
|
"""
|
||||||
log.debug(u'SlideController onMediaStart')
|
log.debug(u'SlideController onMediaStart')
|
||||||
file = os.path.join(item.get_frame_path(), item.get_frame_title())
|
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:
|
if not self.isLive or self.mediaController.withLivePreview:
|
||||||
self.previewDisplay.show()
|
self.previewDisplay.show()
|
||||||
self.slidePreview.hide()
|
self.slidePreview.hide()
|
||||||
|
|
|
@ -157,7 +157,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
u'outlineColorButton', self.outlineColorButton)
|
u'outlineColorButton', self.outlineColorButton)
|
||||||
self.mainAreaPage.registerField(
|
self.mainAreaPage.registerField(
|
||||||
u'outlineSizeSpinBox', self.outlineSizeSpinBox)
|
u'outlineSizeSpinBox', self.outlineSizeSpinBox)
|
||||||
self.mainAreaPage.registerField(u'shadowCheckBox', self.shadowCheckBox)
|
self.mainAreaPage.registerField(
|
||||||
|
u'shadowCheckBox', self.shadowCheckBox)
|
||||||
self.mainAreaPage.registerField(
|
self.mainAreaPage.registerField(
|
||||||
u'mainBoldCheckBox', self.mainBoldCheckBox)
|
u'mainBoldCheckBox', self.mainBoldCheckBox)
|
||||||
self.mainAreaPage.registerField(
|
self.mainAreaPage.registerField(
|
||||||
|
@ -168,8 +169,10 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
u'shadowSizeSpinBox', self.shadowSizeSpinBox)
|
u'shadowSizeSpinBox', self.shadowSizeSpinBox)
|
||||||
self.mainAreaPage.registerField(
|
self.mainAreaPage.registerField(
|
||||||
u'footerSizeSpinBox', self.footerSizeSpinBox)
|
u'footerSizeSpinBox', self.footerSizeSpinBox)
|
||||||
self.areaPositionPage.registerField(u'mainPositionX', self.mainXSpinBox)
|
self.areaPositionPage.registerField(
|
||||||
self.areaPositionPage.registerField(u'mainPositionY', self.mainYSpinBox)
|
u'mainPositionX', self.mainXSpinBox)
|
||||||
|
self.areaPositionPage.registerField(
|
||||||
|
u'mainPositionY', self.mainYSpinBox)
|
||||||
self.areaPositionPage.registerField(
|
self.areaPositionPage.registerField(
|
||||||
u'mainPositionWidth', self.mainWidthSpinBox)
|
u'mainPositionWidth', self.mainWidthSpinBox)
|
||||||
self.areaPositionPage.registerField(
|
self.areaPositionPage.registerField(
|
||||||
|
@ -202,7 +205,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
"""
|
"""
|
||||||
Updates the lines on a page on the wizard
|
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))
|
'(approximately %d lines per slide)')) % int(lines))
|
||||||
|
|
||||||
def resizeEvent(self, event=None):
|
def resizeEvent(self, event=None):
|
||||||
|
@ -224,6 +228,19 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
self.previewBoxLabel.setFixedSize(pixmapWidth + 2 * frameWidth,
|
self.previewBoxLabel.setFixedSize(pixmapWidth + 2 * frameWidth,
|
||||||
pixmapHeight + 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):
|
def onCurrentIdChanged(self, pageId):
|
||||||
"""
|
"""
|
||||||
Detects Page changes and updates as appropriate.
|
Detects Page changes and updates as appropriate.
|
||||||
|
@ -521,7 +538,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||||
images_filter = u'%s;;%s (*.*) (*)' % (
|
images_filter = u'%s;;%s (*.*) (*)' % (
|
||||||
images_filter, UiStrings().AllFiles)
|
images_filter, UiStrings().AllFiles)
|
||||||
filename = QtGui.QFileDialog.getOpenFileName(self,
|
filename = QtGui.QFileDialog.getOpenFileName(self,
|
||||||
translate('OpenLP.ThemeForm', 'Select Image'), u'',
|
translate('OpenLP.ThemeWizard', 'Select Image'), u'',
|
||||||
images_filter)
|
images_filter)
|
||||||
if filename:
|
if filename:
|
||||||
self.theme.background_filename = unicode(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())
|
self.theme.theme_name = unicode(self.field(u'name').toString())
|
||||||
if not self.theme.theme_name:
|
if not self.theme.theme_name:
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
translate('OpenLP.ThemeForm', 'Theme Name Missing'),
|
translate('OpenLP.ThemeWizard', 'Theme Name Missing'),
|
||||||
translate('OpenLP.ThemeForm',
|
translate('OpenLP.ThemeWizard',
|
||||||
'There is no name for this theme. Please enter one.'))
|
'There is no name for this theme. Please enter one.'))
|
||||||
return
|
return
|
||||||
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None':
|
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None':
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
translate('OpenLP.ThemeForm', 'Theme Name Invalid'),
|
translate('OpenLP.ThemeWizard', 'Theme Name Invalid'),
|
||||||
translate('OpenLP.ThemeForm',
|
translate('OpenLP.ThemeWizard',
|
||||||
'Invalid theme name. Please enter one.'))
|
'Invalid theme name. Please enter one.'))
|
||||||
return
|
return
|
||||||
saveFrom = None
|
saveFrom = None
|
||||||
|
|
|
@ -257,6 +257,7 @@ class ThemeManager(QtGui.QWidget):
|
||||||
theme.set_default_header_footer()
|
theme.set_default_header_footer()
|
||||||
self.themeForm.theme = theme
|
self.themeForm.theme = theme
|
||||||
self.themeForm.exec_()
|
self.themeForm.exec_()
|
||||||
|
self.loadThemes()
|
||||||
|
|
||||||
def onRenameTheme(self):
|
def onRenameTheme(self):
|
||||||
"""
|
"""
|
||||||
|
@ -281,7 +282,6 @@ class ThemeManager(QtGui.QWidget):
|
||||||
for plugin in self.mainwindow.pluginManager.plugins:
|
for plugin in self.mainwindow.pluginManager.plugins:
|
||||||
if plugin.usesTheme(old_theme_name):
|
if plugin.usesTheme(old_theme_name):
|
||||||
plugin.renameTheme(old_theme_name, new_theme_name)
|
plugin.renameTheme(old_theme_name, new_theme_name)
|
||||||
self.loadThemes()
|
|
||||||
self.mainwindow.renderer.update_theme(
|
self.mainwindow.renderer.update_theme(
|
||||||
new_theme_name, old_theme_name)
|
new_theme_name, old_theme_name)
|
||||||
|
|
||||||
|
@ -314,6 +314,7 @@ class ThemeManager(QtGui.QWidget):
|
||||||
theme_data.theme_name = new_theme_name
|
theme_data.theme_name = new_theme_name
|
||||||
theme_data.extend_image_filename(self.path)
|
theme_data.extend_image_filename(self.path)
|
||||||
self.saveTheme(theme_data, save_from, save_to)
|
self.saveTheme(theme_data, save_from, save_to)
|
||||||
|
self.loadThemes()
|
||||||
|
|
||||||
def onEditTheme(self):
|
def onEditTheme(self):
|
||||||
"""
|
"""
|
||||||
|
@ -331,6 +332,7 @@ class ThemeManager(QtGui.QWidget):
|
||||||
self.themeForm.exec_(True)
|
self.themeForm.exec_(True)
|
||||||
self.oldBackgroundImage = None
|
self.oldBackgroundImage = None
|
||||||
self.mainwindow.renderer.update_theme(theme.theme_name)
|
self.mainwindow.renderer.update_theme(theme.theme_name)
|
||||||
|
self.loadThemes()
|
||||||
|
|
||||||
def onDeleteTheme(self):
|
def onDeleteTheme(self):
|
||||||
"""
|
"""
|
||||||
|
@ -345,10 +347,10 @@ class ThemeManager(QtGui.QWidget):
|
||||||
row = self.themeListWidget.row(item)
|
row = self.themeListWidget.row(item)
|
||||||
self.themeListWidget.takeItem(row)
|
self.themeListWidget.takeItem(row)
|
||||||
self.deleteTheme(theme)
|
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
|
# As we do not reload the themes, push out the change. Reload the
|
||||||
# list as the internal lists and events need to be triggered.
|
# list as the internal lists and events need to be triggered.
|
||||||
self._pushThemes()
|
self._pushThemes()
|
||||||
self.mainwindow.renderer.update_theme(theme, only_delete=True)
|
|
||||||
|
|
||||||
def deleteTheme(self, theme):
|
def deleteTheme(self, theme):
|
||||||
"""
|
"""
|
||||||
|
@ -516,7 +518,7 @@ class ThemeManager(QtGui.QWidget):
|
||||||
translate('OpenLP.ThemeManager', 'Theme Already Exists'),
|
translate('OpenLP.ThemeManager', 'Theme Already Exists'),
|
||||||
translate('OpenLP.ThemeManager',
|
translate('OpenLP.ThemeManager',
|
||||||
'Theme %s already exists. Do you want to replace it?'
|
'Theme %s already exists. Do you want to replace it?'
|
||||||
% theme_name),
|
).replace('%s', theme_name),
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
|
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
|
||||||
QtGui.QMessageBox.No),
|
QtGui.QMessageBox.No),
|
||||||
QtGui.QMessageBox.No)
|
QtGui.QMessageBox.No)
|
||||||
|
@ -672,7 +674,6 @@ class ThemeManager(QtGui.QWidget):
|
||||||
theme.background_filename,
|
theme.background_filename,
|
||||||
ImageSource.Theme, QtGui.QColor(theme.background_border_color))
|
ImageSource.Theme, QtGui.QColor(theme.background_border_color))
|
||||||
self.mainwindow.imageManager.processUpdates()
|
self.mainwindow.imageManager.processUpdates()
|
||||||
self.loadThemes()
|
|
||||||
|
|
||||||
def _writeTheme(self, theme, image_from, image_to):
|
def _writeTheme(self, theme, image_from, image_to):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -136,7 +136,7 @@ class AppLocation(object):
|
||||||
else:
|
else:
|
||||||
path = AppLocation.get_directory(AppLocation.DataDir)
|
path = AppLocation.get_directory(AppLocation.DataDir)
|
||||||
check_directory_exists(path)
|
check_directory_exists(path)
|
||||||
return path
|
return os.path.normpath(path)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_section_data_path(section):
|
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;' \
|
return resolver.resolve(u'uno:socket,host=localhost,port=2002;' \
|
||||||
+ u'urp;StarOffice.ComponentContext')
|
+ 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 languagemanager import LanguageManager
|
||||||
from actions import ActionList
|
from actions import ActionList
|
||||||
|
|
||||||
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
||||||
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
||||||
u'ActionList', u'get_web_page', u'get_uno_command', u'get_uno_instance',
|
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']
|
||||||
|
|
|
@ -124,6 +124,8 @@ class BGExtract(object):
|
||||||
self._remove_elements(tag, 'div', 'footnotes')
|
self._remove_elements(tag, 'div', 'footnotes')
|
||||||
self._remove_elements(tag, 'div', 'crossrefs')
|
self._remove_elements(tag, 'div', 'crossrefs')
|
||||||
self._remove_elements(tag, 'h3')
|
self._remove_elements(tag, 'h3')
|
||||||
|
self._remove_elements(tag, 'h4')
|
||||||
|
self._remove_elements(tag, 'h5')
|
||||||
|
|
||||||
def _extract_verses(self, tags):
|
def _extract_verses(self, tags):
|
||||||
"""
|
"""
|
||||||
|
@ -155,12 +157,59 @@ class BGExtract(object):
|
||||||
text = text.replace(old, new)
|
text = text.replace(old, new)
|
||||||
text = u' '.join(text.split())
|
text = u' '.join(text.split())
|
||||||
if verse and text:
|
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 = {}
|
verse_list = {}
|
||||||
for verse, text in verses[::-1]:
|
for verse, text in verses[::-1]:
|
||||||
verse_list[verse] = text
|
verse_list[verse] = text
|
||||||
return verse_list
|
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):
|
def get_bible_chapter(self, version, book_name, chapter):
|
||||||
"""
|
"""
|
||||||
Access and decode Bibles via the BibleGateway website.
|
Access and decode Bibles via the BibleGateway website.
|
||||||
|
@ -189,7 +238,13 @@ class BGExtract(object):
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
div = soup.find('div', 'result-text-style-normal')
|
div = soup.find('div', 'result-text-style-normal')
|
||||||
self._clean_soup(div)
|
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:
|
if not verse_list:
|
||||||
log.debug(u'No content found in the BibleGateway response.')
|
log.debug(u'No content found in the BibleGateway response.')
|
||||||
send_error_message(u'parse')
|
send_error_message(u'parse')
|
||||||
|
|
|
@ -208,24 +208,16 @@ class BibleManager(object):
|
||||||
|
|
||||||
def delete_bible(self, name):
|
def delete_bible(self, name):
|
||||||
"""
|
"""
|
||||||
Delete a bible completly.
|
Delete a bible completely.
|
||||||
|
|
||||||
``name``
|
``name``
|
||||||
The name of the bible.
|
The name of the bible.
|
||||||
"""
|
"""
|
||||||
log.debug(u'BibleManager.delete_bible("%s")', name)
|
log.debug(u'BibleManager.delete_bible("%s")', name)
|
||||||
files = SettingsManager.get_files(self.settingsSection,
|
bible = self.db_cache[name]
|
||||||
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()
|
bible.session.close()
|
||||||
if delete_file(os.path.join(self.path, filename)):
|
bible.session = None
|
||||||
return True
|
return delete_file(os.path.join(bible.path, bible.file))
|
||||||
return False
|
|
||||||
|
|
||||||
def get_bibles(self):
|
def get_bibles(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -27,9 +27,10 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from lxml import objectify
|
from lxml import etree, objectify
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
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
|
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -113,8 +114,15 @@ class OpenSongBible(BibleDB):
|
||||||
(db_book.name, int(chapter.attrib[u'n'].split()[-1])))
|
(db_book.name, int(chapter.attrib[u'n'].split()[-1])))
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
Receiver.send_message(u'openlp_process_events')
|
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):
|
except (IOError, AttributeError):
|
||||||
log.exception(u'Loading bible from OpenSong file failed')
|
log.exception(u'Loading Bible from OpenSong file failed')
|
||||||
success = False
|
success = False
|
||||||
finally:
|
finally:
|
||||||
if file:
|
if file:
|
||||||
|
|
|
@ -49,6 +49,8 @@ class Ui_CustomSlideEditDialog(object):
|
||||||
self.retranslateUi(customSlideEditDialog)
|
self.retranslateUi(customSlideEditDialog)
|
||||||
|
|
||||||
def retranslateUi(self, customSlideEditDialog):
|
def retranslateUi(self, customSlideEditDialog):
|
||||||
|
customSlideEditDialog.setWindowTitle(
|
||||||
|
translate('CustomPlugin.EditVerseForm', 'Edit Slide'))
|
||||||
self.splitButton.setText(UiStrings().Split)
|
self.splitButton.setText(UiStrings().Split)
|
||||||
self.splitButton.setToolTip(UiStrings().SplitToolTip)
|
self.splitButton.setToolTip(UiStrings().SplitToolTip)
|
||||||
self.insertButton.setText(
|
self.insertButton.setText(
|
||||||
|
|
|
@ -122,9 +122,9 @@ class RemoteTab(SettingsTab):
|
||||||
self.androidAppGroupBox.setTitle(
|
self.androidAppGroupBox.setTitle(
|
||||||
translate('RemotePlugin.RemoteTab', 'Android App'))
|
translate('RemotePlugin.RemoteTab', 'Android App'))
|
||||||
self.qrDescriptionLabel.setText(translate('RemotePlugin.RemoteTab',
|
self.qrDescriptionLabel.setText(translate('RemotePlugin.RemoteTab',
|
||||||
'Scan the QR code or click <a '
|
'Scan the QR code or click <a href="https://play.google.com/store/'
|
||||||
'href="https://market.android.com/details?id=org.openlp.android">'
|
'apps/details?id=org.openlp.android">download</a> to install the '
|
||||||
'download</a> to install the Android app from the Market.'))
|
'Android app from Google Play.'))
|
||||||
|
|
||||||
def setUrls(self):
|
def setUrls(self):
|
||||||
ipAddress = u'localhost'
|
ipAddress = u'localhost'
|
||||||
|
|
|
@ -528,9 +528,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
for row in self.findVerseSplit.split(verse_list):
|
for row in self.findVerseSplit.split(verse_list):
|
||||||
for match in row.split(u'---['):
|
for match in row.split(u'---['):
|
||||||
for count, parts in enumerate(match.split(u']---\n')):
|
for count, parts in enumerate(match.split(u']---\n')):
|
||||||
if len(parts) <= 1:
|
|
||||||
continue
|
|
||||||
if count == 0:
|
if count == 0:
|
||||||
|
if len(parts) == 0:
|
||||||
|
continue
|
||||||
# handling carefully user inputted versetags
|
# handling carefully user inputted versetags
|
||||||
separator = parts.find(u':')
|
separator = parts.find(u':')
|
||||||
if separator >= 0:
|
if separator >= 0:
|
||||||
|
|
|
@ -67,7 +67,7 @@ class Ui_EditVerseDialog(object):
|
||||||
self.verseTypeLayout.addStretch()
|
self.verseTypeLayout.addStretch()
|
||||||
self.dialogLayout.addLayout(self.verseTypeLayout)
|
self.dialogLayout.addLayout(self.verseTypeLayout)
|
||||||
self.buttonBox = create_button_box(editVerseDialog, u'buttonBox',
|
self.buttonBox = create_button_box(editVerseDialog, u'buttonBox',
|
||||||
[u'cancel', u'save'])
|
[u'cancel', u'ok'])
|
||||||
self.dialogLayout.addWidget(self.buttonBox)
|
self.dialogLayout.addWidget(self.buttonBox)
|
||||||
self.retranslateUi(editVerseDialog)
|
self.retranslateUi(editVerseDialog)
|
||||||
|
|
||||||
|
|
|
@ -185,22 +185,3 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
||||||
text = u'---[%s:1]---\n%s' % \
|
text = u'---[%s:1]---\n%s' % \
|
||||||
(VerseType.TranslatedNames[VerseType.Verse], text)
|
(VerseType.TranslatedNames[VerseType.Verse], text)
|
||||||
return 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)
|
|
||||||
|
|
|
@ -483,8 +483,11 @@ class FoilPresenter(object):
|
||||||
# Process verse order
|
# Process verse order
|
||||||
verse_order = []
|
verse_order = []
|
||||||
verse_strophenr = []
|
verse_strophenr = []
|
||||||
|
try:
|
||||||
for strophennummer in foilpresenterfolie.reihenfolge.strophennummer:
|
for strophennummer in foilpresenterfolie.reihenfolge.strophennummer:
|
||||||
verse_strophenr.append(strophennummer)
|
verse_strophenr.append(strophennummer)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
# Currently we do not support different "parts"!
|
# Currently we do not support different "parts"!
|
||||||
if u'0' in temp_verse_order:
|
if u'0' in temp_verse_order:
|
||||||
for vers in temp_verse_order_backup:
|
for vers in temp_verse_order_backup:
|
||||||
|
@ -538,12 +541,17 @@ class FoilPresenter(object):
|
||||||
``song``
|
``song``
|
||||||
The song object.
|
The song object.
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
for title_string in foilpresenterfolie.titel.titelstring:
|
for title_string in foilpresenterfolie.titel.titelstring:
|
||||||
if not song.title:
|
if not song.title:
|
||||||
song.title = self._child(title_string)
|
song.title = self._child(title_string)
|
||||||
song.alternate_title = u''
|
song.alternate_title = u''
|
||||||
else:
|
else:
|
||||||
song.alternate_title = self._child(title_string)
|
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):
|
def _process_topics(self, foilpresenterfolie, song):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -103,7 +103,7 @@ class PowerSongImport(SongImport):
|
||||||
self.logError(unicode(translate('SongsPlugin.PowerSongImport',
|
self.logError(unicode(translate('SongsPlugin.PowerSongImport',
|
||||||
'No songs to import.')),
|
'No songs to import.')),
|
||||||
unicode(translate('SongsPlugin.PowerSongImport',
|
unicode(translate('SongsPlugin.PowerSongImport',
|
||||||
'No %s files found.' % PS_string)))
|
'No %s files found.')) % PS_string)
|
||||||
return
|
return
|
||||||
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||||
for file in self.importSource:
|
for file in self.importSource:
|
||||||
|
@ -122,8 +122,8 @@ class PowerSongImport(SongImport):
|
||||||
parse_error = True
|
parse_error = True
|
||||||
self.logError(os.path.basename(file), unicode(
|
self.logError(os.path.basename(file), unicode(
|
||||||
translate('SongsPlugin.PowerSongImport',
|
translate('SongsPlugin.PowerSongImport',
|
||||||
'Invalid %s file. Unexpected byte value.'
|
'Invalid %s file. Unexpected byte value.'))
|
||||||
% PS_string)))
|
% PS_string)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if label == u'TITLE':
|
if label == u'TITLE':
|
||||||
|
@ -141,14 +141,14 @@ class PowerSongImport(SongImport):
|
||||||
if not self.title:
|
if not self.title:
|
||||||
self.logError(os.path.basename(file), unicode(
|
self.logError(os.path.basename(file), unicode(
|
||||||
translate('SongsPlugin.PowerSongImport',
|
translate('SongsPlugin.PowerSongImport',
|
||||||
'Invalid %s file. Missing "TITLE" header.' % PS_string)))
|
'Invalid %s file. Missing "TITLE" header.')) % PS_string)
|
||||||
continue
|
continue
|
||||||
# Check that file had COPYRIGHTLINE label
|
# Check that file had COPYRIGHTLINE label
|
||||||
if not found_copyright:
|
if not found_copyright:
|
||||||
self.logError(self.title, unicode(
|
self.logError(self.title, unicode(
|
||||||
translate('SongsPlugin.PowerSongImport',
|
translate('SongsPlugin.PowerSongImport',
|
||||||
'Invalid %s file. Missing "COPYRIGHTLINE" '
|
'Invalid %s file. Missing "COPYRIGHTLINE" '
|
||||||
'header.' % PS_string)))
|
'header.')) % PS_string)
|
||||||
continue
|
continue
|
||||||
# Check that file had at least one verse
|
# Check that file had at least one verse
|
||||||
if not self.verses:
|
if not self.verses:
|
||||||
|
|
|
@ -91,7 +91,7 @@ class ZionWorxImport(SongImport):
|
||||||
self.logError(unicode(translate('SongsPlugin.ZionWorxImport',
|
self.logError(unicode(translate('SongsPlugin.ZionWorxImport',
|
||||||
'Error reading CSV file.')),
|
'Error reading CSV file.')),
|
||||||
unicode(translate('SongsPlugin.ZionWorxImport',
|
unicode(translate('SongsPlugin.ZionWorxImport',
|
||||||
'Line %d: %s' % (songs_reader.line_num, e))))
|
'Line %d: %s')) % (songs_reader.line_num, e))
|
||||||
return
|
return
|
||||||
num_records = len(records)
|
num_records = len(records)
|
||||||
log.info(u'%s records found in CSV file' % num_records)
|
log.info(u'%s records found in CSV file' % num_records)
|
||||||
|
@ -111,7 +111,7 @@ class ZionWorxImport(SongImport):
|
||||||
self.logError(unicode(translate(
|
self.logError(unicode(translate(
|
||||||
'SongsPlugin.ZionWorxImport', 'Record %d' % index)),
|
'SongsPlugin.ZionWorxImport', 'Record %d' % index)),
|
||||||
unicode(translate('SongsPlugin.ZionWorxImport',
|
unicode(translate('SongsPlugin.ZionWorxImport',
|
||||||
'Decoding error: %s' % e)))
|
'Decoding error: %s')) % e)
|
||||||
continue
|
continue
|
||||||
except TypeError, e:
|
except TypeError, e:
|
||||||
self.logError(unicode(translate(
|
self.logError(unicode(translate(
|
||||||
|
@ -130,7 +130,7 @@ class ZionWorxImport(SongImport):
|
||||||
title = self.title
|
title = self.title
|
||||||
if not self.finish():
|
if not self.finish():
|
||||||
self.logError(unicode(translate(
|
self.logError(unicode(translate(
|
||||||
'SongsPlugin.ZionWorxImport', 'Record %d' % index))
|
'SongsPlugin.ZionWorxImport', 'Record %d')) % index
|
||||||
+ (u': "' + title + u'"' if title else u''))
|
+ (u': "' + title + u'"' if title else u''))
|
||||||
|
|
||||||
def _decode(self, str):
|
def _decode(self, str):
|
||||||
|
|
|
@ -147,6 +147,7 @@ class SongsPlugin(Plugin):
|
||||||
progressDialog = QtGui.QProgressDialog(
|
progressDialog = QtGui.QProgressDialog(
|
||||||
translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel,
|
translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel,
|
||||||
0, maxSongs, self.formParent)
|
0, maxSongs, self.formParent)
|
||||||
|
progressDialog.setWindowTitle(translate('SongsPlugin', 'Reindexing songs'))
|
||||||
progressDialog.setWindowModality(QtCore.Qt.WindowModal)
|
progressDialog.setWindowModality(QtCore.Qt.WindowModal)
|
||||||
songs = self.manager.get_all_objects(Song)
|
songs = self.manager.get_all_objects(Song)
|
||||||
for number, song in enumerate(songs):
|
for number, song in enumerate(songs):
|
||||||
|
@ -247,6 +248,7 @@ class SongsPlugin(Plugin):
|
||||||
return
|
return
|
||||||
progress = QtGui.QProgressDialog(self.formParent)
|
progress = QtGui.QProgressDialog(self.formParent)
|
||||||
progress.setWindowModality(QtCore.Qt.WindowModal)
|
progress.setWindowModality(QtCore.Qt.WindowModal)
|
||||||
|
progress.setWindowTitle(translate('OpenLP.Ui', 'Importing Songs'))
|
||||||
progress.setLabelText(translate('OpenLP.Ui', 'Starting import...'))
|
progress.setLabelText(translate('OpenLP.Ui', 'Starting import...'))
|
||||||
progress.setCancelButton(None)
|
progress.setCancelButton(None)
|
||||||
progress.setRange(0, len(song_dbs))
|
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
1397
resources/i18n/da.ts
1397
resources/i18n/da.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
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
1574
resources/i18n/fi.ts
1574
resources/i18n/fi.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
File diff suppressed because it is too large
Load Diff
1386
resources/i18n/it.ts
1386
resources/i18n/it.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
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
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
@ -116,7 +116,7 @@
|
||||||
<file>system_help_contents.png</file>
|
<file>system_help_contents.png</file>
|
||||||
<file>system_online_help.png</file>
|
<file>system_online_help.png</file>
|
||||||
<file>system_mediamanager.png</file>
|
<file>system_mediamanager.png</file>
|
||||||
<file>system_contribute.png</file>
|
<file>system_volunteer.png</file>
|
||||||
<file>system_servicemanager.png</file>
|
<file>system_servicemanager.png</file>
|
||||||
<file>system_thememanager.png</file>
|
<file>system_thememanager.png</file>
|
||||||
<file>system_exit.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 |
Loading…
Reference in New Issue