HEAD
|
@ -177,6 +177,38 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
self.shared_memory.create(1)
|
||||
return False
|
||||
|
||||
def is_data_path_missing(self):
|
||||
"""
|
||||
Check if the data folder path exists.
|
||||
"""
|
||||
data_folder_path = AppLocation.get_data_path()
|
||||
if not os.path.exists(data_folder_path):
|
||||
log.critical('Database was not found in: ' + data_folder_path)
|
||||
status = QtWidgets.QMessageBox.critical(None, translate('OpenLP', 'Data Directory Error'),
|
||||
translate('OpenLP', 'OpenLP data folder was not found in:\n\n{path}'
|
||||
'\n\nThe location of the data folder was '
|
||||
'previously changed from the OpenLP\'s '
|
||||
'default location. If the data was stored on '
|
||||
'removable device, that device needs to be '
|
||||
'made available.\n\nYou may reset the data '
|
||||
'location back to the default location, '
|
||||
'or you can try to make the current location '
|
||||
'available.\n\nDo you want to reset to the '
|
||||
'default data location? If not, OpenLP will be '
|
||||
'closed so you can try to fix the the problem.')
|
||||
.format(path=data_folder_path),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
if status == QtWidgets.QMessageBox.No:
|
||||
# If answer was "No", return "True", it will shutdown OpenLP in def main
|
||||
log.info('User requested termination')
|
||||
return True
|
||||
# If answer was "Yes", remove the custom data path thus resetting the default location.
|
||||
Settings().remove('advanced/data path')
|
||||
log.info('Database location has been reset to the default settings.')
|
||||
return False
|
||||
|
||||
def hook_exception(self, exc_type, value, traceback):
|
||||
"""
|
||||
Add an exception hook so that any uncaught exceptions are displayed in this window rather than somewhere where
|
||||
|
@ -208,8 +240,8 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
# If data_version is different from the current version ask if we should backup the data folder
|
||||
elif data_version != openlp_version:
|
||||
if QtWidgets.QMessageBox.question(None, translate('OpenLP', 'Backup'),
|
||||
translate('OpenLP', 'OpenLP has been upgraded, do you want to create '
|
||||
'a backup of OpenLPs data folder?'),
|
||||
translate('OpenLP', 'OpenLP has been upgraded, do you want to create\n'
|
||||
'a backup of the old data folder?'),
|
||||
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
|
||||
QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.Yes:
|
||||
# Create copy of data folder
|
||||
|
@ -223,8 +255,8 @@ class OpenLP(OpenLPMixin, QtWidgets.QApplication):
|
|||
translate('OpenLP', 'Backup of the data folder failed!'))
|
||||
return
|
||||
message = translate('OpenLP',
|
||||
'A backup of the data folder has been created'
|
||||
'at {text}').format(text=data_folder_backup_path)
|
||||
'A backup of the data folder has been created at:\n\n'
|
||||
'{text}').format(text=data_folder_backup_path)
|
||||
QtWidgets.QMessageBox.information(None, translate('OpenLP', 'Backup'), message)
|
||||
|
||||
# Update the version in the settings
|
||||
|
@ -368,9 +400,13 @@ def main(args=None):
|
|||
Registry.create()
|
||||
Registry().register('application', application)
|
||||
application.setApplicationVersion(get_application_version()['version'])
|
||||
# Instance check
|
||||
# Check if an instance of OpenLP is already running. Quit if there is a running instance and the user only wants one
|
||||
if application.is_already_running():
|
||||
sys.exit()
|
||||
# If the custom data path is missing and the user wants to restore the data path, quit OpenLP.
|
||||
if application.is_data_path_missing():
|
||||
application.shared_memory.detach()
|
||||
sys.exit()
|
||||
# Remove/convert obsolete settings.
|
||||
Settings().remove_obsolete_settings()
|
||||
# First time checks in settings
|
||||
|
|
|
@ -71,6 +71,12 @@ class OpenLPMixin(object):
|
|||
"""
|
||||
self.logger.info(message)
|
||||
|
||||
def log_warning(self, message):
|
||||
"""
|
||||
Common log warning handler
|
||||
"""
|
||||
self.logger.warning(message)
|
||||
|
||||
def log_error(self, message):
|
||||
"""
|
||||
Common log error handler which prints the calling path
|
||||
|
|
|
@ -214,7 +214,10 @@ class Settings(QtCore.QSettings):
|
|||
('media/players', 'media/players_temp', [(media_players_conv, None)]), # Convert phonon to system
|
||||
('media/players_temp', 'media/players', []), # Move temp setting from above to correct setting
|
||||
('advanced/default color', 'core/logo background color', []), # Default image renamed + moved to general > 2.4.
|
||||
('advanced/default image', '/core/logo file', []) # Default image renamed + moved to general after 2.4.
|
||||
('advanced/default image', 'core/logo file', []), # Default image renamed + moved to general after 2.4.
|
||||
('shortcuts/escapeItem', 'shortcuts/desktopScreenEnable', []), # Escape item was removed in 2.6.
|
||||
('shortcuts/offlineHelpItem', 'shortcuts/HelpItem', []), # Online and Offline help were combined in 2.6.
|
||||
('shortcuts/onlineHelpItem', 'shortcuts/HelpItem', []) # Online and Offline help were combined in 2.6.
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
|
@ -261,10 +264,10 @@ class Settings(QtCore.QSettings):
|
|||
'shortcuts/blankScreen': [QtGui.QKeySequence(QtCore.Qt.Key_Period)],
|
||||
'shortcuts/collapse': [QtGui.QKeySequence(QtCore.Qt.Key_Minus)],
|
||||
'shortcuts/desktopScreen': [QtGui.QKeySequence(QtCore.Qt.Key_D)],
|
||||
'shortcuts/desktopScreenEnable': [QtGui.QKeySequence(QtCore.Qt.Key_Escape)],
|
||||
'shortcuts/delete': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
|
||||
'shortcuts/down': [QtGui.QKeySequence(QtCore.Qt.Key_Down)],
|
||||
'shortcuts/editSong': [],
|
||||
'shortcuts/escapeItem': [QtGui.QKeySequence(QtCore.Qt.Key_Escape)],
|
||||
'shortcuts/expand': [QtGui.QKeySequence(QtCore.Qt.Key_Plus)],
|
||||
'shortcuts/exportThemeItem': [],
|
||||
'shortcuts/fileNewItem': [QtGui.QKeySequence(QtGui.QKeySequence.New)],
|
||||
|
@ -273,6 +276,7 @@ class Settings(QtCore.QSettings):
|
|||
'shortcuts/fileSaveItem': [QtGui.QKeySequence(QtGui.QKeySequence.Save)],
|
||||
'shortcuts/fileOpenItem': [QtGui.QKeySequence(QtGui.QKeySequence.Open)],
|
||||
'shortcuts/goLive': [],
|
||||
'shortcuts/HelpItem': [QtGui.QKeySequence(QtGui.QKeySequence.HelpContents)],
|
||||
'shortcuts/importThemeItem': [],
|
||||
'shortcuts/importBibleItem': [],
|
||||
'shortcuts/listViewBiblesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
|
||||
|
@ -333,8 +337,6 @@ class Settings(QtCore.QSettings):
|
|||
QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
|
||||
'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key_Right)],
|
||||
'shortcuts/newService': [],
|
||||
'shortcuts/offlineHelpItem': [QtGui.QKeySequence(QtGui.QKeySequence.HelpContents)],
|
||||
'shortcuts/onlineHelpItem': [QtGui.QKeySequence(QtGui.QKeySequence.HelpContents)],
|
||||
'shortcuts/openService': [],
|
||||
'shortcuts/saveService': [],
|
||||
'shortcuts/previousItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
|
||||
|
@ -379,6 +381,7 @@ class Settings(QtCore.QSettings):
|
|||
'shortcuts/themeScreen': [QtGui.QKeySequence(QtCore.Qt.Key_T)],
|
||||
'shortcuts/toolsReindexItem': [],
|
||||
'shortcuts/toolsFindDuplicates': [],
|
||||
'shortcuts/toolsSongListReport': [],
|
||||
'shortcuts/toolsAlertItem': [QtGui.QKeySequence(QtCore.Qt.Key_F7)],
|
||||
'shortcuts/toolsFirstTimeWizard': [],
|
||||
'shortcuts/toolsOpenDataFolder': [],
|
||||
|
|
|
@ -112,6 +112,7 @@ class UiStrings(object):
|
|||
self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
|
||||
self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
|
||||
self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
|
||||
self.NoResults = translate('OpenLP.Ui', 'No Search Results')
|
||||
self.OLP = translate('OpenLP.Ui', 'OpenLP')
|
||||
self.OLPV2 = "{name} {version}".format(name=self.OLP, version="2")
|
||||
self.OLPV2x = "{name} {version}".format(name=self.OLP, version="2.4")
|
||||
|
@ -139,6 +140,7 @@ class UiStrings(object):
|
|||
self.Settings = translate('OpenLP.Ui', 'Settings')
|
||||
self.SaveService = translate('OpenLP.Ui', 'Save Service')
|
||||
self.Service = translate('OpenLP.Ui', 'Service')
|
||||
self.ShortResults = translate('OpenLP.Ui', 'Please type more text to use \'Search As You Type\'')
|
||||
self.Split = translate('OpenLP.Ui', 'Optional &Split')
|
||||
self.SplitToolTip = translate('OpenLP.Ui',
|
||||
'Split a slide into two only if it does not fit on the screen as one slide.')
|
||||
|
|
|
@ -129,16 +129,16 @@ def build_icon(icon):
|
|||
location like ``/path/to/file.png``. However, the **recommended** way is to specify a resource string.
|
||||
:return: The build icon.
|
||||
"""
|
||||
button_icon = QtGui.QIcon()
|
||||
if isinstance(icon, QtGui.QIcon):
|
||||
button_icon = icon
|
||||
elif isinstance(icon, str):
|
||||
if icon.startswith(':/'):
|
||||
button_icon.addPixmap(QtGui.QPixmap(icon), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
else:
|
||||
button_icon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(icon)), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
return icon
|
||||
pix_map = None
|
||||
button_icon = QtGui.QIcon()
|
||||
if isinstance(icon, str):
|
||||
pix_map = QtGui.QPixmap(icon)
|
||||
elif isinstance(icon, QtGui.QImage):
|
||||
button_icon.addPixmap(QtGui.QPixmap.fromImage(icon), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
pix_map = QtGui.QPixmap.fromImage(icon)
|
||||
if pix_map:
|
||||
button_icon.addPixmap(pix_map, QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
return button_icon
|
||||
|
||||
|
||||
|
@ -310,30 +310,23 @@ def expand_tags(text):
|
|||
|
||||
def create_separated_list(string_list):
|
||||
"""
|
||||
Returns a string that represents a join of a list of strings with a localized separator. This function corresponds
|
||||
Returns a string that represents a join of a list of strings with a localized separator.
|
||||
Localized separation will be done via the translate() function by the translators.
|
||||
|
||||
to QLocale::createSeparatedList which was introduced in Qt 4.8 and implements the algorithm from
|
||||
http://www.unicode.org/reports/tr35/#ListPatterns
|
||||
|
||||
:param string_list: List of unicode strings
|
||||
:param string_list: List of unicode strings
|
||||
:return: Formatted string
|
||||
"""
|
||||
if LooseVersion(Qt.PYQT_VERSION_STR) >= LooseVersion('4.9') and LooseVersion(Qt.qVersion()) >= LooseVersion('4.8'):
|
||||
return QtCore.QLocale().createSeparatedList(string_list)
|
||||
if not string_list:
|
||||
return ''
|
||||
elif len(string_list) == 1:
|
||||
return string_list[0]
|
||||
# TODO: Verify mocking of translate() test before conversion
|
||||
elif len(string_list) == 2:
|
||||
return translate('OpenLP.core.lib', '%s and %s',
|
||||
'Locale list separator: 2 items') % (string_list[0], string_list[1])
|
||||
list_length = len(string_list)
|
||||
if list_length == 1:
|
||||
list_to_string = string_list[0]
|
||||
elif list_length == 2:
|
||||
list_to_string = translate('OpenLP.core.lib', '{one} and {two}').format(one=string_list[0], two=string_list[1])
|
||||
elif list_length > 2:
|
||||
list_to_string = translate('OpenLP.core.lib', '{first} and {last}').format(first=', '.join(string_list[:-1]),
|
||||
last=string_list[-1])
|
||||
else:
|
||||
merged = translate('OpenLP.core.lib', '%s, and %s',
|
||||
'Locale list separator: end') % (string_list[-2], string_list[-1])
|
||||
for index in reversed(list(range(1, len(string_list) - 2))):
|
||||
merged = translate('OpenLP.core.lib', '%s, %s',
|
||||
'Locale list separator: middle') % (string_list[index], merged)
|
||||
return translate('OpenLP.core.lib', '%s, %s', 'Locale list separator: start') % (string_list[0], merged)
|
||||
list_to_string = ''
|
||||
return list_to_string
|
||||
|
||||
|
||||
from .exceptions import ValidationError
|
||||
|
|
|
@ -266,7 +266,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
|||
self.search_text_layout.setObjectName('search_text_layout')
|
||||
self.search_text_label = QtWidgets.QLabel(self.search_widget)
|
||||
self.search_text_label.setObjectName('search_text_label')
|
||||
self.search_text_edit = SearchEdit(self.search_widget)
|
||||
self.search_text_edit = SearchEdit(self.search_widget, self.settings_section)
|
||||
self.search_text_edit.setObjectName('search_text_edit')
|
||||
self.search_text_label.setBuddy(self.search_text_edit)
|
||||
self.search_text_layout.addRow(self.search_text_label, self.search_text_edit)
|
||||
|
@ -397,8 +397,6 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
|||
# Decide if we have to show the context menu or not.
|
||||
if item is None:
|
||||
return
|
||||
if not item.flags() & QtCore.Qt.ItemIsSelectable:
|
||||
return
|
||||
self.menu.exec(self.list_view.mapToGlobal(point))
|
||||
|
||||
def get_file_list(self):
|
||||
|
@ -638,34 +636,6 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
|||
"""
|
||||
return item
|
||||
|
||||
def check_search_result(self):
|
||||
"""
|
||||
Checks if the list_view is empty and adds a "No Search Results" item.
|
||||
"""
|
||||
if self.list_view.count():
|
||||
return
|
||||
message = translate('OpenLP.MediaManagerItem', 'No Search Results')
|
||||
item = QtWidgets.QListWidgetItem(message)
|
||||
item.setFlags(QtCore.Qt.NoItemFlags)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
item.setFont(font)
|
||||
self.list_view.addItem(item)
|
||||
|
||||
def check_search_result_search_while_typing_short(self):
|
||||
"""
|
||||
This is used in Bible "Search while typing" if the search is shorter than the min required len.
|
||||
"""
|
||||
if self.list_view.count():
|
||||
return
|
||||
message = translate('OpenLP.MediaManagerItem', 'Search is too short to be used in: "Search while typing"')
|
||||
item = QtWidgets.QListWidgetItem(message)
|
||||
item.setFlags(QtCore.Qt.NoItemFlags)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
item.setFont(font)
|
||||
self.list_view.addItem(item)
|
||||
|
||||
def _get_id_of_item_to_generate(self, item, remote_item):
|
||||
"""
|
||||
Utility method to check items being submitted for slide generation.
|
||||
|
|
|
@ -26,6 +26,7 @@ from PyQt5 import QtCore, QtWidgets
|
|||
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_widget_action
|
||||
from openlp.core.common import Settings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -37,11 +38,12 @@ class SearchEdit(QtWidgets.QLineEdit):
|
|||
searchTypeChanged = QtCore.pyqtSignal(QtCore.QVariant)
|
||||
cleared = QtCore.pyqtSignal()
|
||||
|
||||
def __init__(self, parent):
|
||||
def __init__(self, parent, settings_section):
|
||||
"""
|
||||
Constructor.
|
||||
"""
|
||||
super(SearchEdit, self).__init__(parent)
|
||||
super().__init__(parent)
|
||||
self.settings_section = settings_section
|
||||
self._current_search_type = -1
|
||||
self.clear_button = QtWidgets.QToolButton(self)
|
||||
self.clear_button.setIcon(build_icon(':/system/clear_shortcut.png'))
|
||||
|
@ -100,14 +102,10 @@ class SearchEdit(QtWidgets.QLineEdit):
|
|||
menu = self.menu_button.menu()
|
||||
for action in menu.actions():
|
||||
if identifier == action.data():
|
||||
# setPlaceholderText has been implemented in Qt 4.7 and in at least PyQt 4.9 (I am not sure, if it was
|
||||
# implemented in PyQt 4.8).
|
||||
try:
|
||||
self.setPlaceholderText(action.placeholder_text)
|
||||
except AttributeError:
|
||||
pass
|
||||
self.setPlaceholderText(action.placeholder_text)
|
||||
self.menu_button.setDefaultAction(action)
|
||||
self._current_search_type = identifier
|
||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section), identifier)
|
||||
self.searchTypeChanged.emit(identifier)
|
||||
return True
|
||||
|
||||
|
@ -130,14 +128,10 @@ class SearchEdit(QtWidgets.QLineEdit):
|
|||
(2, ":/songs/authors.png", "Authors", "Search Authors...")
|
||||
"""
|
||||
menu = QtWidgets.QMenu(self)
|
||||
first = None
|
||||
for identifier, icon, title, placeholder in items:
|
||||
action = create_widget_action(
|
||||
menu, text=title, icon=icon, data=identifier, triggers=self._on_menu_action_triggered)
|
||||
action.placeholder_text = placeholder
|
||||
if first is None:
|
||||
first = action
|
||||
self._current_search_type = identifier
|
||||
if not hasattr(self, 'menu_button'):
|
||||
self.menu_button = QtWidgets.QToolButton(self)
|
||||
self.menu_button.setIcon(build_icon(':/system/clear_shortcut.png'))
|
||||
|
@ -146,7 +140,8 @@ class SearchEdit(QtWidgets.QLineEdit):
|
|||
self.menu_button.setStyleSheet('QToolButton { border: none; padding: 0px 10px 0px 0px; }')
|
||||
self.menu_button.resize(QtCore.QSize(28, 18))
|
||||
self.menu_button.setMenu(menu)
|
||||
self.menu_button.setDefaultAction(first)
|
||||
self.set_current_search_type(
|
||||
Settings().value('{section}/last search type'.format(section=self.settings_section)))
|
||||
self.menu_button.show()
|
||||
self._update_style_sheet()
|
||||
|
||||
|
|
|
@ -397,27 +397,6 @@ class AdvancedTab(SettingsTab):
|
|||
self.data_directory_cancel_button.hide()
|
||||
# Since data location can be changed, make sure the path is present.
|
||||
self.current_data_path = AppLocation.get_data_path()
|
||||
if not os.path.exists(self.current_data_path):
|
||||
log.error('Data path not found {path}'.format(path=self.current_data_path))
|
||||
answer = QtWidgets.QMessageBox.critical(
|
||||
self, translate('OpenLP.AdvancedTab', 'Data Directory Error'),
|
||||
translate('OpenLP.AdvancedTab', 'OpenLP data directory was not found\n\n{path}\n\n'
|
||||
'This data directory was previously changed from the OpenLP '
|
||||
'default location. If the new location was on removable '
|
||||
'media, that media needs to be made available.\n\n'
|
||||
'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.').format(path=self.current_data_path),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
if answer == QtWidgets.QMessageBox.No:
|
||||
log.info('User requested termination')
|
||||
self.main_window.clean_up()
|
||||
sys.exit()
|
||||
# Set data location to default.
|
||||
settings.remove('advanced/data path')
|
||||
self.current_data_path = AppLocation.get_data_path()
|
||||
log.warning('User requested data path set to default {path}'.format(path=self.current_data_path))
|
||||
self.data_directory_label.setText(os.path.abspath(self.current_data_path))
|
||||
# Don't allow data directory move if running portable.
|
||||
if settings.value('advanced/is portable'):
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_ExceptionDialog(object):
|
|||
Set up the UI.
|
||||
"""
|
||||
exception_dialog.setObjectName('exception_dialog')
|
||||
exception_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
exception_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
self.exception_layout = QtWidgets.QVBoxLayout(exception_dialog)
|
||||
self.exception_layout.setObjectName('exception_layout')
|
||||
self.message_layout = QtWidgets.QHBoxLayout()
|
||||
|
@ -97,9 +97,9 @@ class Ui_ExceptionDialog(object):
|
|||
translate('OpenLP.ExceptionDialog', '<strong>Please describe what you were trying to do.</strong> '
|
||||
' If possible, write in English.'))
|
||||
exception_part1 = (translate('OpenLP.ExceptionDialog',
|
||||
'<strong>Oops, OpenLP hit a problem and couldn\'t recover!</strong> <br><br>'
|
||||
'<strong>You can help </strong> the OpenLP developers to <strong>fix this</strong>'
|
||||
' by<br> sending them a <strong>bug report</strong> to {email}{newlines}'
|
||||
'<strong>Oops, OpenLP hit a problem and couldn\'t recover!<br><br>'
|
||||
'You can help </strong> the OpenLP developers to <strong>fix this</strong>'
|
||||
' by<br> sending them a <strong>bug report to {email}</strong>{newlines}'
|
||||
).format(email='<a href = "mailto:bugs@openlp.org" > bugs@openlp.org</a>',
|
||||
newlines='<br><br>'))
|
||||
self.message_label.setText(
|
||||
|
@ -107,7 +107,7 @@ class Ui_ExceptionDialog(object):
|
|||
'<strong>No email app? </strong> You can <strong>save</strong> this '
|
||||
'information to a <strong>file</strong> and<br>'
|
||||
'send it from your <strong>mail on browser</strong> via an <strong>attachment.</strong><br><br>'
|
||||
'<strong>Thank you<strong> for being part of making OpenLP better!<br>'
|
||||
'<strong>Thank you</strong> for being part of making OpenLP better!<br>'
|
||||
).format(first_part=exception_part1))
|
||||
self.send_report_button.setText(translate('OpenLP.ExceptionDialog', 'Send E-Mail'))
|
||||
self.save_report_button.setText(translate('OpenLP.ExceptionDialog', 'Save to File'))
|
||||
|
|
|
@ -208,7 +208,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
|
|||
self.__button_state(False)
|
||||
self.description_word_count.setText(
|
||||
translate('OpenLP.ExceptionDialog', '<strong>Please enter a more detailed description of the situation'
|
||||
))
|
||||
'</strong>'))
|
||||
|
||||
def on_attach_file_button_clicked(self):
|
||||
"""
|
||||
|
|
|
@ -37,7 +37,7 @@ class Ui_FileRenameDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
file_rename_dialog.setObjectName('file_rename_dialog')
|
||||
file_rename_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
file_rename_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
file_rename_dialog.resize(300, 10)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(file_rename_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_FirstTimeLanguageDialog(object):
|
|||
Set up the UI.
|
||||
"""
|
||||
language_dialog.setObjectName('language_dialog')
|
||||
language_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
language_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
language_dialog.resize(300, 50)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(language_dialog)
|
||||
self.dialog_layout.setContentsMargins(8, 8, 8, 8)
|
||||
|
|
|
@ -55,7 +55,7 @@ class UiFirstTimeWizard(object):
|
|||
:param first_time_wizard: The wizard form
|
||||
"""
|
||||
first_time_wizard.setObjectName('first_time_wizard')
|
||||
first_time_wizard.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
first_time_wizard.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
first_time_wizard.resize(550, 386)
|
||||
first_time_wizard.setModal(True)
|
||||
first_time_wizard.setOptions(QtWidgets.QWizard.IndependentPages | QtWidgets.QWizard.NoBackButtonOnStartPage |
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_FormattingTagDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
formatting_tag_dialog.setObjectName('formatting_tag_dialog')
|
||||
formatting_tag_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
formatting_tag_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
formatting_tag_dialog.resize(725, 548)
|
||||
self.list_data_grid_layout = QtWidgets.QVBoxLayout(formatting_tag_dialog)
|
||||
self.list_data_grid_layout.setContentsMargins(8, 8, 8, 8)
|
||||
|
|
|
@ -26,7 +26,7 @@ import os
|
|||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import Registry
|
||||
from openlp.core.common import Registry, UiStrings
|
||||
|
||||
|
||||
class ListWidgetWithDnD(QtWidgets.QListWidget):
|
||||
|
@ -37,8 +37,9 @@ class ListWidgetWithDnD(QtWidgets.QListWidget):
|
|||
"""
|
||||
Initialise the list widget
|
||||
"""
|
||||
super(ListWidgetWithDnD, self).__init__(parent)
|
||||
super().__init__(parent)
|
||||
self.mime_data_text = name
|
||||
self.no_results_text = UiStrings().NoResults
|
||||
|
||||
def activateDnD(self):
|
||||
"""
|
||||
|
@ -48,6 +49,19 @@ class ListWidgetWithDnD(QtWidgets.QListWidget):
|
|||
self.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
|
||||
Registry().register_function(('%s_dnd' % self.mime_data_text), self.parent().load_file)
|
||||
|
||||
def clear(self, search_while_typing=False):
|
||||
"""
|
||||
Re-implement clear, so that we can customise feedback when using 'Search as you type'
|
||||
|
||||
:param search_while_typing: True if we want to display the customised message
|
||||
:return: None
|
||||
"""
|
||||
if search_while_typing:
|
||||
self.no_results_text = UiStrings().ShortResults
|
||||
else:
|
||||
self.no_results_text = UiStrings().NoResults
|
||||
super().clear()
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
"""
|
||||
Drag and drop event does not care what data is selected as the recipient will use events to request the data
|
||||
|
@ -102,6 +116,24 @@ class ListWidgetWithDnD(QtWidgets.QListWidget):
|
|||
listing = os.listdir(local_file)
|
||||
for file in listing:
|
||||
files.append(os.path.join(local_file, file))
|
||||
Registry().execute('%s_dnd' % self.mime_data_text, {'files': files, 'target': self.itemAt(event.pos())})
|
||||
Registry().execute('{mime_data}_dnd'.format(mime_data=self.mime_data_text),
|
||||
{'files': files, 'target': self.itemAt(event.pos())})
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def paintEvent(self, event):
|
||||
"""
|
||||
Re-implement paintEvent so that we can add 'No Results' text when the listWidget is empty.
|
||||
|
||||
:param event: A QPaintEvent
|
||||
:return: None
|
||||
"""
|
||||
super().paintEvent(event)
|
||||
if not self.count():
|
||||
viewport = self.viewport()
|
||||
painter = QtGui.QPainter(viewport)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
painter.setFont(font)
|
||||
painter.drawText(QtCore.QRect(0, 0, viewport.width(), viewport.height()),
|
||||
(QtCore.Qt.AlignHCenter | QtCore.Qt.TextWordWrap), self.no_results_text)
|
||||
|
|
|
@ -26,7 +26,7 @@ import os
|
|||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import Registry
|
||||
from openlp.core.common import Registry, is_win
|
||||
|
||||
|
||||
class TreeWidgetWithDnD(QtWidgets.QTreeWidget):
|
||||
|
@ -108,6 +108,11 @@ class TreeWidgetWithDnD(QtWidgets.QTreeWidget):
|
|||
|
||||
:param event: Handle of the event pint passed
|
||||
"""
|
||||
# If we are on Windows, OpenLP window will not be set on top. For example, user can drag images to Library and
|
||||
# the folder stays on top of the group creation box. This piece of code fixes this issue.
|
||||
if is_win():
|
||||
self.setWindowState(self.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
|
||||
self.setWindowState(QtCore.Qt.WindowNoState)
|
||||
if event.mimeData().hasUrls():
|
||||
event.setDropAction(QtCore.Qt.CopyAction)
|
||||
event.accept()
|
||||
|
|
|
@ -46,6 +46,7 @@ class WizardStrings(object):
|
|||
OSIS = 'OSIS'
|
||||
ZEF = 'Zefania'
|
||||
SWORD = 'Sword'
|
||||
WordProject = 'WordProject'
|
||||
# These strings should need a good reason to be retranslated elsewhere.
|
||||
FinishedImport = translate('OpenLP.Ui', 'Finished import.')
|
||||
FormatLabel = translate('OpenLP.Ui', 'Format:')
|
||||
|
@ -95,6 +96,7 @@ class OpenLPWizard(QtWidgets.QWizard, RegistryProperties):
|
|||
super(OpenLPWizard, self).__init__(parent)
|
||||
self.plugin = plugin
|
||||
self.with_progress_page = add_progress_page
|
||||
self.setFixedWidth(640)
|
||||
self.setObjectName(name)
|
||||
self.open_icon = build_icon(':/general/general_open.png')
|
||||
self.delete_icon = build_icon(':/general/general_delete.png')
|
||||
|
|
|
@ -307,21 +307,13 @@ class Ui_MainWindow(object):
|
|||
self.about_item.setMenuRole(QtWidgets.QAction.AboutRole)
|
||||
if is_win():
|
||||
self.local_help_file = os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
|
||||
self.offline_help_item = create_action(main_window, 'offlineHelpItem',
|
||||
icon=':/system/system_help_contents.png',
|
||||
can_shortcuts=True,
|
||||
category=UiStrings().Help, triggers=self.on_offline_help_clicked)
|
||||
elif is_macosx():
|
||||
self.local_help_file = os.path.join(AppLocation.get_directory(AppLocation.AppDir),
|
||||
'..', 'Resources', 'OpenLP.help')
|
||||
self.offline_help_item = create_action(main_window, 'offlineHelpItem',
|
||||
icon=':/system/system_help_contents.png',
|
||||
can_shortcuts=True,
|
||||
category=UiStrings().Help, triggers=self.on_offline_help_clicked)
|
||||
self.on_line_help_item = create_action(main_window, 'onlineHelpItem',
|
||||
icon=':/system/system_online_help.png',
|
||||
can_shortcuts=True,
|
||||
category=UiStrings().Help, triggers=self.on_online_help_clicked)
|
||||
self.on_help_item = create_action(main_window, 'HelpItem',
|
||||
icon=':/system/system_help_contents.png',
|
||||
can_shortcuts=True,
|
||||
category=UiStrings().Help, triggers=self.on_help_clicked)
|
||||
self.web_site_item = create_action(main_window, 'webSiteItem', can_shortcuts=True, category=UiStrings().Help)
|
||||
# Shortcuts not connected to buttons or menu entries.
|
||||
self.search_shortcut_action = create_action(main_window,
|
||||
|
@ -360,11 +352,7 @@ class Ui_MainWindow(object):
|
|||
add_actions(self.tools_menu, (self.tools_open_data_folder, None))
|
||||
add_actions(self.tools_menu, (self.tools_first_time_wizard, None))
|
||||
add_actions(self.tools_menu, [self.update_theme_images])
|
||||
if (is_win() or is_macosx()) and (hasattr(sys, 'frozen') and sys.frozen == 1):
|
||||
add_actions(self.help_menu, (self.offline_help_item, self.on_line_help_item, None, self.web_site_item,
|
||||
self.about_item))
|
||||
else:
|
||||
add_actions(self.help_menu, (self.on_line_help_item, None, self.web_site_item, self.about_item))
|
||||
add_actions(self.help_menu, (self.on_help_item, None, self.web_site_item, self.about_item))
|
||||
add_actions(self.menu_bar, (self.file_menu.menuAction(), self.view_menu.menuAction(),
|
||||
self.tools_menu.menuAction(), self.settings_menu.menuAction(), self.help_menu.menuAction()))
|
||||
add_actions(self, [self.search_shortcut_action])
|
||||
|
@ -460,9 +448,7 @@ class Ui_MainWindow(object):
|
|||
'from here.'))
|
||||
self.about_item.setText(translate('OpenLP.MainWindow', '&About'))
|
||||
self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP.'))
|
||||
if is_win() or is_macosx():
|
||||
self.offline_help_item.setText(translate('OpenLP.MainWindow', '&User Guide'))
|
||||
self.on_line_help_item.setText(translate('OpenLP.MainWindow', '&Online Help'))
|
||||
self.on_help_item.setText(translate('OpenLP.MainWindow', '&User Manual'))
|
||||
self.search_shortcut_action.setText(UiStrings().Search)
|
||||
self.search_shortcut_action.setToolTip(
|
||||
translate('OpenLP.MainWindow', 'Jump to the search box of the current active plugin.'))
|
||||
|
@ -776,18 +762,16 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
|
|||
import webbrowser
|
||||
webbrowser.open_new('http://openlp.org/')
|
||||
|
||||
def on_offline_help_clicked(self):
|
||||
def on_help_clicked(self):
|
||||
"""
|
||||
Load the local OpenLP help file
|
||||
If is_macosx or is_win, open the local OpenLP help file.
|
||||
Use the Online manual in other cases. (Linux)
|
||||
"""
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + self.local_help_file))
|
||||
|
||||
def on_online_help_clicked(self):
|
||||
"""
|
||||
Load the online OpenLP manual
|
||||
"""
|
||||
import webbrowser
|
||||
webbrowser.open_new('http://manual.openlp.org/')
|
||||
if is_macosx() or is_win():
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + self.local_help_file))
|
||||
else:
|
||||
import webbrowser
|
||||
webbrowser.open_new('http://manual.openlp.org/')
|
||||
|
||||
def on_about_item_clicked(self):
|
||||
"""
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_PluginViewDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
plugin_view_dialog.setObjectName('plugin_view_dialog')
|
||||
plugin_view_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
plugin_view_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
plugin_view_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
self.plugin_layout = QtWidgets.QVBoxLayout(plugin_view_dialog)
|
||||
self.plugin_layout.setObjectName('plugin_layout')
|
||||
|
|
|
@ -50,7 +50,7 @@ class Ui_PrintServiceDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
print_service_dialog.setObjectName('print_service_dialog')
|
||||
print_service_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
print_service_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
print_service_dialog.resize(664, 594)
|
||||
self.main_layout = QtWidgets.QVBoxLayout(print_service_dialog)
|
||||
self.main_layout.setSpacing(0)
|
||||
|
|
|
@ -47,7 +47,7 @@ class Ui_ProjectorEditForm(object):
|
|||
Create the interface layout.
|
||||
"""
|
||||
edit_projector_dialog.setObjectName('edit_projector_dialog')
|
||||
edit_projector_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
edit_projector_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
edit_projector_dialog.setMinimumWidth(400)
|
||||
edit_projector_dialog.setModal(True)
|
||||
# Define the basic layout
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_ServiceItemEditDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
serviceItemEditDialog.setObjectName('serviceItemEditDialog')
|
||||
serviceItemEditDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
serviceItemEditDialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
self.dialog_layout = QtWidgets.QGridLayout(serviceItemEditDialog)
|
||||
self.dialog_layout.setContentsMargins(8, 8, 8, 8)
|
||||
self.dialog_layout.setSpacing(8)
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_SettingsDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
settings_dialog.setObjectName('settings_dialog')
|
||||
settings_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
settings_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
settings_dialog.resize(800, 700)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(settings_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -72,7 +72,7 @@ class Ui_ShortcutListDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
shortcutListDialog.setObjectName('shortcutListDialog')
|
||||
shortcutListDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
shortcutListDialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
shortcutListDialog.resize(500, 438)
|
||||
self.shortcut_list_layout = QtWidgets.QVBoxLayout(shortcutListDialog)
|
||||
self.shortcut_list_layout.setObjectName('shortcut_list_layout')
|
||||
|
|
|
@ -426,11 +426,11 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
|
|||
is_valid = False
|
||||
if not is_valid:
|
||||
text = translate('OpenLP.ShortcutListDialog',
|
||||
'The shortcut "{key}" is already assigned to another action, please'
|
||||
' use a different shortcut.'
|
||||
'The shortcut "{key}" is already assigned to another action,\n'
|
||||
'please use a different shortcut.'
|
||||
).format(key=self.get_shortcut_string(key_sequence))
|
||||
self.main_window.warning_message(translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'),
|
||||
text, for_display=True)
|
||||
text)
|
||||
self.dialog_was_shown = True
|
||||
return is_valid
|
||||
|
||||
|
|
|
@ -234,25 +234,32 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
self.hide_menu.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup)
|
||||
self.hide_menu.setMenu(QtWidgets.QMenu(translate('OpenLP.SlideController', 'Hide'), self.toolbar))
|
||||
self.toolbar.add_toolbar_widget(self.hide_menu)
|
||||
self.blank_screen = create_action(self, 'blankScreen',
|
||||
text=translate('OpenLP.SlideController', 'Blank Screen'),
|
||||
icon=':/slides/slide_blank.png',
|
||||
checked=False, can_shortcuts=True, category=self.category,
|
||||
triggers=self.on_blank_display)
|
||||
self.theme_screen = create_action(self, 'themeScreen',
|
||||
text=translate('OpenLP.SlideController', 'Blank to Theme'),
|
||||
icon=':/slides/slide_theme.png',
|
||||
checked=False, can_shortcuts=True, category=self.category,
|
||||
triggers=self.on_theme_display)
|
||||
# The order of the blank to modes in Shortcuts list comes from here.
|
||||
self.desktop_screen_enable = create_action(self, 'desktopScreenEnable',
|
||||
text=translate('OpenLP.SlideController', 'Show Desktop'),
|
||||
icon=':/slides/slide_desktop.png', can_shortcuts=True,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.on_hide_display_enable)
|
||||
self.desktop_screen = create_action(self, 'desktopScreen',
|
||||
text=translate('OpenLP.SlideController', 'Show Desktop'),
|
||||
text=translate('OpenLP.SlideController', 'Toggle Desktop'),
|
||||
icon=':/slides/slide_desktop.png',
|
||||
checked=False, can_shortcuts=True, category=self.category,
|
||||
triggers=self.on_hide_display)
|
||||
self.theme_screen = create_action(self, 'themeScreen',
|
||||
text=translate('OpenLP.SlideController', 'Toggle Blank to Theme'),
|
||||
icon=':/slides/slide_theme.png',
|
||||
checked=False, can_shortcuts=True, category=self.category,
|
||||
triggers=self.on_theme_display)
|
||||
self.blank_screen = create_action(self, 'blankScreen',
|
||||
text=translate('OpenLP.SlideController', 'Toggle Blank Screen'),
|
||||
icon=':/slides/slide_blank.png',
|
||||
checked=False, can_shortcuts=True, category=self.category,
|
||||
triggers=self.on_blank_display)
|
||||
self.hide_menu.setDefaultAction(self.blank_screen)
|
||||
self.hide_menu.menu().addAction(self.blank_screen)
|
||||
self.hide_menu.menu().addAction(self.theme_screen)
|
||||
self.hide_menu.menu().addAction(self.desktop_screen)
|
||||
self.hide_menu.menu().addAction(self.desktop_screen_enable)
|
||||
# Wide menu of display control buttons.
|
||||
self.blank_screen_button = QtWidgets.QToolButton(self.toolbar)
|
||||
self.blank_screen_button.setObjectName('blank_screen_button')
|
||||
|
@ -512,23 +519,6 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category,
|
||||
triggers=self.service_next)
|
||||
self.escape_item = create_action(parent, 'escapeItem',
|
||||
text=translate('OpenLP.SlideController', 'Escape Item'),
|
||||
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category,
|
||||
triggers=self.live_escape)
|
||||
|
||||
def live_escape(self, field=None):
|
||||
"""
|
||||
If you press ESC on the live screen it should close the display temporarily.
|
||||
"""
|
||||
self.display.setVisible(False)
|
||||
self.media_controller.media_stop(self)
|
||||
# Stop looping if active
|
||||
if self.play_slides_loop.isChecked():
|
||||
self.on_play_slides_loop(False)
|
||||
elif self.play_slides_once.isChecked():
|
||||
self.on_play_slides_once(False)
|
||||
|
||||
def toggle_display(self, action):
|
||||
"""
|
||||
|
@ -622,7 +612,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
widget.addActions([
|
||||
self.previous_item, self.next_item,
|
||||
self.previous_service, self.next_service,
|
||||
self.escape_item,
|
||||
self.desktop_screen_enable,
|
||||
self.desktop_screen,
|
||||
self.theme_screen,
|
||||
self.blank_screen])
|
||||
|
@ -732,8 +722,10 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
# Reset the button
|
||||
self.play_slides_once.setChecked(False)
|
||||
self.play_slides_once.setIcon(build_icon(':/media/media_time.png'))
|
||||
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
|
||||
self.play_slides_loop.setChecked(False)
|
||||
self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
|
||||
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
||||
if item.is_text():
|
||||
if (Settings().value(self.main_window.songs_settings_section + '/display songbar') and
|
||||
not self.song_menu.menu().isEmpty()):
|
||||
|
@ -965,7 +957,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
else:
|
||||
Registry().execute('live_display_show')
|
||||
else:
|
||||
self.live_escape()
|
||||
self.on_hide_display_enable()
|
||||
|
||||
def on_slide_blank(self):
|
||||
"""
|
||||
|
@ -1025,6 +1017,7 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
def on_hide_display(self, checked=None):
|
||||
"""
|
||||
Handle the Hide screen button
|
||||
This toggles the desktop screen.
|
||||
|
||||
:param checked: the new state of the of the widget
|
||||
"""
|
||||
|
@ -1043,6 +1036,20 @@ class SlideController(DisplayController, RegistryProperties):
|
|||
self.update_preview()
|
||||
self.on_toggle_loop()
|
||||
|
||||
def on_hide_display_enable(self, checked=None):
|
||||
"""
|
||||
Handle the on_hide_display_enable
|
||||
This only enables the desktop screen.
|
||||
|
||||
:param checked: the new state of the of the widget
|
||||
"""
|
||||
self.blank_screen.setChecked(False)
|
||||
self.theme_screen.setChecked(False)
|
||||
Registry().execute('live_display_hide', HideMode.Screen)
|
||||
self.desktop_screen.setChecked(True)
|
||||
self.update_preview()
|
||||
self.on_toggle_loop()
|
||||
|
||||
def blank_plugin(self):
|
||||
"""
|
||||
Blank/Hide the display screen within a plugin if required.
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_StartTimeDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
StartTimeDialog.setObjectName('StartTimeDialog')
|
||||
StartTimeDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
StartTimeDialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
StartTimeDialog.resize(350, 10)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(StartTimeDialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_ThemeLayoutDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
themeLayoutDialog.setObjectName('themeLayoutDialogDialog')
|
||||
themeLayoutDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
themeLayoutDialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
self.preview_layout = QtWidgets.QVBoxLayout(themeLayoutDialog)
|
||||
self.preview_layout.setObjectName('preview_layout')
|
||||
self.preview_area = QtWidgets.QWidget(themeLayoutDialog)
|
||||
|
|
|
@ -40,7 +40,7 @@ class Ui_ThemeWizard(object):
|
|||
Set up the UI
|
||||
"""
|
||||
theme_wizard.setObjectName('OpenLP.ThemeWizard')
|
||||
theme_wizard.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
theme_wizard.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
theme_wizard.setModal(True)
|
||||
theme_wizard.setOptions(QtWidgets.QWizard.IndependentPages |
|
||||
QtWidgets.QWizard.NoBackButtonOnStartPage | QtWidgets.QWizard.HaveCustomButton1)
|
||||
|
|
|
@ -39,7 +39,7 @@ class Ui_AlertDialog(object):
|
|||
"""
|
||||
alert_dialog.setObjectName('alert_dialog')
|
||||
alert_dialog.resize(400, 300)
|
||||
alert_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
alert_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
self.alert_dialog_layout = QtWidgets.QGridLayout(alert_dialog)
|
||||
self.alert_dialog_layout.setObjectName('alert_dialog_layout')
|
||||
self.alert_text_layout = QtWidgets.QFormLayout()
|
||||
|
|
|
@ -140,10 +140,10 @@ class BiblePlugin(Plugin):
|
|||
|
||||
def uses_theme(self, theme):
|
||||
"""
|
||||
Called to find out if the bible plugin is currently using a theme. Returns ``1`` if the theme is being used,
|
||||
otherwise returns ``0``.
|
||||
Called to find out if the bible plugin is currently using a theme.
|
||||
|
||||
:param theme: The theme
|
||||
:return: 1 if the theme is being used, otherwise returns 0
|
||||
"""
|
||||
if str(self.settings_tab.bible_theme) == theme:
|
||||
return 1
|
||||
|
@ -151,11 +151,11 @@ class BiblePlugin(Plugin):
|
|||
|
||||
def rename_theme(self, old_theme, new_theme):
|
||||
"""
|
||||
Rename the theme the bible plugin is using making the plugin use the
|
||||
new name.
|
||||
Rename the theme the bible plugin is using, making the plugin use the new name.
|
||||
|
||||
:param old_theme: The name of the theme the plugin should stop using. Unused for this particular plugin.
|
||||
:param new_theme: The new name the plugin should now use.
|
||||
:return: None
|
||||
"""
|
||||
self.settings_tab.bible_theme = new_theme
|
||||
self.settings_tab.save()
|
||||
|
|
|
@ -25,6 +25,7 @@ The bible import functions for OpenLP
|
|||
import logging
|
||||
import os
|
||||
import urllib.error
|
||||
from lxml import etree
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
try:
|
||||
|
@ -33,14 +34,15 @@ try:
|
|||
except:
|
||||
PYSWORD_AVAILABLE = False
|
||||
|
||||
from openlp.core.common import AppLocation, Settings, UiStrings, translate, clean_filename
|
||||
from openlp.core.common import AppLocation, Settings, UiStrings, trace_error_handler, translate
|
||||
from openlp.core.common.languagemanager import get_locale_key
|
||||
from openlp.core.lib.db import delete_database
|
||||
from openlp.core.lib.exceptions import ValidationError
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.lib.wizard import OpenLPWizard, WizardStrings
|
||||
from openlp.core.common.languagemanager import get_locale_key
|
||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||
from openlp.plugins.bibles.lib.db import clean_filename
|
||||
from openlp.plugins.bibles.lib.importers.http import CWExtract, BGExtract, BSExtract
|
||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -123,6 +125,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.csv_verses_button.clicked.connect(self.on_csv_verses_browse_button_clicked)
|
||||
self.open_song_browse_button.clicked.connect(self.on_open_song_browse_button_clicked)
|
||||
self.zefania_browse_button.clicked.connect(self.on_zefania_browse_button_clicked)
|
||||
self.wordproject_browse_button.clicked.connect(self.on_wordproject_browse_button_clicked)
|
||||
self.web_update_button.clicked.connect(self.on_web_update_button_clicked)
|
||||
self.sword_browse_button.clicked.connect(self.on_sword_browse_button_clicked)
|
||||
self.sword_zipbrowse_button.clicked.connect(self.on_sword_zipbrowse_button_clicked)
|
||||
|
@ -141,7 +144,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.format_label = QtWidgets.QLabel(self.select_page)
|
||||
self.format_label.setObjectName('FormatLabel')
|
||||
self.format_combo_box = QtWidgets.QComboBox(self.select_page)
|
||||
self.format_combo_box.addItems(['', '', '', '', '', ''])
|
||||
self.format_combo_box.addItems(['', '', '', '', '', '', ''])
|
||||
self.format_combo_box.setObjectName('FormatComboBox')
|
||||
self.format_layout.addRow(self.format_label, self.format_combo_box)
|
||||
self.spacer = QtWidgets.QSpacerItem(10, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
|
||||
|
@ -159,6 +162,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.osis_file_layout = QtWidgets.QHBoxLayout()
|
||||
self.osis_file_layout.setObjectName('OsisFileLayout')
|
||||
self.osis_file_edit = QtWidgets.QLineEdit(self.osis_widget)
|
||||
self.osis_file_edit.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
|
||||
self.osis_file_edit.setObjectName('OsisFileEdit')
|
||||
self.osis_file_layout.addWidget(self.osis_file_edit)
|
||||
self.osis_browse_button = QtWidgets.QToolButton(self.osis_widget)
|
||||
|
@ -178,6 +182,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.csv_books_layout = QtWidgets.QHBoxLayout()
|
||||
self.csv_books_layout.setObjectName('CsvBooksLayout')
|
||||
self.csv_books_edit = QtWidgets.QLineEdit(self.csv_widget)
|
||||
self.csv_books_edit.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
|
||||
self.csv_books_edit.setObjectName('CsvBooksEdit')
|
||||
self.csv_books_layout.addWidget(self.csv_books_edit)
|
||||
self.csv_books_button = QtWidgets.QToolButton(self.csv_widget)
|
||||
|
@ -190,6 +195,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.csv_verses_layout = QtWidgets.QHBoxLayout()
|
||||
self.csv_verses_layout.setObjectName('CsvVersesLayout')
|
||||
self.csv_verses_edit = QtWidgets.QLineEdit(self.csv_widget)
|
||||
self.csv_verses_edit.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
|
||||
self.csv_verses_edit.setObjectName('CsvVersesEdit')
|
||||
self.csv_verses_layout.addWidget(self.csv_verses_edit)
|
||||
self.csv_verses_button = QtWidgets.QToolButton(self.csv_widget)
|
||||
|
@ -209,6 +215,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.open_song_file_layout = QtWidgets.QHBoxLayout()
|
||||
self.open_song_file_layout.setObjectName('OpenSongFileLayout')
|
||||
self.open_song_file_edit = QtWidgets.QLineEdit(self.open_song_widget)
|
||||
self.open_song_file_edit.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
|
||||
self.open_song_file_edit.setObjectName('OpenSongFileEdit')
|
||||
self.open_song_file_layout.addWidget(self.open_song_file_edit)
|
||||
self.open_song_browse_button = QtWidgets.QToolButton(self.open_song_widget)
|
||||
|
@ -298,61 +305,84 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.sword_widget = QtWidgets.QWidget(self.select_page)
|
||||
self.sword_widget.setObjectName('SwordWidget')
|
||||
self.sword_layout = QtWidgets.QVBoxLayout(self.sword_widget)
|
||||
self.sword_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.sword_layout.setObjectName('SwordLayout')
|
||||
self.sword_tab_widget = QtWidgets.QTabWidget(self.sword_widget)
|
||||
self.sword_tab_widget.setObjectName('SwordTabWidget')
|
||||
self.sword_folder_tab = QtWidgets.QWidget(self.sword_tab_widget)
|
||||
self.sword_folder_tab.setObjectName('SwordFolderTab')
|
||||
self.sword_folder_tab_layout = QtWidgets.QGridLayout(self.sword_folder_tab)
|
||||
self.sword_folder_tab_layout = QtWidgets.QFormLayout(self.sword_folder_tab)
|
||||
self.sword_folder_tab_layout.setObjectName('SwordTabFolderLayout')
|
||||
self.sword_folder_label = QtWidgets.QLabel(self.sword_folder_tab)
|
||||
self.sword_folder_label.setObjectName('SwordSourceLabel')
|
||||
self.sword_folder_tab_layout.addWidget(self.sword_folder_label, 0, 0)
|
||||
self.sword_folder_label.setObjectName('SwordFolderLabel')
|
||||
self.sword_folder_edit = QtWidgets.QLineEdit(self.sword_folder_tab)
|
||||
self.sword_folder_edit.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
|
||||
self.sword_folder_edit.setObjectName('SwordFolderEdit')
|
||||
self.sword_browse_button = QtWidgets.QToolButton(self.sword_folder_tab)
|
||||
self.sword_browse_button.setIcon(self.open_icon)
|
||||
self.sword_browse_button.setObjectName('SwordBrowseButton')
|
||||
self.sword_folder_tab_layout.addWidget(self.sword_folder_edit, 0, 1)
|
||||
self.sword_folder_tab_layout.addWidget(self.sword_browse_button, 0, 2)
|
||||
self.sword_folder_layout = QtWidgets.QHBoxLayout()
|
||||
self.sword_folder_layout.addWidget(self.sword_folder_edit)
|
||||
self.sword_folder_layout.addWidget(self.sword_browse_button)
|
||||
self.sword_folder_tab_layout.addRow(self.sword_folder_label, self.sword_folder_layout)
|
||||
self.sword_bible_label = QtWidgets.QLabel(self.sword_folder_tab)
|
||||
self.sword_bible_label.setObjectName('SwordBibleLabel')
|
||||
self.sword_folder_tab_layout.addWidget(self.sword_bible_label, 1, 0)
|
||||
self.sword_bible_combo_box = QtWidgets.QComboBox(self.sword_folder_tab)
|
||||
self.sword_bible_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
|
||||
self.sword_bible_combo_box.setInsertPolicy(QtWidgets.QComboBox.InsertAlphabetically)
|
||||
self.sword_bible_combo_box.setObjectName('SwordBibleComboBox')
|
||||
self.sword_folder_tab_layout.addWidget(self.sword_bible_combo_box, 1, 1)
|
||||
self.sword_folder_tab_layout.addRow(self.sword_bible_label, self.sword_bible_combo_box)
|
||||
self.sword_tab_widget.addTab(self.sword_folder_tab, '')
|
||||
self.sword_zip_tab = QtWidgets.QWidget(self.sword_tab_widget)
|
||||
self.sword_zip_tab.setObjectName('SwordZipTab')
|
||||
self.sword_zip_layout = QtWidgets.QGridLayout(self.sword_zip_tab)
|
||||
self.sword_zip_layout = QtWidgets.QFormLayout(self.sword_zip_tab)
|
||||
self.sword_zip_layout.setObjectName('SwordZipLayout')
|
||||
self.sword_zipfile_label = QtWidgets.QLabel(self.sword_zip_tab)
|
||||
self.sword_zipfile_label.setObjectName('SwordZipFileLabel')
|
||||
self.sword_zipfile_edit = QtWidgets.QLineEdit(self.sword_zip_tab)
|
||||
self.sword_zipfile_edit.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
|
||||
self.sword_zipfile_edit.setObjectName('SwordZipFileEdit')
|
||||
self.sword_zipbrowse_button = QtWidgets.QToolButton(self.sword_zip_tab)
|
||||
self.sword_zipbrowse_button.setIcon(self.open_icon)
|
||||
self.sword_zipbrowse_button.setObjectName('SwordZipBrowseButton')
|
||||
self.sword_zipfile_layout = QtWidgets.QHBoxLayout()
|
||||
self.sword_zipfile_layout.addWidget(self.sword_zipfile_edit)
|
||||
self.sword_zipfile_layout.addWidget(self.sword_zipbrowse_button)
|
||||
self.sword_zip_layout.addRow(self.sword_zipfile_label, self.sword_zipfile_layout)
|
||||
self.sword_zipbible_label = QtWidgets.QLabel(self.sword_folder_tab)
|
||||
self.sword_zipbible_label.setObjectName('SwordZipBibleLabel')
|
||||
self.sword_zipbible_combo_box = QtWidgets.QComboBox(self.sword_zip_tab)
|
||||
self.sword_zipbible_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
|
||||
self.sword_zipbible_combo_box.setInsertPolicy(QtWidgets.QComboBox.InsertAlphabetically)
|
||||
self.sword_zipbible_combo_box.setObjectName('SwordZipBibleComboBox')
|
||||
self.sword_zip_layout.addWidget(self.sword_zipfile_label, 0, 0)
|
||||
self.sword_zip_layout.addWidget(self.sword_zipfile_edit, 0, 1)
|
||||
self.sword_zip_layout.addWidget(self.sword_zipbrowse_button, 0, 2)
|
||||
self.sword_zip_layout.addWidget(self.sword_zipbible_label, 1, 0)
|
||||
self.sword_zip_layout.addWidget(self.sword_zipbible_combo_box, 1, 1)
|
||||
self.sword_zip_layout.addRow(self.sword_zipbible_label, self.sword_zipbible_combo_box)
|
||||
self.sword_tab_widget.addTab(self.sword_zip_tab, '')
|
||||
self.sword_layout.addWidget(self.sword_tab_widget)
|
||||
self.sword_disabled_label = QtWidgets.QLabel(self.sword_widget)
|
||||
self.sword_disabled_label.setObjectName('SwordDisabledLabel')
|
||||
self.sword_layout.addWidget(self.sword_disabled_label)
|
||||
self.select_stack.addWidget(self.sword_widget)
|
||||
self.wordproject_widget = QtWidgets.QWidget(self.select_page)
|
||||
self.wordproject_widget.setObjectName('WordProjectWidget')
|
||||
self.wordproject_layout = QtWidgets.QFormLayout(self.wordproject_widget)
|
||||
self.wordproject_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.wordproject_layout.setObjectName('WordProjectLayout')
|
||||
self.wordproject_file_label = QtWidgets.QLabel(self.wordproject_widget)
|
||||
self.wordproject_file_label.setObjectName('WordProjectFileLabel')
|
||||
self.wordproject_file_layout = QtWidgets.QHBoxLayout()
|
||||
self.wordproject_file_layout.setObjectName('WordProjectFileLayout')
|
||||
self.wordproject_file_edit = QtWidgets.QLineEdit(self.wordproject_widget)
|
||||
self.wordproject_file_edit.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
|
||||
self.wordproject_file_edit.setObjectName('WordProjectFileEdit')
|
||||
self.wordproject_file_layout.addWidget(self.wordproject_file_edit)
|
||||
self.wordproject_browse_button = QtWidgets.QToolButton(self.wordproject_widget)
|
||||
self.wordproject_browse_button.setIcon(self.open_icon)
|
||||
self.wordproject_browse_button.setObjectName('WordProjectBrowseButton')
|
||||
self.wordproject_file_layout.addWidget(self.wordproject_browse_button)
|
||||
self.wordproject_layout.addRow(self.wordproject_file_label, self.wordproject_file_layout)
|
||||
self.wordproject_layout.setItem(5, QtWidgets.QFormLayout.LabelRole, self.spacer)
|
||||
self.select_stack.addWidget(self.wordproject_widget)
|
||||
self.select_page_layout.addLayout(self.select_stack)
|
||||
self.addPage(self.select_page)
|
||||
# License Page
|
||||
|
@ -398,6 +428,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.format_combo_box.setItemText(BibleFormat.OSIS, WizardStrings.OSIS)
|
||||
self.format_combo_box.setItemText(BibleFormat.CSV, WizardStrings.CSV)
|
||||
self.format_combo_box.setItemText(BibleFormat.OpenSong, WizardStrings.OS)
|
||||
self.format_combo_box.setItemText(BibleFormat.WordProject, WizardStrings.WordProject)
|
||||
self.format_combo_box.setItemText(BibleFormat.WebDownload, translate('BiblesPlugin.ImportWizardForm',
|
||||
'Web Download'))
|
||||
self.format_combo_box.setItemText(BibleFormat.Zefania, WizardStrings.ZEF)
|
||||
|
@ -408,6 +439,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.open_song_file_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
||||
self.web_source_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Location:'))
|
||||
self.zefania_file_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
||||
self.wordproject_file_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
||||
self.web_update_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Click to download bible list'))
|
||||
self.web_update_button.setText(translate('BiblesPlugin.ImportWizardForm', 'Download bible list'))
|
||||
self.web_source_combo_box.setItemText(WebDownload.Crosswalk, translate('BiblesPlugin.ImportWizardForm',
|
||||
|
@ -466,6 +498,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
"""
|
||||
Validate the current page before moving on to the next page.
|
||||
"""
|
||||
log.debug(self.size())
|
||||
if self.currentPage() == self.welcome_page:
|
||||
return True
|
||||
elif self.currentPage() == self.select_page:
|
||||
|
@ -502,6 +535,12 @@ class BibleImportForm(OpenLPWizard):
|
|||
critical_error_message_box(UiStrings().NFSs, WizardStrings.YouSpecifyFile % WizardStrings.ZEF)
|
||||
self.zefania_file_edit.setFocus()
|
||||
return False
|
||||
elif self.field('source_format') == BibleFormat.WordProject:
|
||||
if not self.field('wordproject_file'):
|
||||
critical_error_message_box(UiStrings().NFSs,
|
||||
WizardStrings.YouSpecifyFile % WizardStrings.WordProject)
|
||||
self.wordproject_file_edit.setFocus()
|
||||
return False
|
||||
elif self.field('source_format') == BibleFormat.WebDownload:
|
||||
# If count is 0 the bible list has not yet been downloaded
|
||||
if self.web_translation_combo_box.count() == 0:
|
||||
|
@ -625,6 +664,14 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.get_file_name(WizardStrings.OpenTypeFile % WizardStrings.ZEF, self.zefania_file_edit,
|
||||
'last directory import')
|
||||
|
||||
def on_wordproject_browse_button_clicked(self):
|
||||
"""
|
||||
Show the file open dialog for the WordProject file.
|
||||
"""
|
||||
# TODO: Verify format() with variable template
|
||||
self.get_file_name(WizardStrings.OpenTypeFile % WizardStrings.WordProject, self.wordproject_file_edit,
|
||||
'last directory import')
|
||||
|
||||
def on_web_update_button_clicked(self):
|
||||
"""
|
||||
Download list of bibles from Crosswalk, BibleServer and BibleGateway.
|
||||
|
@ -705,6 +752,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.select_page.registerField('csv_versefile', self.csv_verses_edit)
|
||||
self.select_page.registerField('opensong_file', self.open_song_file_edit)
|
||||
self.select_page.registerField('zefania_file', self.zefania_file_edit)
|
||||
self.select_page.registerField('wordproject_file', self.wordproject_file_edit)
|
||||
self.select_page.registerField('web_location', self.web_source_combo_box)
|
||||
self.select_page.registerField('web_biblename', self.web_translation_combo_box)
|
||||
self.select_page.registerField('sword_folder_path', self.sword_folder_edit)
|
||||
|
@ -797,6 +845,10 @@ class BibleImportForm(OpenLPWizard):
|
|||
# Import a Zefania bible.
|
||||
importer = self.manager.import_bible(BibleFormat.Zefania, name=license_version,
|
||||
filename=self.field('zefania_file'))
|
||||
elif bible_type == BibleFormat.WordProject:
|
||||
# Import a WordProject bible.
|
||||
importer = self.manager.import_bible(BibleFormat.WordProject, name=license_version,
|
||||
filename=self.field('wordproject_file'))
|
||||
elif bible_type == BibleFormat.SWORD:
|
||||
# Import a SWORD bible.
|
||||
if self.sword_tab_widget.currentIndex() == self.sword_tab_widget.indexOf(self.sword_folder_tab):
|
||||
|
@ -809,16 +861,22 @@ class BibleImportForm(OpenLPWizard):
|
|||
sword_path=self.field('sword_zip_path'),
|
||||
sword_key=self.sword_zipbible_combo_box.itemData(
|
||||
self.sword_zipbible_combo_box.currentIndex()))
|
||||
if importer.do_import(license_version):
|
||||
self.manager.save_meta_data(license_version, license_version, license_copyright, license_permissions)
|
||||
self.manager.reload_bibles()
|
||||
if bible_type == BibleFormat.WebDownload:
|
||||
self.progress_label.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Registered Bible. Please note, that verses will be '
|
||||
'downloaded on demand and thus an internet connection is required.'))
|
||||
else:
|
||||
self.progress_label.setText(WizardStrings.FinishedImport)
|
||||
else:
|
||||
self.progress_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Your Bible import failed.'))
|
||||
del self.manager.db_cache[importer.name]
|
||||
delete_database(self.plugin.settings_section, importer.file)
|
||||
|
||||
try:
|
||||
if importer.do_import(license_version) and not importer.stop_import_flag:
|
||||
self.manager.save_meta_data(license_version, license_version, license_copyright, license_permissions)
|
||||
self.manager.reload_bibles()
|
||||
if bible_type == BibleFormat.WebDownload:
|
||||
self.progress_label.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Registered Bible. Please note, that verses will be '
|
||||
'downloaded on demand and thus an internet connection is required.'))
|
||||
else:
|
||||
self.progress_label.setText(WizardStrings.FinishedImport)
|
||||
return
|
||||
except (AttributeError, ValidationError, etree.XMLSyntaxError):
|
||||
log.exception('Importing bible failed')
|
||||
trace_error_handler(log)
|
||||
|
||||
self.progress_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Your Bible import failed.'))
|
||||
del self.manager.db_cache[importer.name]
|
||||
delete_database(self.plugin.settings_section, importer.file)
|
||||
|
|
|
@ -30,7 +30,7 @@ from openlp.core.lib.ui import create_button_box
|
|||
class Ui_BookNameDialog(object):
|
||||
def setupUi(self, book_name_dialog):
|
||||
book_name_dialog.setObjectName('book_name_dialog')
|
||||
book_name_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
book_name_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
book_name_dialog.resize(400, 271)
|
||||
self.book_name_layout = QtWidgets.QVBoxLayout(book_name_dialog)
|
||||
self.book_name_layout.setSpacing(8)
|
||||
|
|
|
@ -32,7 +32,7 @@ from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
|||
class Ui_EditBibleDialog(object):
|
||||
def setupUi(self, edit_bible_dialog):
|
||||
edit_bible_dialog.setObjectName('edit_bible_dialog')
|
||||
edit_bible_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
edit_bible_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
edit_bible_dialog.resize(520, 400)
|
||||
edit_bible_dialog.setModal(True)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(edit_bible_dialog)
|
||||
|
|
|
@ -30,7 +30,7 @@ from openlp.core.lib.ui import create_button_box
|
|||
class Ui_LanguageDialog(object):
|
||||
def setupUi(self, language_dialog):
|
||||
language_dialog.setObjectName('language_dialog')
|
||||
language_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
language_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
language_dialog.resize(400, 165)
|
||||
self.language_layout = QtWidgets.QVBoxLayout(language_dialog)
|
||||
self.language_layout.setSpacing(8)
|
||||
|
|
|
@ -173,7 +173,7 @@ class BibleStrings(object):
|
|||
|
||||
def update_reference_separators():
|
||||
"""
|
||||
Updates separators and matches for parsing and formating scripture references.
|
||||
Updates separators and matches for parsing and formatting scripture references.
|
||||
"""
|
||||
default_separators = [
|
||||
'|'.join([
|
||||
|
@ -215,7 +215,7 @@ def update_reference_separators():
|
|||
# escape reserved characters
|
||||
for character in '\\.^$*+?{}[]()':
|
||||
source_string = source_string.replace(character, '\\' + character)
|
||||
# add various unicode alternatives
|
||||
# add various Unicode alternatives
|
||||
source_string = source_string.replace('-', '(?:[-\u00AD\u2010\u2011\u2012\u2014\u2014\u2212\uFE63\uFF0D])')
|
||||
source_string = source_string.replace(',', '(?:[,\u201A])')
|
||||
REFERENCE_SEPARATORS['sep_{role}'.format(role=role)] = '\s*(?:{source})\s*'.format(source=source_string)
|
||||
|
|
|
@ -20,25 +20,84 @@
|
|||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
import logging
|
||||
|
||||
from lxml import etree, objectify
|
||||
from zipfile import is_zipfile
|
||||
|
||||
from openlp.core.common import OpenLPMixin, languages
|
||||
from openlp.core.common import OpenLPMixin, Registry, RegistryProperties, languages, translate
|
||||
from openlp.core.lib import ValidationError
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.lib.db import AlternativeBookNamesDB, BibleDB, BiblesResourcesDB
|
||||
|
||||
|
||||
class BibleImport(OpenLPMixin, BibleDB):
|
||||
class BibleImport(OpenLPMixin, RegistryProperties, BibleDB):
|
||||
"""
|
||||
Helper class to import bibles from a third party source into OpenLP
|
||||
"""
|
||||
# TODO: Test
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.filename = kwargs['filename'] if 'filename' in kwargs else None
|
||||
self.wizard = None
|
||||
self.stop_import_flag = False
|
||||
Registry().register_function('openlp_stop_wizard', self.stop_import)
|
||||
|
||||
@staticmethod
|
||||
def is_compressed(file):
|
||||
"""
|
||||
Check if the supplied file is compressed
|
||||
|
||||
:param file: A path to the file to check
|
||||
"""
|
||||
if is_zipfile(file):
|
||||
critical_error_message_box(
|
||||
message=translate('BiblesPlugin.BibleImport',
|
||||
'The file "{file}" you supplied is compressed. You must decompress it before import.'
|
||||
).format(file=file))
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_book_ref_id_by_name(self, book, maxbooks=66, language_id=None):
|
||||
"""
|
||||
Find the book id from the name or abbreviation of the book. If it doesn't currently exist, ask the user.
|
||||
|
||||
:param book: The name or abbreviation of the book
|
||||
:param maxbooks: The number of books in the bible
|
||||
:param language_id: The language_id of the bible
|
||||
:return: The id of the bible, or None
|
||||
"""
|
||||
self.log_debug('BibleDB.get_book_ref_id_by_name:("{book}", "{lang}")'.format(book=book, lang=language_id))
|
||||
book_temp = BiblesResourcesDB.get_book(book, True)
|
||||
if book_temp:
|
||||
return book_temp['id']
|
||||
book_id = BiblesResourcesDB.get_alternative_book_name(book)
|
||||
if book_id:
|
||||
return book_id
|
||||
book_id = AlternativeBookNamesDB.get_book_reference_id(book)
|
||||
if book_id:
|
||||
return book_id
|
||||
from openlp.plugins.bibles.forms import BookNameForm
|
||||
book_name = BookNameForm(self.wizard)
|
||||
if book_name.exec(book, self.get_books(), maxbooks) and book_name.book_id:
|
||||
AlternativeBookNamesDB.create_alternative_book_name(book, book_name.book_id, language_id)
|
||||
return book_name.book_id
|
||||
|
||||
def get_language(self, bible_name=None):
|
||||
"""
|
||||
If no language is given it calls a dialog window where the user could select the bible language.
|
||||
Return the language id of a bible.
|
||||
|
||||
:param bible_name: The language the bible is.
|
||||
"""
|
||||
self.log_debug('BibleImpoer.get_language()')
|
||||
from openlp.plugins.bibles.forms import LanguageForm
|
||||
language_id = None
|
||||
language_form = LanguageForm(self.wizard)
|
||||
if language_form.exec(bible_name):
|
||||
combo_box = language_form.language_combo_box
|
||||
language_id = combo_box.itemData(combo_box.currentIndex())
|
||||
if not language_id:
|
||||
return None
|
||||
self.save_meta('language_id', language_id)
|
||||
return language_id
|
||||
|
||||
def get_language_id(self, file_language=None, bible_name=None):
|
||||
"""
|
||||
|
@ -58,8 +117,8 @@ class BibleImport(OpenLPMixin, BibleDB):
|
|||
language_id = self.get_language(bible_name)
|
||||
if not language_id:
|
||||
# User cancelled get_language dialog
|
||||
log.error('Language detection failed when importing from "{name}". User aborted language selection.'
|
||||
.format(name=bible_name))
|
||||
self.log_error('Language detection failed when importing from "{name}". User aborted language selection.'
|
||||
.format(name=bible_name))
|
||||
return None
|
||||
self.save_meta('language_id', language_id)
|
||||
return language_id
|
||||
|
@ -77,7 +136,7 @@ class BibleImport(OpenLPMixin, BibleDB):
|
|||
if name:
|
||||
book_ref_id = self.get_book_ref_id_by_name(name, no_of_books, language_id)
|
||||
else:
|
||||
log.debug('No book name supplied. Falling back to guess_id')
|
||||
self.log_debug('No book name supplied. Falling back to guess_id')
|
||||
book_ref_id = guess_id
|
||||
if not book_ref_id:
|
||||
raise ValidationError(msg='Could not resolve book_ref_id in "{}"'.format(self.filename))
|
||||
|
@ -87,8 +146,7 @@ class BibleImport(OpenLPMixin, BibleDB):
|
|||
'importing {file}'.format(book_ref=book_ref_id, file=self.filename))
|
||||
return self.create_book(name, book_ref_id, book_details['testament_id'])
|
||||
|
||||
@staticmethod
|
||||
def parse_xml(filename, use_objectify=False, elements=None, tags=None):
|
||||
def parse_xml(self, filename, use_objectify=False, elements=None, tags=None):
|
||||
"""
|
||||
Parse and clean the supplied file by removing any elements or tags we don't use.
|
||||
:param filename: The filename of the xml file to parse. Str
|
||||
|
@ -97,17 +155,80 @@ class BibleImport(OpenLPMixin, BibleDB):
|
|||
:param tags: A tuple of element names (Str) to remove, preserving their content.
|
||||
:return: The root element of the xml document
|
||||
"""
|
||||
with open(filename, 'rb') as import_file:
|
||||
# NOTE: We don't need to do any of the normal encoding detection here, because lxml does it's own encoding
|
||||
# detection, and the two mechanisms together interfere with each other.
|
||||
if not use_objectify:
|
||||
tree = etree.parse(import_file, parser=etree.XMLParser(recover=True))
|
||||
else:
|
||||
tree = objectify.parse(import_file, parser=objectify.makeparser(recover=True))
|
||||
if elements:
|
||||
# Strip tags we don't use - remove content
|
||||
etree.strip_elements(tree, elements, with_tail=False)
|
||||
if tags:
|
||||
# Strip tags we don't use - keep content
|
||||
etree.strip_tags(tree, tags)
|
||||
return tree.getroot()
|
||||
try:
|
||||
with open(filename, 'rb') as import_file:
|
||||
# NOTE: We don't need to do any of the normal encoding detection here, because lxml does it's own
|
||||
# encoding detection, and the two mechanisms together interfere with each other.
|
||||
if not use_objectify:
|
||||
tree = etree.parse(import_file, parser=etree.XMLParser(recover=True))
|
||||
else:
|
||||
tree = objectify.parse(import_file, parser=objectify.makeparser(recover=True))
|
||||
if elements or tags:
|
||||
self.wizard.increment_progress_bar(
|
||||
translate('BiblesPlugin.OsisImport', 'Removing unused tags (this may take a few minutes)...'))
|
||||
if elements:
|
||||
# Strip tags we don't use - remove content
|
||||
etree.strip_elements(tree, elements, with_tail=False)
|
||||
if tags:
|
||||
# Strip tags we don't use - keep content
|
||||
etree.strip_tags(tree, tags)
|
||||
return tree.getroot()
|
||||
except OSError as e:
|
||||
self.log_exception('Opening {file_name} failed.'.format(file_name=e.filename))
|
||||
critical_error_message_box(
|
||||
title='An Error Occured When Opening A File',
|
||||
message='The following error occurred when trying to open\n{file_name}:\n\n{error}'
|
||||
.format(file_name=e.filename, error=e.strerror))
|
||||
return None
|
||||
|
||||
def register(self, wizard):
|
||||
"""
|
||||
This method basically just initialises the database. It is called from the Bible Manager when a Bible is
|
||||
imported. Descendant classes may want to override this method to supply their own custom
|
||||
initialisation as well.
|
||||
|
||||
:param wizard: The actual Qt wizard form.
|
||||
"""
|
||||
self.wizard = wizard
|
||||
return self.name
|
||||
|
||||
def set_current_chapter(self, book_name, chapter_name):
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.OsisImport', 'Importing {book} {chapter}...')
|
||||
.format(book=book_name, chapter=chapter_name))
|
||||
|
||||
def stop_import(self):
|
||||
"""
|
||||
Stops the import of the Bible.
|
||||
"""
|
||||
self.log_debug('Stopping import')
|
||||
self.stop_import_flag = True
|
||||
|
||||
def validate_xml_file(self, filename, tag):
|
||||
"""
|
||||
Validate the supplied file
|
||||
|
||||
:param filename: The supplied file
|
||||
:param tag: The expected root tag type
|
||||
:return: True if valid. ValidationError is raised otherwise.
|
||||
"""
|
||||
if BibleImport.is_compressed(filename):
|
||||
raise ValidationError(msg='Compressed file')
|
||||
bible = self.parse_xml(filename, use_objectify=True)
|
||||
if bible is None:
|
||||
raise ValidationError(msg='Error when opening file')
|
||||
root_tag = bible.tag.lower()
|
||||
bible_type = translate('BiblesPlugin.BibleImport', 'unknown type of',
|
||||
'This looks like an unknown type of XML bible.')
|
||||
if root_tag == tag:
|
||||
return True
|
||||
elif root_tag == 'bible':
|
||||
bible_type = "OpenSong"
|
||||
elif root_tag == '{http://www.bibletechnologies.net/2003/osis/namespace}osis':
|
||||
bible_type = 'OSIS'
|
||||
elif root_tag == 'xmlbible':
|
||||
bible_type = 'Zefania'
|
||||
critical_error_message_box(
|
||||
message=translate('BiblesPlugin.BibleImport',
|
||||
'Incorrect Bible file type supplied. This looks like an {bible_type} XML bible.'
|
||||
.format(bible_type=bible_type)))
|
||||
raise ValidationError(msg='Invalid xml.')
|
||||
|
|
|
@ -33,7 +33,7 @@ from sqlalchemy.exc import OperationalError
|
|||
from sqlalchemy.orm import class_mapper, mapper, relation
|
||||
from sqlalchemy.orm.exc import UnmappedClassError
|
||||
|
||||
from openlp.core.common import Registry, RegistryProperties, AppLocation, translate, clean_filename
|
||||
from openlp.core.common import AppLocation, translate, clean_filename
|
||||
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.lib import upgrade
|
||||
|
@ -106,7 +106,7 @@ def init_schema(url):
|
|||
return session
|
||||
|
||||
|
||||
class BibleDB(Manager, RegistryProperties):
|
||||
class BibleDB(Manager):
|
||||
"""
|
||||
This class represents a database-bound Bible. It is used as a base class for all the custom importers, so that
|
||||
the can implement their own import methods, but benefit from the database methods in here via inheritance,
|
||||
|
@ -140,7 +140,6 @@ class BibleDB(Manager, RegistryProperties):
|
|||
raise KeyError('Missing keyword argument "path".')
|
||||
if 'name' not in kwargs and 'file' not in kwargs:
|
||||
raise KeyError('Missing keyword argument "name" or "file".')
|
||||
self.stop_import_flag = False
|
||||
if 'name' in kwargs:
|
||||
self.name = kwargs['name']
|
||||
if not isinstance(self.name, str):
|
||||
|
@ -153,15 +152,6 @@ class BibleDB(Manager, RegistryProperties):
|
|||
self.get_name()
|
||||
if 'path' in kwargs:
|
||||
self.path = kwargs['path']
|
||||
self.wizard = None
|
||||
Registry().register_function('openlp_stop_wizard', self.stop_import)
|
||||
|
||||
def stop_import(self):
|
||||
"""
|
||||
Stops the import of the Bible.
|
||||
"""
|
||||
log.debug('Stopping import')
|
||||
self.stop_import_flag = True
|
||||
|
||||
def get_name(self):
|
||||
"""
|
||||
|
@ -171,17 +161,6 @@ class BibleDB(Manager, RegistryProperties):
|
|||
self.name = version_name.value if version_name else None
|
||||
return self.name
|
||||
|
||||
def register(self, wizard):
|
||||
"""
|
||||
This method basically just initialises the database. It is called from the Bible Manager when a Bible is
|
||||
imported. Descendant classes may want to override this method to supply their own custom
|
||||
initialisation as well.
|
||||
|
||||
:param wizard: The actual Qt wizard form.
|
||||
"""
|
||||
self.wizard = wizard
|
||||
return self.name
|
||||
|
||||
def create_book(self, name, bk_ref_id, testament=1):
|
||||
"""
|
||||
Add a book to the database.
|
||||
|
@ -306,26 +285,6 @@ class BibleDB(Manager, RegistryProperties):
|
|||
log.debug('BibleDB.get_book_by_book_ref_id("{ref}")'.format(ref=ref_id))
|
||||
return self.get_object_filtered(Book, Book.book_reference_id.like(ref_id))
|
||||
|
||||
def get_book_ref_id_by_name(self, book, maxbooks, language_id=None):
|
||||
log.debug('BibleDB.get_book_ref_id_by_name:("{book}", "{lang}")'.format(book=book, lang=language_id))
|
||||
book_id = None
|
||||
if BiblesResourcesDB.get_book(book, True):
|
||||
book_temp = BiblesResourcesDB.get_book(book, True)
|
||||
book_id = book_temp['id']
|
||||
elif BiblesResourcesDB.get_alternative_book_name(book):
|
||||
book_id = BiblesResourcesDB.get_alternative_book_name(book)
|
||||
elif AlternativeBookNamesDB.get_book_reference_id(book):
|
||||
book_id = AlternativeBookNamesDB.get_book_reference_id(book)
|
||||
else:
|
||||
from openlp.plugins.bibles.forms import BookNameForm
|
||||
book_name = BookNameForm(self.wizard)
|
||||
if book_name.exec(book, self.get_books(), maxbooks):
|
||||
book_id = book_name.book_id
|
||||
if book_id:
|
||||
AlternativeBookNamesDB.create_alternative_book_name(
|
||||
book, book_id, language_id)
|
||||
return book_id
|
||||
|
||||
def get_book_ref_id_by_localised_name(self, book, language_selection):
|
||||
"""
|
||||
Return the id of a named book.
|
||||
|
@ -462,25 +421,6 @@ class BibleDB(Manager, RegistryProperties):
|
|||
return 0
|
||||
return count
|
||||
|
||||
def get_language(self, bible_name=None):
|
||||
"""
|
||||
If no language is given it calls a dialog window where the user could select the bible language.
|
||||
Return the language id of a bible.
|
||||
|
||||
:param bible_name: The language the bible is.
|
||||
"""
|
||||
log.debug('BibleDB.get_language()')
|
||||
from openlp.plugins.bibles.forms import LanguageForm
|
||||
language_id = None
|
||||
language_form = LanguageForm(self.wizard)
|
||||
if language_form.exec(bible_name):
|
||||
combo_box = language_form.language_combo_box
|
||||
language_id = combo_box.itemData(combo_box.currentIndex())
|
||||
if not language_id:
|
||||
return None
|
||||
self.save_meta('language_id', language_id)
|
||||
return language_id
|
||||
|
||||
def dump_bible(self):
|
||||
"""
|
||||
Utility debugging method to dump the contents of a bible.
|
||||
|
|
|
@ -50,7 +50,6 @@ There are two acceptable formats of the verses file. They are:
|
|||
All CSV files are expected to use a comma (',') as the delimiter and double quotes ('"') as the quote symbol.
|
||||
"""
|
||||
import csv
|
||||
import logging
|
||||
from collections import namedtuple
|
||||
|
||||
from openlp.core.common import get_file_encoding, translate
|
||||
|
@ -58,8 +57,6 @@ from openlp.core.lib.exceptions import ValidationError
|
|||
from openlp.plugins.bibles.lib.bibleimport import BibleImport
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
Book = namedtuple('Book', 'id, testament_id, name, abbreviation')
|
||||
Verse = namedtuple('Verse', 'book_id_name, chapter_number, number, text')
|
||||
|
||||
|
@ -68,15 +65,13 @@ class CSVBible(BibleImport):
|
|||
"""
|
||||
This class provides a specialisation for importing of CSV Bibles.
|
||||
"""
|
||||
log.info('CSVBible loaded')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Loads a Bible from a set of CSV files. This class assumes the files contain all the information and a clean
|
||||
bible is being loaded.
|
||||
"""
|
||||
log.info(self.__class__.__name__)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.log_info(self.__class__.__name__)
|
||||
self.books_file = kwargs['booksfile']
|
||||
self.verses_file = kwargs['versefile']
|
||||
|
||||
|
@ -123,12 +118,11 @@ class CSVBible(BibleImport):
|
|||
number_of_books = len(books)
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
return None
|
||||
break
|
||||
self.wizard.increment_progress_bar(
|
||||
translate('BiblesPlugin.CSVBible', 'Importing books... {book}').format(book=book.name))
|
||||
self.find_and_create_book(book.name, number_of_books, self.language_id)
|
||||
book_list.update({int(book.id): book.name})
|
||||
self.application.process_events()
|
||||
return book_list
|
||||
|
||||
def process_verses(self, verses, books):
|
||||
|
@ -142,7 +136,7 @@ class CSVBible(BibleImport):
|
|||
book_ptr = None
|
||||
for verse in verses:
|
||||
if self.stop_import_flag:
|
||||
return None
|
||||
break
|
||||
verse_book = self.get_book_name(verse.book_id_name, books)
|
||||
if book_ptr != verse_book:
|
||||
book = self.get_book(verse_book)
|
||||
|
@ -151,9 +145,7 @@ class CSVBible(BibleImport):
|
|||
translate('BiblesPlugin.CSVBible', 'Importing verses from {book}...',
|
||||
'Importing verses from <book name>...').format(book=book.name))
|
||||
self.session.commit()
|
||||
self.create_verse(book.id, verse.chapter_number, verse.number, verse.text)
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing verses... done.'))
|
||||
self.application.process_events()
|
||||
self.create_verse(book.id, int(verse.chapter_number), int(verse.number), verse.text)
|
||||
self.session.commit()
|
||||
|
||||
def do_import(self, bible_name=None):
|
||||
|
@ -163,24 +155,16 @@ class CSVBible(BibleImport):
|
|||
:param bible_name: Optional name of the bible being imported. Str or None
|
||||
:return: True if the import was successful, False if it failed or was cancelled
|
||||
"""
|
||||
try:
|
||||
self.language_id = self.get_language(bible_name)
|
||||
if not self.language_id:
|
||||
raise ValidationError(msg='Invalid language selected')
|
||||
books = self.parse_csv_file(self.books_file, Book)
|
||||
self.wizard.progress_bar.setValue(0)
|
||||
self.wizard.progress_bar.setMinimum(0)
|
||||
self.wizard.progress_bar.setMaximum(len(books))
|
||||
book_list = self.process_books(books)
|
||||
if self.stop_import_flag:
|
||||
return False
|
||||
verses = self.parse_csv_file(self.verses_file, Verse)
|
||||
self.wizard.progress_bar.setValue(0)
|
||||
self.wizard.progress_bar.setMaximum(len(books) + 1)
|
||||
self.process_verses(verses, book_list)
|
||||
if self.stop_import_flag:
|
||||
return False
|
||||
except ValidationError:
|
||||
log.exception('Could not import CSV bible')
|
||||
self.language_id = self.get_language(bible_name)
|
||||
if not self.language_id:
|
||||
return False
|
||||
books = self.parse_csv_file(self.books_file, Book)
|
||||
self.wizard.progress_bar.setValue(0)
|
||||
self.wizard.progress_bar.setMinimum(0)
|
||||
self.wizard.progress_bar.setMaximum(len(books))
|
||||
book_list = self.process_books(books)
|
||||
verses = self.parse_csv_file(self.verses_file, Verse)
|
||||
self.wizard.progress_bar.setValue(0)
|
||||
self.wizard.progress_bar.setMaximum(len(books) + 1)
|
||||
self.process_verses(verses, book_list)
|
||||
return True
|
||||
|
|
|
@ -493,7 +493,7 @@ class CWExtract(RegistryProperties):
|
|||
for verse in verses_div:
|
||||
self.application.process_events()
|
||||
verse_number = int(verse.find('strong').contents[0])
|
||||
verse_span = verse.find('span')
|
||||
verse_span = verse.find('span', class_='verse-%d' % verse_number)
|
||||
tags_to_remove = verse_span.find_all(['a', 'sup'])
|
||||
for tag in tags_to_remove:
|
||||
tag.decompose()
|
||||
|
|
|
@ -20,109 +20,126 @@
|
|||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
import logging
|
||||
from lxml import etree, objectify
|
||||
|
||||
from openlp.core.common import translate, trace_error_handler
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.lib.bibleimport import BibleImport
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
def get_text(element):
|
||||
"""
|
||||
Recursively get all text in an objectify element and its child elements.
|
||||
|
||||
:param element: An objectify element to get the text from
|
||||
:return: The text content of the element (str)
|
||||
"""
|
||||
verse_text = ''
|
||||
if element.text:
|
||||
verse_text = element.text
|
||||
for sub_element in element.iterchildren():
|
||||
verse_text += get_text(sub_element)
|
||||
if element.tail:
|
||||
verse_text += element.tail
|
||||
return verse_text
|
||||
|
||||
|
||||
def parse_chapter_number(number, previous_number):
|
||||
"""
|
||||
Parse the chapter number
|
||||
|
||||
:param number: The raw data from the xml
|
||||
:param previous_number: The previous chapter number
|
||||
:return: Number of current chapter. (Int)
|
||||
"""
|
||||
if number:
|
||||
return int(number.split()[-1])
|
||||
return previous_number + 1
|
||||
|
||||
|
||||
class OpenSongBible(BibleImport):
|
||||
"""
|
||||
OpenSong Bible format importer class. This class is used to import Bibles from OpenSong's XML format.
|
||||
"""
|
||||
def get_text(self, element):
|
||||
"""
|
||||
Recursively get all text in an objectify element and its child elements.
|
||||
|
||||
:param element: An objectify element to get the text from
|
||||
def parse_verse_number(self, number, previous_number):
|
||||
"""
|
||||
verse_text = ''
|
||||
if element.text:
|
||||
verse_text = element.text
|
||||
for sub_element in element.iterchildren():
|
||||
verse_text += self.get_text(sub_element)
|
||||
if element.tail:
|
||||
verse_text += element.tail
|
||||
return verse_text
|
||||
Parse the verse number retrieved from the xml
|
||||
|
||||
:param number: The raw data from the xml
|
||||
:param previous_number: The previous verse number
|
||||
:return: Number of current verse. (Int)
|
||||
"""
|
||||
if not number:
|
||||
return previous_number + 1
|
||||
try:
|
||||
return int(number)
|
||||
except ValueError:
|
||||
verse_parts = number.split('-')
|
||||
if len(verse_parts) > 1:
|
||||
number = int(verse_parts[0])
|
||||
return number
|
||||
except TypeError:
|
||||
self.log_warning('Illegal verse number: {verse_no}'.format(verse_no=str(number)))
|
||||
return previous_number + 1
|
||||
|
||||
def process_books(self, books):
|
||||
"""
|
||||
Extract and create the books from the objectified xml
|
||||
|
||||
:param books: Objectified xml
|
||||
:return: None
|
||||
"""
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
db_book = self.find_and_create_book(str(book.attrib['n']), len(books), self.language_id)
|
||||
self.process_chapters(db_book, book.c)
|
||||
self.session.commit()
|
||||
|
||||
def process_chapters(self, book, chapters):
|
||||
"""
|
||||
Extract and create the chapters from the objectified xml for the book `book`
|
||||
|
||||
:param book: A database Book object to add the chapters to
|
||||
:param chapters: Objectified xml containing chapters
|
||||
:return: None
|
||||
"""
|
||||
chapter_number = 0
|
||||
for chapter in chapters:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
chapter_number = parse_chapter_number(chapter.attrib['n'], chapter_number)
|
||||
self.set_current_chapter(book.name, chapter_number)
|
||||
self.process_verses(book, chapter_number, chapter.v)
|
||||
|
||||
def process_verses(self, book, chapter_number, verses):
|
||||
"""
|
||||
Extract and create the verses from the objectified xml
|
||||
|
||||
:param book: A database Book object
|
||||
:param chapter_number: The chapter number to add the verses to (int)
|
||||
:param verses: Objectified xml containing verses
|
||||
:return: None
|
||||
"""
|
||||
verse_number = 0
|
||||
for verse in verses:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
verse_number = self.parse_verse_number(verse.attrib['n'], verse_number)
|
||||
self.create_verse(book.id, chapter_number, verse_number, get_text(verse))
|
||||
|
||||
def do_import(self, bible_name=None):
|
||||
"""
|
||||
Loads a Bible from file.
|
||||
Loads an Open Song Bible from a file.
|
||||
|
||||
:param bible_name: The name of the bible being imported
|
||||
:return: True if import completed, False if import was unsuccessful
|
||||
"""
|
||||
log.debug('Starting OpenSong import from "{name}"'.format(name=self.filename))
|
||||
success = True
|
||||
try:
|
||||
bible = self.parse_xml(self.filename, use_objectify=True)
|
||||
# Check that we're not trying to import a Zefania XML bible, it is sometimes refered to as 'OpenSong'
|
||||
if bible.tag.upper() == 'XMLBIBLE':
|
||||
critical_error_message_box(
|
||||
message=translate('BiblesPlugin.OpenSongImport',
|
||||
'Incorrect Bible file type supplied. This looks like a Zefania XML bible, '
|
||||
'please use the Zefania import option.'))
|
||||
return False
|
||||
# No language info in the opensong format, so ask the user
|
||||
language_id = self.get_language_id(bible_name=self.filename)
|
||||
if not language_id:
|
||||
return False
|
||||
for book in bible.b:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
book_ref_id = self.get_book_ref_id_by_name(str(book.attrib['n']), len(bible.b), language_id)
|
||||
if not book_ref_id:
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.filename))
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.create_book(book.attrib['n'], book_ref_id, book_details['testament_id'])
|
||||
chapter_number = 0
|
||||
for chapter in book.c:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
number = chapter.attrib['n']
|
||||
if number:
|
||||
chapter_number = int(number.split()[-1])
|
||||
else:
|
||||
chapter_number += 1
|
||||
verse_number = 0
|
||||
for verse in chapter.v:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
number = verse.attrib['n']
|
||||
if number:
|
||||
try:
|
||||
number = int(number)
|
||||
except ValueError:
|
||||
verse_parts = number.split('-')
|
||||
if len(verse_parts) > 1:
|
||||
number = int(verse_parts[0])
|
||||
except TypeError:
|
||||
log.warning('Illegal verse number: {verse:d}'.format(verse=verse.attrib['n']))
|
||||
verse_number = number
|
||||
else:
|
||||
verse_number += 1
|
||||
self.create_verse(db_book.id, chapter_number, verse_number, self.get_text(verse))
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.Opensong',
|
||||
'Importing {name} {chapter}...'
|
||||
).format(name=db_book.name, chapter=chapter_number))
|
||||
self.session.commit()
|
||||
self.application.process_events()
|
||||
except etree.XMLSyntaxError as inst:
|
||||
trace_error_handler(log)
|
||||
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('Loading Bible from OpenSong file failed')
|
||||
success = False
|
||||
if self.stop_import_flag:
|
||||
self.log_debug('Starting OpenSong import from "{name}"'.format(name=self.filename))
|
||||
self.validate_xml_file(self.filename, 'bible')
|
||||
bible = self.parse_xml(self.filename, use_objectify=True)
|
||||
if bible is None:
|
||||
return False
|
||||
else:
|
||||
return success
|
||||
# No language info in the opensong format, so ask the user
|
||||
self.language_id = self.get_language_id(bible_name=self.filename)
|
||||
if not self.language_id:
|
||||
return False
|
||||
self.process_books(bible.b)
|
||||
return True
|
||||
|
|
|
@ -20,15 +20,9 @@
|
|||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
import logging
|
||||
from lxml import etree
|
||||
|
||||
from openlp.core.common import translate, trace_error_handler
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.lib.bibleimport import BibleImport
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
NS = {'ns': 'http://www.bibletechnologies.net/2003/OSIS/namespace'}
|
||||
# Tags we don't use and can remove the content
|
||||
|
@ -74,104 +68,106 @@ REMOVABLE_TAGS = (
|
|||
'{http://www.bibletechnologies.net/2003/OSIS/namespace}caption'
|
||||
)
|
||||
|
||||
|
||||
def replacement(match):
|
||||
return match.group(2).upper()
|
||||
# Precompile a few xpath-querys
|
||||
verse_in_chapter = etree.XPath('//ns:chapter[1]/ns:verse', namespaces=NS)
|
||||
text_in_verse = etree.XPath('//ns:verse[1]/text()', namespaces=NS)
|
||||
|
||||
|
||||
class OSISBible(BibleImport):
|
||||
"""
|
||||
`OSIS <http://www.bibletechnologies.net/>`_ Bible format importer class.
|
||||
"""
|
||||
def process_books(self, bible_data):
|
||||
"""
|
||||
Extract and create the bible books from the parsed xml
|
||||
|
||||
:param bible_data: parsed xml
|
||||
:return: None
|
||||
"""
|
||||
# Find books in the bible
|
||||
bible_books = bible_data.xpath("//ns:div[@type='book']", namespaces=NS)
|
||||
no_of_books = len(bible_books)
|
||||
for book in bible_books:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
# Remove div-tags in the book
|
||||
etree.strip_tags(book, '{http://www.bibletechnologies.net/2003/OSIS/namespace}div')
|
||||
db_book = self.find_and_create_book(book.get('osisID'), no_of_books, self.language_id)
|
||||
self.process_chapters(db_book, book)
|
||||
self.session.commit()
|
||||
|
||||
def process_chapters(self, book, chapters):
|
||||
"""
|
||||
Extract the chapters, and do some initial processing of the verses
|
||||
|
||||
:param book: An OpenLP bible database book object
|
||||
:param chapters: parsed chapters
|
||||
:return: None
|
||||
"""
|
||||
# Find out if chapter-tags contains the verses, or if it is used as milestone/anchor
|
||||
if verse_in_chapter(chapters):
|
||||
# The chapter tags contains the verses
|
||||
for chapter in chapters:
|
||||
chapter_number = int(chapter.get("osisID").split('.')[1])
|
||||
self.set_current_chapter(book.name, chapter_number)
|
||||
# Find out if verse-tags contains the text, or if it is used as milestone/anchor
|
||||
if not text_in_verse(chapter):
|
||||
# verse-tags are used as milestone
|
||||
for verse in chapter:
|
||||
# If this tag marks the start of a verse, the verse text is between this tag and
|
||||
# the next tag, which the "tail" attribute gives us.
|
||||
self.process_verse(book, chapter_number, verse, use_milestones=True)
|
||||
else:
|
||||
# Verse-tags contains the text
|
||||
for verse in chapter:
|
||||
self.process_verse(book, chapter_number, verse)
|
||||
else:
|
||||
# The chapter tags is used as milestones. For now we assume verses is also milestones
|
||||
chapter_number = 0
|
||||
for element in chapters:
|
||||
if element.tag == '{http://www.bibletechnologies.net/2003/OSIS/namespace}chapter' \
|
||||
and element.get('sID'):
|
||||
chapter_number = int(element.get("osisID").split('.')[1])
|
||||
self.set_current_chapter(book.name, chapter_number)
|
||||
elif element.tag == '{http://www.bibletechnologies.net/2003/OSIS/namespace}verse':
|
||||
# If this tag marks the start of a verse, the verse text is between this tag and
|
||||
# the next tag, which the "tail" attribute gives us.
|
||||
self.process_verse(book, chapter_number, element, use_milestones=True)
|
||||
|
||||
def process_verse(self, book, chapter_number, element, use_milestones=False):
|
||||
"""
|
||||
Process a verse element
|
||||
:param book: A database Book object
|
||||
:param chapter_number: The chapter number to add the verses to (int)
|
||||
:param element: The verse element to process. (etree element type)
|
||||
:param use_milestones: set to True to process a 'milestone' verse. Defaults to False
|
||||
:return: None
|
||||
"""
|
||||
osis_id = element.get("osisID")
|
||||
if not osis_id:
|
||||
return None
|
||||
verse_number = int(osis_id.split('.')[2])
|
||||
verse_text = ''
|
||||
if use_milestones and element.get('sID'):
|
||||
verse_text = element.tail
|
||||
elif not use_milestones:
|
||||
verse_text = element.text
|
||||
if verse_text:
|
||||
self.create_verse(book.id, chapter_number, verse_number, verse_text.strip())
|
||||
|
||||
def do_import(self, bible_name=None):
|
||||
"""
|
||||
Loads a Bible from file.
|
||||
"""
|
||||
log.debug('Starting OSIS import from "{name}"'.format(name=self.filename))
|
||||
success = True
|
||||
try:
|
||||
self.wizard.increment_progress_bar(translate('BiblesPlugin.OsisImport',
|
||||
'Removing unused tags (this may take a few minutes)...'))
|
||||
osis_bible_tree = self.parse_xml(self.filename, elements=REMOVABLE_ELEMENTS, tags=REMOVABLE_TAGS)
|
||||
# Find bible language]
|
||||
language = osis_bible_tree.xpath("//ns:osisText/@xml:lang", namespaces=NS)
|
||||
language_id = self.get_language_id(language[0] if language else None, bible_name=self.filename)
|
||||
if not language_id:
|
||||
return False
|
||||
num_books = int(osis_bible_tree.xpath("count(//ns:div[@type='book'])", namespaces=NS))
|
||||
# Precompile a few xpath-querys
|
||||
verse_in_chapter = etree.XPath('count(//ns:chapter[1]/ns:verse)', namespaces=NS)
|
||||
text_in_verse = etree.XPath('count(//ns:verse[1]/text())', namespaces=NS)
|
||||
# Find books in the bible
|
||||
bible_books = osis_bible_tree.xpath("//ns:div[@type='book']", namespaces=NS)
|
||||
for book in bible_books:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
# Remove div-tags in the book
|
||||
etree.strip_tags(book, ('{http://www.bibletechnologies.net/2003/OSIS/namespace}div'))
|
||||
book_ref_id = self.get_book_ref_id_by_name(book.get('osisID'), num_books, language_id)
|
||||
if not book_ref_id:
|
||||
log.error('Importing books from "{name}" failed'.format(name=self.filename))
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.create_book(book_details['name'], book_ref_id, book_details['testament_id'])
|
||||
# Find out if chapter-tags contains the verses, or if it is used as milestone/anchor
|
||||
if int(verse_in_chapter(book)) > 0:
|
||||
# The chapter tags contains the verses
|
||||
for chapter in book:
|
||||
chapter_number = chapter.get("osisID").split('.')[1]
|
||||
# Find out if verse-tags contains the text, or if it is used as milestone/anchor
|
||||
if int(text_in_verse(chapter)) == 0:
|
||||
# verse-tags are used as milestone
|
||||
for verse in chapter:
|
||||
# If this tag marks the start of a verse, the verse text is between this tag and
|
||||
# the next tag, which the "tail" attribute gives us.
|
||||
if verse.get('sID'):
|
||||
verse_number = verse.get("osisID").split('.')[2]
|
||||
verse_text = verse.tail
|
||||
if verse_text:
|
||||
self.create_verse(db_book.id, chapter_number, verse_number, verse_text.strip())
|
||||
else:
|
||||
# Verse-tags contains the text
|
||||
for verse in chapter:
|
||||
verse_number = verse.get("osisID").split('.')[2]
|
||||
if verse.text:
|
||||
self.create_verse(db_book.id, chapter_number, verse_number, verse.text.strip())
|
||||
self.wizard.increment_progress_bar(
|
||||
translate('BiblesPlugin.OsisImport', 'Importing %(bookname)s %(chapter)s...') %
|
||||
{'bookname': db_book.name, 'chapter': chapter_number})
|
||||
else:
|
||||
# The chapter tags is used as milestones. For now we assume verses is also milestones
|
||||
chapter_number = 0
|
||||
for element in book:
|
||||
if element.tag == '{http://www.bibletechnologies.net/2003/OSIS/namespace}chapter' \
|
||||
and element.get('sID'):
|
||||
chapter_number = element.get("osisID").split('.')[1]
|
||||
self.wizard.increment_progress_bar(
|
||||
translate('BiblesPlugin.OsisImport', 'Importing %(bookname)s %(chapter)s...') %
|
||||
{'bookname': db_book.name, 'chapter': chapter_number})
|
||||
elif element.tag == '{http://www.bibletechnologies.net/2003/OSIS/namespace}verse' \
|
||||
and element.get('sID'):
|
||||
# If this tag marks the start of a verse, the verse text is between this tag and
|
||||
# the next tag, which the "tail" attribute gives us.
|
||||
verse_number = element.get("osisID").split('.')[2]
|
||||
verse_text = element.tail
|
||||
if verse_text:
|
||||
self.create_verse(db_book.id, chapter_number, verse_number, verse_text.strip())
|
||||
self.session.commit()
|
||||
self.application.process_events()
|
||||
except (ValueError, IOError):
|
||||
log.exception('Loading bible from OSIS file failed')
|
||||
trace_error_handler(log)
|
||||
success = False
|
||||
except etree.XMLSyntaxError as e:
|
||||
log.exception('Loading bible from OSIS file failed')
|
||||
trace_error_handler(log)
|
||||
success = False
|
||||
critical_error_message_box(message=translate('BiblesPlugin.OsisImport',
|
||||
'The file is not a valid OSIS-XML file:'
|
||||
'\n{text}').format(text=e.msg))
|
||||
if self.stop_import_flag:
|
||||
self.log_debug('Starting OSIS import from "{name}"'.format(name=self.filename))
|
||||
self.validate_xml_file(self.filename, '{http://www.bibletechnologies.net/2003/osis/namespace}osis')
|
||||
bible = self.parse_xml(self.filename, elements=REMOVABLE_ELEMENTS, tags=REMOVABLE_TAGS)
|
||||
if bible is None:
|
||||
return False
|
||||
else:
|
||||
return success
|
||||
# Find bible language
|
||||
language = bible.xpath("//ns:osisText/@xml:lang", namespaces=NS)
|
||||
self.language_id = self.get_language_id(language[0] if language else None, bible_name=self.filename)
|
||||
if not self.language_id:
|
||||
return False
|
||||
self.process_books(bible)
|
||||
return True
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
from codecs import open as copen
|
||||
from tempfile import TemporaryDirectory
|
||||
from zipfile import ZipFile
|
||||
|
||||
from bs4 import BeautifulSoup, Tag, NavigableString
|
||||
|
||||
from openlp.plugins.bibles.lib.bibleimport import BibleImport
|
||||
|
||||
BOOK_NUMBER_PATTERN = re.compile(r'\[(\d+)\]')
|
||||
REPLACE_SPACES = re.compile(r'\s{2,}')
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WordProjectBible(BibleImport):
|
||||
"""
|
||||
`WordProject <http://www.wordproaudio.com/>`_ Bible format importer class.
|
||||
"""
|
||||
def _cleanup(self):
|
||||
"""
|
||||
Clean up after ourselves
|
||||
"""
|
||||
self.tmp.cleanup()
|
||||
|
||||
def _unzip_file(self):
|
||||
"""
|
||||
Unzip the file to a temporary directory
|
||||
"""
|
||||
self.tmp = TemporaryDirectory()
|
||||
zip_file = ZipFile(os.path.abspath(self.filename))
|
||||
zip_file.extractall(self.tmp.name)
|
||||
self.base_dir = os.path.join(self.tmp.name, os.path.splitext(os.path.basename(self.filename))[0])
|
||||
|
||||
def process_books(self):
|
||||
"""
|
||||
Extract and create the bible books from the parsed html
|
||||
|
||||
:param bible_data: parsed xml
|
||||
:return: None
|
||||
"""
|
||||
with copen(os.path.join(self.base_dir, 'index.htm'), encoding='utf-8', errors='ignore') as index_file:
|
||||
page = index_file.read()
|
||||
soup = BeautifulSoup(page, 'lxml')
|
||||
bible_books = soup.find('div', 'textOptions').find_all('li')
|
||||
book_count = len(bible_books)
|
||||
for li_book in bible_books:
|
||||
log.debug(li_book)
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
# Sometimes the structure is "[1] <a>Genesis</a>", and sometimes it's "<a>[1] Genesis</a>"
|
||||
if isinstance(li_book.contents[0], NavigableString) and str(li_book.contents[0]).strip():
|
||||
book_string = str(li_book.contents[0])
|
||||
book_name = str(li_book.a.contents[0])
|
||||
elif li_book.a:
|
||||
book_string, book_name = str(li_book.a.contents[0]).split(' ', 1)
|
||||
book_link = li_book.a['href']
|
||||
book_id = int(BOOK_NUMBER_PATTERN.search(book_string).group(1))
|
||||
book_name = book_name.strip()
|
||||
db_book = self.find_and_create_book(book_name, book_count, self.language_id, book_id)
|
||||
self.process_chapters(db_book, book_id, book_link)
|
||||
self.session.commit()
|
||||
|
||||
def process_chapters(self, db_book, book_id, book_link):
|
||||
"""
|
||||
Extract the chapters, and do some initial processing of the verses
|
||||
|
||||
:param book: An OpenLP bible database book object
|
||||
:param chapters: parsed chapters
|
||||
:return: None
|
||||
"""
|
||||
log.debug(book_link)
|
||||
book_file = os.path.join(self.base_dir, os.path.normpath(book_link))
|
||||
with copen(book_file, encoding='utf-8', errors='ignore') as f:
|
||||
page = f.read()
|
||||
soup = BeautifulSoup(page, 'lxml')
|
||||
header_div = soup.find('div', 'textHeader')
|
||||
chapters_p = header_div.find('p')
|
||||
if not chapters_p:
|
||||
chapters_p = soup.p
|
||||
log.debug(chapters_p)
|
||||
for item in chapters_p.contents:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
if isinstance(item, Tag) and item.name in ['a', 'span']:
|
||||
chapter_number = int(item.string.strip())
|
||||
self.set_current_chapter(db_book.name, chapter_number)
|
||||
self.process_verses(db_book, book_id, chapter_number)
|
||||
|
||||
def process_verses(self, db_book, book_number, chapter_number):
|
||||
"""
|
||||
Get the verses for a particular book
|
||||
"""
|
||||
chapter_file_name = os.path.join(self.base_dir, '{:02d}'.format(book_number), '{}.htm'.format(chapter_number))
|
||||
with copen(chapter_file_name, encoding='utf-8', errors='ignore') as chapter_file:
|
||||
page = chapter_file.read()
|
||||
soup = BeautifulSoup(page, 'lxml')
|
||||
text_body = soup.find('div', 'textBody')
|
||||
if text_body:
|
||||
verses_p = text_body.find('p')
|
||||
else:
|
||||
verses_p = soup.find_all('p')[2]
|
||||
verse_number = 0
|
||||
verse_text = ''
|
||||
for item in verses_p.contents:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
if isinstance(item, Tag) and 'verse' in item.get('class', []):
|
||||
if verse_number > 0:
|
||||
self.process_verse(db_book, chapter_number, verse_number, verse_text.strip())
|
||||
verse_number = int(item.string.strip())
|
||||
verse_text = ''
|
||||
elif isinstance(item, NavigableString):
|
||||
verse_text += str(item)
|
||||
elif isinstance(item, Tag) and item.name in ['span', 'a']:
|
||||
verse_text += str(item.string)
|
||||
else:
|
||||
log.warning('Can\'t store %s', item)
|
||||
self.process_verse(db_book, chapter_number, verse_number, verse_text.strip())
|
||||
|
||||
def process_verse(self, db_book, chapter_number, verse_number, verse_text):
|
||||
"""
|
||||
Process a verse element
|
||||
:param book: A database Book object
|
||||
:param chapter_number: The chapter number to add the verses to (int)
|
||||
:param element: The verse element to process. (etree element type)
|
||||
:param use_milestones: set to True to process a 'milestone' verse. Defaults to False
|
||||
:return: None
|
||||
"""
|
||||
if verse_text:
|
||||
log.debug('%s %s:%s %s', db_book.name, chapter_number, verse_number, verse_text.strip())
|
||||
self.create_verse(db_book.id, chapter_number, verse_number, verse_text.strip())
|
||||
|
||||
def do_import(self, bible_name=None):
|
||||
"""
|
||||
Loads a Bible from file.
|
||||
"""
|
||||
self.log_debug('Starting WordProject import from "{name}"'.format(name=self.filename))
|
||||
self._unzip_file()
|
||||
self.language_id = self.get_language_id(None, bible_name=self.filename)
|
||||
result = False
|
||||
if self.language_id:
|
||||
self.process_books()
|
||||
result = True
|
||||
self._cleanup()
|
||||
return result
|
|
@ -54,7 +54,7 @@ class ZefaniaBible(BibleImport):
|
|||
language_id = self.get_language_id(language[0] if language else None, bible_name=self.filename)
|
||||
if not language_id:
|
||||
return False
|
||||
num_books = int(xmlbible.xpath('count(//BIBLEBOOK)'))
|
||||
no_of_books = int(xmlbible.xpath('count(//BIBLEBOOK)'))
|
||||
self.wizard.progress_bar.setMaximum(int(xmlbible.xpath('count(//CHAPTER)')))
|
||||
for BIBLEBOOK in xmlbible:
|
||||
if self.stop_import_flag:
|
||||
|
@ -64,7 +64,7 @@ class ZefaniaBible(BibleImport):
|
|||
if not bname and not bnumber:
|
||||
continue
|
||||
if bname:
|
||||
book_ref_id = self.get_book_ref_id_by_name(bname, num_books, language_id)
|
||||
book_ref_id = self.get_book_ref_id_by_name(bname, no_of_books, language_id)
|
||||
else:
|
||||
log.debug('Could not find a name, will use number, basically a guess.')
|
||||
book_ref_id = int(bnumber)
|
||||
|
@ -79,7 +79,8 @@ class ZefaniaBible(BibleImport):
|
|||
chapter_number = CHAPTER.get("cnumber")
|
||||
for VERS in CHAPTER:
|
||||
verse_number = VERS.get("vnumber")
|
||||
self.create_verse(db_book.id, chapter_number, verse_number, VERS.text.replace('<BR/>', '\n'))
|
||||
self.create_verse(
|
||||
db_book.id, int(chapter_number), int(verse_number), VERS.text.replace('<BR/>', '\n'))
|
||||
self.wizard.increment_progress_bar(
|
||||
translate('BiblesPlugin.Zefnia',
|
||||
'Importing {book} {chapter}...').format(book=db_book.name,
|
||||
|
|
|
@ -23,14 +23,15 @@
|
|||
import logging
|
||||
import os
|
||||
|
||||
from openlp.core.common import RegistryProperties, AppLocation, Settings, translate, delete_file, UiStrings
|
||||
from openlp.plugins.bibles.lib import parse_reference, LanguageSelection
|
||||
from openlp.core.common import AppLocation, OpenLPMixin, RegistryProperties, Settings, translate, delete_file, UiStrings
|
||||
from openlp.plugins.bibles.lib import LanguageSelection, parse_reference
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
|
||||
from .importers.csvbible import CSVBible
|
||||
from .importers.http import HTTPBible
|
||||
from .importers.opensong import OpenSongBible
|
||||
from .importers.osis import OSISBible
|
||||
from .importers.zefania import ZefaniaBible
|
||||
from .importers.wordproject import WordProjectBible
|
||||
try:
|
||||
from .importers.sword import SwordBible
|
||||
except:
|
||||
|
@ -50,6 +51,7 @@ class BibleFormat(object):
|
|||
WebDownload = 3
|
||||
Zefania = 4
|
||||
SWORD = 5
|
||||
WordProject = 6
|
||||
|
||||
@staticmethod
|
||||
def get_class(bible_format):
|
||||
|
@ -70,6 +72,8 @@ class BibleFormat(object):
|
|||
return ZefaniaBible
|
||||
elif bible_format == BibleFormat.SWORD:
|
||||
return SwordBible
|
||||
elif bible_format == BibleFormat.WordProject:
|
||||
return WordProjectBible
|
||||
else:
|
||||
return None
|
||||
|
||||
|
@ -84,11 +88,12 @@ class BibleFormat(object):
|
|||
BibleFormat.OpenSong,
|
||||
BibleFormat.WebDownload,
|
||||
BibleFormat.Zefania,
|
||||
BibleFormat.SWORD
|
||||
BibleFormat.SWORD,
|
||||
BibleFormat.WordProject
|
||||
]
|
||||
|
||||
|
||||
class BibleManager(RegistryProperties):
|
||||
class BibleManager(OpenLPMixin, RegistryProperties):
|
||||
"""
|
||||
The Bible manager which holds and manages all the Bibles.
|
||||
"""
|
||||
|
@ -131,7 +136,7 @@ class BibleManager(RegistryProperties):
|
|||
name = bible.get_name()
|
||||
# Remove corrupted files.
|
||||
if name is None:
|
||||
bible.session.close()
|
||||
bible.session.close_all()
|
||||
delete_file(os.path.join(self.path, filename))
|
||||
continue
|
||||
log.debug('Bible Name: "{name}"'.format(name=name))
|
||||
|
@ -178,7 +183,7 @@ class BibleManager(RegistryProperties):
|
|||
"""
|
||||
log.debug('BibleManager.delete_bible("{name}")'.format(name=name))
|
||||
bible = self.db_cache[name]
|
||||
bible.session.close()
|
||||
bible.session.close_all()
|
||||
bible.session = None
|
||||
return delete_file(os.path.join(bible.path, bible.file))
|
||||
|
||||
|
@ -367,7 +372,6 @@ class BibleManager(RegistryProperties):
|
|||
second_web_bible = self.db_cache[second_bible].get_object(BibleMeta, 'download_source')
|
||||
if web_bible or second_web_bible:
|
||||
# If either Bible is Web, cursor is reset to normal and search ends w/o any message.
|
||||
self.check_search_result()
|
||||
self.application.set_normal_cursor()
|
||||
return None
|
||||
# Fetch the results from db. If no results are found, return None, no message is given for this.
|
||||
|
|
|
@ -75,21 +75,16 @@ class BibleMediaItem(MediaManagerItem):
|
|||
self.has_search = True
|
||||
self.search_results = {}
|
||||
self.second_search_results = {}
|
||||
self.check_search_result()
|
||||
Registry().register_function('bibles_load_list', self.reload_bibles)
|
||||
|
||||
def __check_second_bible(self, bible, second_bible):
|
||||
"""
|
||||
Check if the first item is a second bible item or not.
|
||||
"""
|
||||
bitem = self.list_view.item(0)
|
||||
if not bitem.flags() & QtCore.Qt.ItemIsSelectable:
|
||||
# The item is the "No Search Results" item.
|
||||
self.list_view.clear()
|
||||
if not self.list_view.count():
|
||||
self.display_results(bible, second_bible)
|
||||
return
|
||||
else:
|
||||
item_second_bible = self._decode_qt_object(bitem, 'second_bible')
|
||||
item_second_bible = self._decode_qt_object(self.list_view.item(0), 'second_bible')
|
||||
if item_second_bible and second_bible or not item_second_bible and not second_bible:
|
||||
self.display_results(bible, second_bible)
|
||||
elif critical_error_message_box(
|
||||
|
@ -199,7 +194,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
self.quick_search_label = QtWidgets.QLabel(self.quickTab)
|
||||
self.quick_search_label.setObjectName('quick_search_label')
|
||||
self.quickLayout.addWidget(self.quick_search_label, 0, 0, QtCore.Qt.AlignRight)
|
||||
self.quick_search_edit = SearchEdit(self.quickTab)
|
||||
self.quick_search_edit = SearchEdit(self.quickTab, self.settings_section)
|
||||
self.quick_search_edit.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Fixed)
|
||||
self.quick_search_edit.setObjectName('quick_search_edit')
|
||||
self.quick_search_label.setBuddy(self.quick_search_edit)
|
||||
|
@ -254,8 +249,8 @@ class BibleMediaItem(MediaManagerItem):
|
|||
self.quickStyleComboBox.activated.connect(self.on_quick_style_combo_box_changed)
|
||||
self.advancedStyleComboBox.activated.connect(self.on_advanced_style_combo_box_changed)
|
||||
# Buttons
|
||||
self.advancedClearButton.clicked.connect(self.on_clear_button)
|
||||
self.quickClearButton.clicked.connect(self.on_clear_button)
|
||||
self.advancedClearButton.clicked.connect(self.on_advanced_clear_button_clicked)
|
||||
self.quickClearButton.clicked.connect(self.on_clear_button_clicked)
|
||||
self.advancedSearchButton.clicked.connect(self.on_advanced_search_button)
|
||||
self.quickSearchButton.clicked.connect(self.on_quick_search_button)
|
||||
# Other stuff
|
||||
|
@ -333,8 +328,8 @@ class BibleMediaItem(MediaManagerItem):
|
|||
translate('BiblesPlugin.MediaItem', 'Text Search'),
|
||||
translate('BiblesPlugin.MediaItem', 'Search Text...'))
|
||||
])
|
||||
text = self.settings_section
|
||||
self.quick_search_edit.set_current_search_type(Settings().value('{text}/last search type'.format(text=text)))
|
||||
if Settings().value(self.settings_section + '/reset to combined quick search'):
|
||||
self.quick_search_edit.set_current_search_type(BibleSearch.Combined)
|
||||
self.config_update()
|
||||
log.debug('bible manager initialise complete')
|
||||
|
||||
|
@ -430,6 +425,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
verse_count = self.plugin.manager.get_verse_count_by_book_ref_id(bible, book_ref_id, 1)
|
||||
if verse_count == 0:
|
||||
self.advancedSearchButton.setEnabled(False)
|
||||
log.warning('Not enough chapters in %s', book_ref_id)
|
||||
critical_error_message_box(message=translate('BiblesPlugin.MediaItem', 'Bible not fully loaded.'))
|
||||
else:
|
||||
self.advancedSearchButton.setEnabled(True)
|
||||
|
@ -444,15 +440,6 @@ class BibleMediaItem(MediaManagerItem):
|
|||
only updated when we are doing reference or combined search, in text search the completion list is removed.
|
||||
"""
|
||||
log.debug('update_auto_completer')
|
||||
# Save the current search type to the configuration. If setting for automatically resetting the search type to
|
||||
# Combined is enabled, use that otherwise use the currently selected search type.
|
||||
# Note: This setting requires a restart to take effect.
|
||||
if Settings().value(self.settings_section + '/reset to combined quick search'):
|
||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||
BibleSearch.Combined)
|
||||
else:
|
||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||
self.quick_search_edit.current_search_type())
|
||||
# Save the current bible to the configuration.
|
||||
Settings().setValue('{section}/quick bible'.format(section=self.settings_section),
|
||||
self.quickVersionComboBox.currentText())
|
||||
|
@ -548,19 +535,29 @@ class BibleMediaItem(MediaManagerItem):
|
|||
self.advancedTab.setVisible(True)
|
||||
self.advanced_book_combo_box.setFocus()
|
||||
|
||||
def on_clear_button(self):
|
||||
def on_clear_button_clicked(self):
|
||||
# Clear the list, then set the "No search Results" message, then clear the text field and give it focus.
|
||||
self.list_view.clear()
|
||||
self.check_search_result()
|
||||
self.quick_search_edit.clear()
|
||||
self.quick_search_edit.setFocus()
|
||||
|
||||
def on_advanced_clear_button_clicked(self):
|
||||
# The same as the on_clear_button_clicked, but gives focus to Book name field in "Select" (advanced).
|
||||
self.list_view.clear()
|
||||
self.advanced_book_combo_box.setFocus()
|
||||
|
||||
def on_lock_button_toggled(self, checked):
|
||||
self.quick_search_edit.setFocus()
|
||||
"""
|
||||
Toggle the lock button, if Search tab is used, set focus to search field.
|
||||
:param checked: The state of the toggle button. bool
|
||||
:return: None
|
||||
"""
|
||||
if checked:
|
||||
self.sender().setIcon(self.lock_icon)
|
||||
else:
|
||||
self.sender().setIcon(self.unlock_icon)
|
||||
if self.quickTab.isVisible():
|
||||
self.quick_search_edit.setFocus()
|
||||
|
||||
def on_quick_style_combo_box_changed(self):
|
||||
self.settings.layout_style = self.quickStyleComboBox.currentIndex()
|
||||
|
@ -680,7 +677,6 @@ class BibleMediaItem(MediaManagerItem):
|
|||
elif self.search_results:
|
||||
self.display_results(bible, second_bible)
|
||||
self.advancedSearchButton.setEnabled(True)
|
||||
self.check_search_result()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def on_quick_reference_search(self):
|
||||
|
@ -874,7 +870,6 @@ class BibleMediaItem(MediaManagerItem):
|
|||
elif self.search_results:
|
||||
self.display_results(bible, second_bible)
|
||||
self.quickSearchButton.setEnabled(True)
|
||||
self.check_search_result()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def on_quick_search_while_typing(self):
|
||||
|
@ -905,7 +900,6 @@ class BibleMediaItem(MediaManagerItem):
|
|||
self.__check_second_bible(bible, second_bible)
|
||||
elif self.search_results:
|
||||
self.display_results(bible, second_bible)
|
||||
self.check_search_result()
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def on_search_text_edit_changed(self):
|
||||
|
@ -944,17 +938,13 @@ class BibleMediaItem(MediaManagerItem):
|
|||
if len(text) == 0:
|
||||
if not self.quickLockButton.isChecked():
|
||||
self.list_view.clear()
|
||||
self.check_search_result()
|
||||
else:
|
||||
if limit == 3 and (len(text) < limit or len(count_space_digit_reference) == 0):
|
||||
if not self.quickLockButton.isChecked():
|
||||
self.list_view.clear()
|
||||
self.check_search_result()
|
||||
elif (limit == 8 and (len(text) < limit or len(count_spaces_two_chars_text) == 0 or
|
||||
len(count_two_chars_text) < 2)):
|
||||
elif limit == 8 and (len(text) < limit or len(count_two_chars_text) < 2):
|
||||
if not self.quickLockButton.isChecked():
|
||||
self.list_view.clear()
|
||||
self.check_search_result_search_while_typing_short()
|
||||
self.list_view.clear(search_while_typing=True)
|
||||
else:
|
||||
"""
|
||||
Start search if no chars are entered or deleted for 0.2 s
|
||||
|
|
|
@ -24,8 +24,6 @@ The :mod:`upgrade` module provides a way for the database and schema that is the
|
|||
"""
|
||||
import logging
|
||||
|
||||
from sqlalchemy import delete, func, insert, select
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
__version__ = 1
|
||||
|
||||
|
@ -35,166 +33,6 @@ def upgrade_1(session, metadata):
|
|||
"""
|
||||
Version 1 upgrade.
|
||||
|
||||
This upgrade renames a number of keys to a single naming convention.
|
||||
This upgrade renamed a number of keys to a single naming convention.
|
||||
"""
|
||||
metadata_table = metadata.tables['metadata']
|
||||
# Copy "Version" to "name" ("version" used by upgrade system)
|
||||
try:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='name',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == 'Version'
|
||||
).as_scalar()
|
||||
))
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'Version'))
|
||||
except:
|
||||
log.exception('Exception when upgrading Version')
|
||||
# Copy "Copyright" to "copyright"
|
||||
try:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='copyright',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == 'Copyright'
|
||||
).as_scalar()
|
||||
))
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'Copyright'))
|
||||
except:
|
||||
log.exception('Exception when upgrading Copyright')
|
||||
# Copy "Permissions" to "permissions"
|
||||
try:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='permissions',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == 'Permissions'
|
||||
).as_scalar()
|
||||
))
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'Permissions'))
|
||||
except:
|
||||
log.exception('Exception when upgrading Permissions')
|
||||
# Copy "Bookname language" to "book_name_language"
|
||||
try:
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == 'Bookname language'
|
||||
)
|
||||
).scalar()
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='book_name_language',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == 'Bookname language'
|
||||
).as_scalar()
|
||||
))
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'Bookname language'))
|
||||
except:
|
||||
log.exception('Exception when upgrading Bookname language')
|
||||
# Copy "download source" to "download_source"
|
||||
try:
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == 'download source'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('download source: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='download_source',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == 'download source'
|
||||
).as_scalar()
|
||||
))
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'download source'))
|
||||
except:
|
||||
log.exception('Exception when upgrading download source')
|
||||
# Copy "download name" to "download_name"
|
||||
try:
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == 'download name'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('download name: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='download_name',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == 'download name'
|
||||
).as_scalar()
|
||||
))
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'download name'))
|
||||
except:
|
||||
log.exception('Exception when upgrading download name')
|
||||
# Copy "proxy server" to "proxy_server"
|
||||
try:
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == 'proxy server'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('proxy server: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='proxy_server',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == 'proxy server'
|
||||
).as_scalar()
|
||||
))
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'proxy server'))
|
||||
except:
|
||||
log.exception('Exception when upgrading proxy server')
|
||||
# Copy "proxy username" to "proxy_username"
|
||||
try:
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == 'proxy username'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('proxy username: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='proxy_username',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == 'proxy username'
|
||||
).as_scalar()
|
||||
))
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'proxy username'))
|
||||
except:
|
||||
log.exception('Exception when upgrading proxy username')
|
||||
# Copy "proxy password" to "proxy_password"
|
||||
try:
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == 'proxy password'
|
||||
)
|
||||
).scalar()
|
||||
log.debug('proxy password: {count}'.format(count=value_count))
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key='proxy_password',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == 'proxy password'
|
||||
).as_scalar()
|
||||
))
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'proxy password'))
|
||||
except:
|
||||
log.exception('Exception when upgrading proxy password')
|
||||
try:
|
||||
session.execute(delete(metadata_table).where(metadata_table.c.key == 'dbversion'))
|
||||
except:
|
||||
log.exception('Exception when deleting dbversion')
|
||||
session.commit()
|
||||
log.info('No upgrades to perform')
|
||||
|
|
|
@ -34,7 +34,7 @@ class Ui_CustomEditDialog(object):
|
|||
:param custom_edit_dialog: The Dialog
|
||||
"""
|
||||
custom_edit_dialog.setObjectName('custom_edit_dialog')
|
||||
custom_edit_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
custom_edit_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
custom_edit_dialog.resize(450, 350)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(custom_edit_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -31,7 +31,7 @@ from openlp.core.ui.lib import SpellTextEdit
|
|||
class Ui_CustomSlideEditDialog(object):
|
||||
def setupUi(self, custom_slide_edit_dialog):
|
||||
custom_slide_edit_dialog.setObjectName('custom_slide_edit_dialog')
|
||||
custom_slide_edit_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
custom_slide_edit_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
custom_slide_edit_dialog.resize(350, 300)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(custom_slide_edit_dialog)
|
||||
self.slide_text_edit = SpellTextEdit(self)
|
||||
|
|
|
@ -105,8 +105,6 @@ class CustomMediaItem(MediaManagerItem):
|
|||
[(CustomSearch.Titles, ':/songs/song_search_title.png', translate('SongsPlugin.MediaItem', 'Titles'),
|
||||
translate('SongsPlugin.MediaItem', 'Search Titles...')),
|
||||
(CustomSearch.Themes, ':/slides/slide_theme.png', UiStrings().Themes, UiStrings().SearchThemes)])
|
||||
text = '{section}/last search type'.format(section=self.settings_section)
|
||||
self.search_text_edit.set_current_search_type(Settings().value(text))
|
||||
self.load_list(self.plugin.db_manager.get_all_objects(CustomSlide, order_by_ref=CustomSlide.title))
|
||||
self.config_update()
|
||||
|
||||
|
@ -131,7 +129,6 @@ class CustomMediaItem(MediaManagerItem):
|
|||
# Called to redisplay the custom list screen edith from a search
|
||||
# or from the exit of the Custom edit dialog. If remote editing is
|
||||
# active trigger it and clean up so it will not update again.
|
||||
self.check_search_result()
|
||||
|
||||
def on_new_click(self):
|
||||
"""
|
||||
|
@ -250,9 +247,6 @@ class CustomMediaItem(MediaManagerItem):
|
|||
"""
|
||||
Search the plugin database
|
||||
"""
|
||||
# Save the current search type to the configuration.
|
||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||
self.search_text_edit.current_search_type())
|
||||
# Reload the list considering the new search type.
|
||||
search_type = self.search_text_edit.current_search_type()
|
||||
search_keywords = '%{search}%'.format(search=self.whitespace.sub(' ', self.search_text_edit.displayText()))
|
||||
|
@ -268,7 +262,6 @@ class CustomMediaItem(MediaManagerItem):
|
|||
CustomSlide.theme_name.like(search_keywords),
|
||||
order_by_ref=CustomSlide.title)
|
||||
self.load_list(search_results)
|
||||
self.check_search_result()
|
||||
|
||||
def on_search_text_edit_changed(self, text):
|
||||
"""
|
||||
|
@ -350,7 +343,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||
:param string: The search string
|
||||
:param show_error: The error string to be show.
|
||||
"""
|
||||
search = '%{search}%'.forma(search=string.lower())
|
||||
search = '%{search}%'.format(search=string.lower())
|
||||
search_results = self.plugin.db_manager.get_all_objects(CustomSlide,
|
||||
or_(func.lower(CustomSlide.title).like(search),
|
||||
func.lower(CustomSlide.text).like(search)),
|
||||
|
|
|
@ -150,7 +150,8 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
triggers=self.on_replace_click)
|
||||
if 'webkit' not in get_media_players()[0]:
|
||||
self.replace_action.setDisabled(True)
|
||||
self.replace_action_context.setDisabled(True)
|
||||
if hasattr(self, 'replace_action_context'):
|
||||
self.replace_action_context.setDisabled(True)
|
||||
self.reset_action = self.toolbar.add_toolbar_action('reset_action', icon=':/system/system_close.png',
|
||||
visible=False, triggers=self.on_reset_click)
|
||||
self.media_widget = QtWidgets.QWidget(self)
|
||||
|
|
|
@ -36,7 +36,7 @@ class Ui_AuthorsDialog(object):
|
|||
Set up the UI for the dialog.
|
||||
"""
|
||||
authors_dialog.setObjectName('authors_dialog')
|
||||
authors_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
authors_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
authors_dialog.resize(300, 10)
|
||||
authors_dialog.setModal(True)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(authors_dialog)
|
||||
|
|
|
@ -36,7 +36,7 @@ class Ui_EditSongDialog(object):
|
|||
"""
|
||||
def setupUi(self, edit_song_dialog):
|
||||
edit_song_dialog.setObjectName('edit_song_dialog')
|
||||
edit_song_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
edit_song_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
edit_song_dialog.resize(900, 600)
|
||||
edit_song_dialog.setModal(True)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(edit_song_dialog)
|
||||
|
|
|
@ -317,7 +317,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
self.song.verse_order = re.sub('([' + verse.upper() + verse.lower() + '])(\W|$)',
|
||||
r'\g<1>1\2', self.song.verse_order)
|
||||
except:
|
||||
log.exception('Problem processing song Lyrics \n{xml}'.forma(xml=sxml.dump_xml()))
|
||||
log.exception('Problem processing song Lyrics \n{xml}'.format(xml=sxml.dump_xml()))
|
||||
raise
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
|
|
|
@ -31,7 +31,7 @@ from openlp.plugins.songs.lib import VerseType
|
|||
class Ui_EditVerseDialog(object):
|
||||
def setupUi(self, edit_verse_dialog):
|
||||
edit_verse_dialog.setObjectName('edit_verse_dialog')
|
||||
edit_verse_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
edit_verse_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
edit_verse_dialog.resize(400, 400)
|
||||
edit_verse_dialog.setModal(True)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(edit_verse_dialog)
|
||||
|
|
|
@ -35,7 +35,7 @@ class Ui_MediaFilesDialog(object):
|
|||
Set up the user interface.
|
||||
"""
|
||||
media_files_dialog.setObjectName('media_files_dialog')
|
||||
media_files_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
media_files_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
media_files_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
media_files_dialog.resize(400, 300)
|
||||
media_files_dialog.setModal(True)
|
||||
|
|
|
@ -35,7 +35,7 @@ class Ui_SongBookDialog(object):
|
|||
Set up the user interface.
|
||||
"""
|
||||
song_book_dialog.setObjectName('song_book_dialog')
|
||||
song_book_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
song_book_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
song_book_dialog.resize(300, 10)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(song_book_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -51,7 +51,7 @@ class SongExportForm(OpenLPWizard):
|
|||
:param parent: The QWidget-derived parent of the wizard.
|
||||
:param plugin: The songs plugin.
|
||||
"""
|
||||
super(SongExportForm, self).__init__(parent, plugin, 'song_export_wizard', ':/wizards/wizard_exportsong.bmp')
|
||||
super(SongExportForm, self).__init__(parent, plugin, 'song_export_wizard', ':/wizards/wizard_song.bmp')
|
||||
self.stop_export_flag = False
|
||||
Registry().register_function('openlp_stop_wizard', self.stop_export)
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class SongImportForm(OpenLPWizard, RegistryProperties):
|
|||
:param parent: The QWidget-derived parent of the wizard.
|
||||
:param plugin: The songs plugin.
|
||||
"""
|
||||
super(SongImportForm, self).__init__(parent, plugin, 'songImportWizard', ':/wizards/wizard_importsong.bmp')
|
||||
super(SongImportForm, self).__init__(parent, plugin, 'songImportWizard', ':/wizards/wizard_song.bmp')
|
||||
self.clipboard = self.main_window.clipboard
|
||||
|
||||
def setupUi(self, image):
|
||||
|
|
|
@ -37,7 +37,7 @@ class Ui_SongMaintenanceDialog(object):
|
|||
Set up the user interface for the song maintenance dialog
|
||||
"""
|
||||
song_maintenance_dialog.setObjectName('song_maintenance_dialog')
|
||||
song_maintenance_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
song_maintenance_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
song_maintenance_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
song_maintenance_dialog.resize(10, 350)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(song_maintenance_dialog)
|
||||
|
|
|
@ -182,7 +182,7 @@ class SongReviewWidget(QtWidgets.QWidget):
|
|||
self.song_vertical_layout.addWidget(self.song_group_box)
|
||||
self.song_remove_button = QtWidgets.QPushButton(self)
|
||||
self.song_remove_button.setObjectName('song_remove_button')
|
||||
self.song_remove_button.setIcon(build_icon(':/songs/song_delete.png'))
|
||||
self.song_remove_button.setIcon(build_icon(':/general/general_delete.png'))
|
||||
self.song_remove_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
self.song_vertical_layout.addWidget(self.song_remove_button, alignment=QtCore.Qt.AlignHCenter)
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class Ui_TopicsDialog(object):
|
|||
Set up the user interface for the topics dialog.
|
||||
"""
|
||||
topics_dialog.setObjectName('topics_dialog')
|
||||
topics_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
topics_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
topics_dialog.resize(300, 10)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(topics_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -101,7 +101,7 @@ class MediaShoutImport(SongImport):
|
|||
self.song_book_name = song.SongID
|
||||
for verse in verses:
|
||||
tag = VERSE_TAGS[verse.Type] + str(verse.Number) if verse.Type < len(VERSE_TAGS) else 'O'
|
||||
self.add_verse(verse.Text, tag)
|
||||
self.add_verse(self.tidy_text(verse.Text), tag)
|
||||
for order in verse_order:
|
||||
if order.Type < len(VERSE_TAGS):
|
||||
self.verse_order_list.append(VERSE_TAGS[order.Type] + str(order.Number))
|
||||
|
|
|
@ -140,10 +140,13 @@ class SongImport(QtCore.QObject):
|
|||
text = text.replace('\u2026', '...')
|
||||
text = text.replace('\u2013', '-')
|
||||
text = text.replace('\u2014', '-')
|
||||
# Replace vertical tab with 2 linebreaks
|
||||
text = text.replace('\v', '\n\n')
|
||||
# Replace form feed (page break) with 2 linebreaks
|
||||
text = text.replace('\f', '\n\n')
|
||||
# Remove surplus blank lines, spaces, trailing/leading spaces
|
||||
text = re.sub(r'[ \t\v]+', ' ', text)
|
||||
text = re.sub(r'[ \t]+', ' ', text)
|
||||
text = re.sub(r' ?(\r\n?|\n) ?', '\n', text)
|
||||
text = re.sub(r' ?(\n{5}|\f)+ ?', '\f', text)
|
||||
return text
|
||||
|
||||
def process_song_text(self, text):
|
||||
|
|
|
@ -166,14 +166,9 @@ class SongMediaItem(MediaManagerItem):
|
|||
translate('SongsPlugin.MediaItem', 'CCLI number'),
|
||||
translate('SongsPlugin.MediaItem', 'Search CCLI number...'))
|
||||
])
|
||||
self.search_text_edit.set_current_search_type(
|
||||
Settings().value('{section}/last search type'.format(section=self.settings_section)))
|
||||
self.config_update()
|
||||
|
||||
def on_search_text_button_clicked(self):
|
||||
# Save the current search type to the configuration.
|
||||
Settings().setValue('{section}/last search type'.format(section=self.settings_section),
|
||||
self.search_text_edit.current_search_type())
|
||||
# Reload the list considering the new search type.
|
||||
search_keywords = str(self.search_text_edit.displayText())
|
||||
search_type = self.search_text_edit.current_search_type()
|
||||
|
@ -232,7 +227,6 @@ class SongMediaItem(MediaManagerItem):
|
|||
search_results = self.plugin.manager.get_all_objects(
|
||||
Song, and_(Song.ccli_number.like(search_string), Song.ccli_number != ''))
|
||||
self.display_results_cclinumber(search_results)
|
||||
self.check_search_result()
|
||||
|
||||
def search_entire(self, search_keywords):
|
||||
search_string = '%{text}%'.format(text=clean_string(search_keywords))
|
||||
|
|
|
@ -458,7 +458,7 @@ class OpenLyrics(object):
|
|||
self._add_tag_to_formatting(tag, tags_element)
|
||||
# Replace end tags.
|
||||
for tag in end_tags:
|
||||
text = text.replace('{{{tag}}}'.format(tag=tag), '</tag>')
|
||||
text = text.replace('{{/{tag}}}'.format(tag=tag), '</tag>')
|
||||
# Replace \n with <br/>.
|
||||
text = text.replace('\n', '<br/>')
|
||||
element = etree.XML('<lines>{text}</lines>'.format(text=text))
|
||||
|
|
|
@ -46,13 +46,13 @@ MIN_BLOCK_SIZE = 70
|
|||
MAX_TYPO_SIZE = 3
|
||||
|
||||
|
||||
def songs_probably_equal(song_tupel):
|
||||
def songs_probably_equal(song_tuple):
|
||||
"""
|
||||
Calculate and return whether two songs are probably equal.
|
||||
|
||||
:param song_tupel: A tuple of two songs to compare.
|
||||
:param song_tuple: A tuple of two songs to compare.
|
||||
"""
|
||||
song1, song2 = song_tupel
|
||||
song1, song2 = song_tuple
|
||||
pos1, lyrics1 = song1
|
||||
pos2, lyrics2 = song2
|
||||
if len(lyrics1) < len(lyrics2):
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2016 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`db` module provides the ability to provide a csv file of all songs
|
||||
"""
|
||||
import csv
|
||||
import logging
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common import Registry, translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.songs.lib.db import Song
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def report_song_list():
|
||||
"""
|
||||
Export the song list as a CSV file.
|
||||
:return: Nothing
|
||||
"""
|
||||
main_window = Registry().get('main_window')
|
||||
plugin = Registry().get('songs').plugin
|
||||
report_file_name, filter_used = QtWidgets.QFileDialog.getSaveFileName(
|
||||
main_window,
|
||||
translate('SongPlugin.ReportSongList', 'Save File'),
|
||||
translate('SongPlugin.ReportSongList', 'song_extract.csv'),
|
||||
translate('SongPlugin.ReportSongList', 'CSV format (*.csv)'))
|
||||
|
||||
if not report_file_name:
|
||||
main_window.error_message(
|
||||
translate('SongPlugin.ReportSongList', 'Output Path Not Selected'),
|
||||
translate('SongPlugin.ReportSongList', 'You have not set a valid output location for your '
|
||||
'report. \nPlease select an existing path '
|
||||
'on your computer.')
|
||||
)
|
||||
return
|
||||
if not report_file_name.endswith('csv'):
|
||||
report_file_name += '.csv'
|
||||
file_handle = None
|
||||
Registry().get('application').set_busy_cursor()
|
||||
try:
|
||||
file_handle = open(report_file_name, 'wt')
|
||||
fieldnames = ('Title', 'Alternative Title', 'Copyright', 'Author(s)', 'Song Book', 'Topic')
|
||||
writer = csv.DictWriter(file_handle, fieldnames=fieldnames, quoting=csv.QUOTE_ALL)
|
||||
headers = dict((n, n) for n in fieldnames)
|
||||
writer.writerow(headers)
|
||||
song_list = plugin.manager.get_all_objects(Song)
|
||||
for song in song_list:
|
||||
author_list = []
|
||||
for author_song in song.authors_songs:
|
||||
author_list.append(author_song.author.display_name)
|
||||
author_string = ' | '.join(author_list)
|
||||
book_list = []
|
||||
for book_song in song.songbook_entries:
|
||||
if hasattr(book_song, 'entry') and book_song.entry:
|
||||
book_list.append('{name} #{entry}'.format(name=book_song.songbook.name, entry=book_song.entry))
|
||||
book_string = ' | '.join(book_list)
|
||||
topic_list = []
|
||||
for topic_song in song.topics:
|
||||
if hasattr(topic_song, 'name'):
|
||||
topic_list.append(topic_song.name)
|
||||
topic_string = ' | '.join(topic_list)
|
||||
writer.writerow({'Title': song.title,
|
||||
'Alternative Title': song.alternate_title,
|
||||
'Copyright': song.copyright,
|
||||
'Author(s)': author_string,
|
||||
'Song Book': book_string,
|
||||
'Topic': topic_string})
|
||||
Registry().get('application').set_normal_cursor()
|
||||
main_window.information_message(
|
||||
translate('SongPlugin.ReportSongList', 'Report Creation'),
|
||||
translate('SongPlugin.ReportSongList',
|
||||
'Report \n{name} \nhas been successfully created. ').format(name=report_file_name)
|
||||
)
|
||||
except OSError as ose:
|
||||
Registry().get('application').set_normal_cursor()
|
||||
log.exception('Failed to write out song usage records')
|
||||
critical_error_message_box(translate('SongPlugin.ReportSongList', 'Song Extraction Failed'),
|
||||
translate('SongPlugin.ReportSongList',
|
||||
'An error occurred while extracting: {error}'
|
||||
).format(error=ose.strerror))
|
||||
finally:
|
||||
if file_handle:
|
||||
file_handle.close()
|
|
@ -36,6 +36,7 @@ from openlp.core.common.actions import ActionList
|
|||
from openlp.core.lib import Plugin, StringContent, build_icon
|
||||
from openlp.core.lib.db import Manager
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.plugins.songs import reporting
|
||||
from openlp.plugins.songs.forms.duplicatesongremovalform import DuplicateSongRemovalForm
|
||||
from openlp.plugins.songs.forms.songselectform import SongSelectForm
|
||||
from openlp.plugins.songs.lib import clean_song, upgrade
|
||||
|
@ -102,13 +103,13 @@ class SongsPlugin(Plugin):
|
|||
self.songselect_form.initialise()
|
||||
self.song_import_item.setVisible(True)
|
||||
self.song_export_item.setVisible(True)
|
||||
self.tools_reindex_item.setVisible(True)
|
||||
self.tools_find_duplicates.setVisible(True)
|
||||
self.song_tools_menu.menuAction().setVisible(True)
|
||||
action_list = ActionList.get_instance()
|
||||
action_list.add_action(self.song_import_item, UiStrings().Import)
|
||||
action_list.add_action(self.song_export_item, UiStrings().Export)
|
||||
action_list.add_action(self.tools_reindex_item, UiStrings().Tools)
|
||||
action_list.add_action(self.tools_find_duplicates, UiStrings().Tools)
|
||||
action_list.add_action(self.tools_report_song_list, UiStrings().Tools)
|
||||
|
||||
def add_import_menu_item(self, import_menu):
|
||||
"""
|
||||
|
@ -151,19 +152,37 @@ class SongsPlugin(Plugin):
|
|||
:param tools_menu: The actual **Tools** menu item, so that your actions can use it as their parent.
|
||||
"""
|
||||
log.info('add tools menu')
|
||||
self.tools_menu = tools_menu
|
||||
self.song_tools_menu = QtWidgets.QMenu(tools_menu)
|
||||
self.song_tools_menu.setObjectName('song_tools_menu')
|
||||
self.song_tools_menu.setTitle(translate('SongsPlugin', 'Songs'))
|
||||
self.tools_reindex_item = create_action(
|
||||
tools_menu, 'toolsReindexItem',
|
||||
text=translate('SongsPlugin', '&Re-index Songs'),
|
||||
icon=':/plugins/plugin_songs.png',
|
||||
statustip=translate('SongsPlugin', 'Re-index the songs database to improve searching and ordering.'),
|
||||
visible=False, triggers=self.on_tools_reindex_item_triggered)
|
||||
tools_menu.addAction(self.tools_reindex_item)
|
||||
triggers=self.on_tools_reindex_item_triggered)
|
||||
self.tools_find_duplicates = create_action(
|
||||
tools_menu, 'toolsFindDuplicates',
|
||||
text=translate('SongsPlugin', 'Find &Duplicate Songs'),
|
||||
statustip=translate('SongsPlugin', 'Find and remove duplicate songs in the song database.'),
|
||||
visible=False, triggers=self.on_tools_find_duplicates_triggered, can_shortcuts=True)
|
||||
tools_menu.addAction(self.tools_find_duplicates)
|
||||
triggers=self.on_tools_find_duplicates_triggered, can_shortcuts=True)
|
||||
self.tools_report_song_list = create_action(
|
||||
tools_menu, 'toolsSongListReport',
|
||||
text=translate('SongsPlugin', 'Song List Report'),
|
||||
statustip=translate('SongsPlugin', 'Produce a CSV file of all the songs in the database.'),
|
||||
triggers=self.on_tools_report_song_list_triggered)
|
||||
|
||||
self.tools_menu.addAction(self.song_tools_menu.menuAction())
|
||||
self.song_tools_menu.addAction(self.tools_reindex_item)
|
||||
self.song_tools_menu.addAction(self.tools_find_duplicates)
|
||||
self.song_tools_menu.addAction(self.tools_report_song_list)
|
||||
|
||||
self.song_tools_menu.menuAction().setVisible(False)
|
||||
|
||||
@staticmethod
|
||||
def on_tools_report_song_list_triggered():
|
||||
reporting.report_song_list()
|
||||
|
||||
def on_tools_reindex_item_triggered(self):
|
||||
"""
|
||||
|
@ -326,13 +345,13 @@ class SongsPlugin(Plugin):
|
|||
self.manager.finalise()
|
||||
self.song_import_item.setVisible(False)
|
||||
self.song_export_item.setVisible(False)
|
||||
self.tools_reindex_item.setVisible(False)
|
||||
self.tools_find_duplicates.setVisible(False)
|
||||
action_list = ActionList.get_instance()
|
||||
action_list.remove_action(self.song_import_item, UiStrings().Import)
|
||||
action_list.remove_action(self.song_export_item, UiStrings().Export)
|
||||
action_list.remove_action(self.tools_reindex_item, UiStrings().Tools)
|
||||
action_list.remove_action(self.tools_find_duplicates, UiStrings().Tools)
|
||||
action_list.add_action(self.tools_report_song_list, UiStrings().Tools)
|
||||
self.song_tools_menu.menuAction().setVisible(False)
|
||||
super(SongsPlugin, self).finalise()
|
||||
|
||||
def new_service_created(self):
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_SongUsageDeleteDialog(object):
|
|||
:param song_usage_delete_dialog:
|
||||
"""
|
||||
song_usage_delete_dialog.setObjectName('song_usage_delete_dialog')
|
||||
song_usage_delete_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
song_usage_delete_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
song_usage_delete_dialog.resize(291, 243)
|
||||
self.vertical_layout = QtWidgets.QVBoxLayout(song_usage_delete_dialog)
|
||||
self.vertical_layout.setSpacing(8)
|
||||
|
|
|
@ -38,7 +38,7 @@ class Ui_SongUsageDetailDialog(object):
|
|||
:param song_usage_detail_dialog:
|
||||
"""
|
||||
song_usage_detail_dialog.setObjectName('song_usage_detail_dialog')
|
||||
song_usage_detail_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
|
||||
song_usage_detail_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
song_usage_detail_dialog.resize(609, 413)
|
||||
self.vertical_layout = QtWidgets.QVBoxLayout(song_usage_detail_dialog)
|
||||
self.vertical_layout.setSpacing(8)
|
||||
|
|
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 802 B |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 720 B |
Before Width: | Height: | Size: 762 B |
Before Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 668 B |
Before Width: | Height: | Size: 579 B |
Before Width: | Height: | Size: 644 B |
Before Width: | Height: | Size: 187 KiB |
Before Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 531 B |
Before Width: | Height: | Size: 531 B |
Before Width: | Height: | Size: 862 B |
Before Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 784 B |
Before Width: | Height: | Size: 740 B |
Before Width: | Height: | Size: 795 B |
Before Width: | Height: | Size: 762 B |
|
@ -23,8 +23,7 @@
|
|||
<file>topic_maintenance.png</file>
|
||||
<file>song_author_edit.png</file>
|
||||
<file>song_book_edit.png</file>
|
||||
<file>song_delete.png</file>
|
||||
</qresource>
|
||||
</qresource>
|
||||
<qresource prefix="images">
|
||||
<file>image_group.png</file>
|
||||
<file>image_new_group.png</file>
|
||||
|
@ -33,7 +32,6 @@
|
|||
<file>bibles_search_combined.png</file>
|
||||
<file>bibles_search_text.png</file>
|
||||
<file>bibles_search_reference.png</file>
|
||||
<file>bibles_upgrade_alert.png</file>
|
||||
<file>bibles_search_clear.png</file>
|
||||
<file>bibles_search_unlock.png</file>
|
||||
<file>bibles_search_lock.png</file>
|
||||
|
@ -71,7 +69,6 @@
|
|||
<file>general_back.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="slides">
|
||||
<file>slide_close.png</file>
|
||||
<file>slide_next.png</file>
|
||||
<file>slide_blank.png</file>
|
||||
<file>slide_desktop.png</file>
|
||||
|
@ -83,12 +80,6 @@
|
|||
<file>media_playback_next.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="icon">
|
||||
<file>openlp-logo-16x16.png</file>
|
||||
<file>openlp-logo-32x32.png</file>
|
||||
<file>openlp-logo-48x48.png</file>
|
||||
<file>openlp-logo-64x64.png</file>
|
||||
<file>openlp-logo-128x128.png</file>
|
||||
<file>openlp-logo-256x256.png</file>
|
||||
<file>openlp-logo.svg</file>
|
||||
</qresource>
|
||||
<qresource prefix="graphics">
|
||||
|
@ -97,24 +88,18 @@
|
|||
<file>openlp-about-logo.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="imports">
|
||||
<file>import_selectall.png</file>
|
||||
<file>import_move_to_list.png</file>
|
||||
<file>import_remove.png</file>
|
||||
<file>import_load.png</file>
|
||||
</qresource>
|
||||
</qresource>
|
||||
<qresource prefix="exports">
|
||||
<file>export_load.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="wizards">
|
||||
<file>openlp-osx-wizard.png</file>
|
||||
<file>wizard_exportsong.bmp</file>
|
||||
<file>wizard_importsong.bmp</file>
|
||||
<file>wizard_song.bmp</file>
|
||||
<file>wizard_importbible.bmp</file>
|
||||
<file>wizard_firsttime.bmp</file>
|
||||
<file>wizard_createtheme.bmp</file>
|
||||
<file>wizard_duplicateremoval.bmp</file>
|
||||
<file>wizard_createprojector.png</file>
|
||||
</qresource>
|
||||
</qresource>
|
||||
<qresource prefix="services">
|
||||
<file>service_collapse_all.png</file>
|
||||
<file>service_expand_all.png</file>
|
||||
|
@ -130,7 +115,6 @@
|
|||
<file>clear_shortcut.png</file>
|
||||
<file>system_about.png</file>
|
||||
<file>system_help_contents.png</file>
|
||||
<file>system_online_help.png</file>
|
||||
<file>system_mediamanager.png</file>
|
||||
<file>system_volunteer.png</file>
|
||||
<file>system_servicemanager.png</file>
|
||||
|
@ -156,10 +140,7 @@
|
|||
<file>multimedia-player.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="messagebox">
|
||||
<file>messagebox_critical.png</file>
|
||||
<file>messagebox_info.png</file>
|
||||
<file>messagebox_warning.png</file>
|
||||
</qresource>
|
||||
</qresource>
|
||||
<qresource prefix="remote">
|
||||
<file>network_server.png</file>
|
||||
<file>network_ssl.png</file>
|
||||
|
@ -171,10 +152,8 @@
|
|||
</qresource>
|
||||
<qresource prefix="tools">
|
||||
<file>tools_add.png</file>
|
||||
<file>tools_alert.png</file>
|
||||
</qresource>
|
||||
</qresource>
|
||||
<qresource prefix="themes">
|
||||
<file>theme_delete.png</file>
|
||||
<file>theme_new.png</file>
|
||||
<file>theme_edit.png</file>
|
||||
</qresource>
|
||||
|
@ -202,12 +181,10 @@
|
|||
<file>projector_power_on_tiled.png</file>
|
||||
<file>projector_show.png</file>
|
||||
<file>projector_show_tiled.png</file>
|
||||
<file>projector_spacer.png</file>
|
||||
<file>projector_warmup.png</file>
|
||||
<file>projector_view.png</file>
|
||||
</qresource>
|
||||
</qresource>
|
||||
<qresource prefix="remotes">
|
||||
<file>android_app_qr.png</file>
|
||||
<file>ios_app_qr.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
</RCC>
|
|
@ -1,323 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="500"
|
||||
height="85"
|
||||
id="svg4363"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
version="1.0"
|
||||
sodipodi:docname="openlp-website-logo.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
inkscape:export-filename="/home/raoul/Projects/OpenLP/bug-1069109/resources/images/openlp-about-logo.png"
|
||||
inkscape:export-xdpi="91.058823"
|
||||
inkscape:export-ydpi="91.058823">
|
||||
<defs
|
||||
id="defs4365">
|
||||
<linearGradient
|
||||
id="linearGradient4043">
|
||||
<stop
|
||||
id="stop4045"
|
||||
offset="0"
|
||||
style="stop-color:#000d26;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop4047"
|
||||
offset="1"
|
||||
style="stop-color:#77a5ff;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3208">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.25098041;"
|
||||
offset="0"
|
||||
id="stop3210" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3212" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient6359">
|
||||
<stop
|
||||
style="stop-color:#000d26;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6361" />
|
||||
<stop
|
||||
style="stop-color:#507fda;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop6363" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3195">
|
||||
<stop
|
||||
style="stop-color:#cdcdff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3197" />
|
||||
<stop
|
||||
style="stop-color:#ebebff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3199" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective4371" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3208"
|
||||
id="linearGradient4437"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.12702,0,0,0.1374728,-18.124431,2.9208725)"
|
||||
x1="470.25891"
|
||||
y1="276.68851"
|
||||
x2="469.44925"
|
||||
y2="104.30029" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6359"
|
||||
id="linearGradient4440"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="815.75"
|
||||
y1="480.55844"
|
||||
x2="201.10622"
|
||||
y2="371.85938"
|
||||
gradientTransform="matrix(0.1142015,0,0,0.1142015,-11.580885,2.363006)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3195"
|
||||
id="linearGradient4445"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="117.59262"
|
||||
y1="384.05795"
|
||||
x2="418.20981"
|
||||
y2="436.03787" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter4956">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="10.731562"
|
||||
id="feGaussianBlur4958" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3195"
|
||||
id="linearGradient4967"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="117.59262"
|
||||
y1="384.05795"
|
||||
x2="418.20981"
|
||||
y2="436.03787" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter5019">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="4.333215"
|
||||
id="feGaussianBlur5021" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3208"
|
||||
id="linearGradient4027"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.12702,0,0,0.1374728,-16.124431,1.0651835)"
|
||||
x1="470.25891"
|
||||
y1="276.68851"
|
||||
x2="469.44925"
|
||||
y2="104.30029" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6359"
|
||||
id="linearGradient4030"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.1142015,0,0,0.1142015,-9.580885,0.507317)"
|
||||
x1="815.75"
|
||||
y1="480.55844"
|
||||
x2="201.10622"
|
||||
y2="371.85938" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4043"
|
||||
id="linearGradient4082"
|
||||
x1="903.01746"
|
||||
y1="1155.8621"
|
||||
x2="903.01746"
|
||||
y2="1010.8456"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="184.78458"
|
||||
inkscape:cy="42.5"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1600"
|
||||
inkscape:window-height="845"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-3"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata4368">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
transform="matrix(0.1118197,0,0,0.1118197,-8.786549,-1.2232712)"
|
||||
d="m 833.03006,395.26932 a 357.71872,357.71872 0 1 1 -715.43744,0 357.71872,357.71872 0 1 1 715.43744,0 z"
|
||||
sodipodi:ry="357.71872"
|
||||
sodipodi:rx="357.71872"
|
||||
sodipodi:cy="395.26932"
|
||||
sodipodi:cx="475.31134"
|
||||
id="path3204"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;filter:url(#filter4956)"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
sodipodi:type="arc"
|
||||
style="fill:#051e52;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
|
||||
id="path3206"
|
||||
sodipodi:cx="475.31134"
|
||||
sodipodi:cy="395.26932"
|
||||
sodipodi:rx="357.71872"
|
||||
sodipodi:ry="357.71872"
|
||||
d="m 833.03006,395.26932 a 357.71872,357.71872 0 1 1 -715.43744,0 357.71872,357.71872 0 1 1 715.43744,0 z"
|
||||
transform="matrix(0.1118197,0,0,0.1118197,-8.786549,-1.2232712)" />
|
||||
<path
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
transform="matrix(0.1107234,0,0,0.1107234,-8.265479,-0.7899487)"
|
||||
d="m 833.03006,395.26932 a 357.71872,357.71872 0 1 1 -715.43744,0 357.71872,357.71872 0 1 1 715.43744,0 z"
|
||||
sodipodi:ry="357.71872"
|
||||
sodipodi:rx="357.71872"
|
||||
sodipodi:cy="395.26932"
|
||||
sodipodi:cx="475.31134"
|
||||
id="path3208"
|
||||
style="fill:url(#linearGradient4967);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
id="path3210"
|
||||
d="m 44.36148,3.758491 c -6.297077,0 -12.248038,1.4878106 -17.522793,4.1290979 L 55.060733,30.528036 82.41913,52.476137 c 0.757958,-3.042375 1.159859,-6.2242 1.159859,-9.500137 0,-21.647054 -17.570455,-39.2175089 -39.217509,-39.217509 z m -27.440479,11.21316 c -1.397407,1.36948 -2.691129,2.843176 -3.872145,4.407464 L 51.188588,38.186674 79.157249,51.980074 51.306358,35.417288 16.921001,14.971651 z M 7.3459186,29.999854 c -0.6358568,1.811994 -1.1400074,3.684306 -1.5060323,5.60658 l 42.8148557,10.577914 28.5361,7.051943 -28.528962,-9.493 L 7.3459186,29.999854 z M 5.4223371,47.622573 c 0.2287353,1.934542 0.5954569,3.825699 1.0956206,5.663681 l 40.0561763,1.142015 30.40258,0.870786 -29.481831,-3.165522 -42.0725459,-4.51096 z m 72.7356489,9.510844 -31.32333,3.343963 -35.406034,3.779356 c 1.044472,1.612311 2.202222,3.144536 3.465302,4.582335 l 31.005707,-5.738626 32.258355,-5.967028 z m 2.416076,0.913612 -33.01494,10.899106 -23.311381,7.694326 c 5.882638,3.524576 12.76171,5.549478 20.113739,5.549479 16.307671,0 30.301779,-9.969218 36.212582,-24.142911 z"
|
||||
style="fill:url(#linearGradient4030);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3212"
|
||||
d="m 44.36148,3.758491 c -6.297077,0 -12.248038,1.4878106 -17.522793,4.1290979 l 28.222046,22.6404471 9.211065,7.390979 C 71.133234,37.064569 77.342848,35.776232 82.579726,34.161072 78.576448,16.75338 62.978175,3.7584911 44.36148,3.758491 z m -27.440479,11.21316 c -1.397407,1.36948 -2.691129,2.843176 -3.872145,4.407464 l 38.139732,18.807559 1.459638,0.720897 c 1.387008,-0.06663 2.75609,-0.150339 4.107685,-0.249815 L 51.306358,35.417288 16.921001,14.971651 z M 7.3459186,29.999854 c -0.4665326,1.329474 -0.862645,2.69238 -1.1848406,4.082704 7.470753,2.334095 16.950926,3.993198 27.508286,4.675124 L 7.3459186,29.999854 z"
|
||||
style="fill:url(#linearGradient4027);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
|
||||
<g
|
||||
id="g4991"
|
||||
transform="matrix(0.5913526,0,0,0.5913526,-290.02996,-588.79058)"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.69103849;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter5019)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4993"
|
||||
d="m 801.444,1038.553 15.617,0 c 18.862,0 28.496,10.444 28.496,25.961 0,15.212 -9.634,25.859 -28.496,25.859 l -8.316,0 0,17.139 -7.301,0 0,-68.959 0,0 z m 15.211,45.431 c 15.517,0 21.297,-8.112 21.297,-19.471 0,-11.359 -5.78,-19.471 -21.297,-19.471 l -7.91,0 0,38.941 7.91,0 0,10e-4 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.69103849;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4995"
|
||||
d="m 852.858,1038.553 41.984,0 0,6.49 -34.684,0 0,32.35 30.931,0 0,6.389 -30.931,0 0,17.24 36.103,0 0,6.49 -43.403,0 0,-68.959 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.69103849;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4997"
|
||||
d="m 913.197,1059.545 c -1.927,-2.333 -4.767,-6.39 -4.767,-6.39 0,0 0.608,4.868 0.608,7.81 l 0,46.547 -6.896,0 0,-69.669 1.217,0 41.173,48.677 c 1.927,2.333 4.259,5.163 4.259,5.163 0,0 0,-3.642 0,-6.582 l 0,-46.548 6.795,0 0,69.669 -1.217,0 -41.172,-48.677 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.69103849;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4999"
|
||||
d="m 677.015,1070.032 c 0,-34.836 26.253,-58.564 58.564,-58.564 32.311,0 58.564,23.729 58.564,58.564 0,34.835 -26.253,58.564 -58.564,58.564 -32.311,0 -58.564,-23.728 -58.564,-58.564 z m 110.06,0 c 0,-29.955 -22.045,-52.338 -51.496,-52.338 -29.451,0 -51.496,22.383 -51.496,52.338 0,29.956 22.045,52.338 51.496,52.338 29.451,0 51.496,-22.382 51.496,-52.338 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.69103849;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5001"
|
||||
d="m 967.521,1012.814 23.561,0 0,93.737 51.833,0 0,20.699 -75.394,0 0,-114.436 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.69103849;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5003"
|
||||
d="m 1054.85,1012.814 31.639,0 c 31.975,0 51.16,16.661 51.16,44.26 0,27.6 -19.354,44.092 -51.16,44.092 l -8.078,0 0,26.085 -23.561,0 0,-114.437 z m 30.965,67.653 c 19.185,0 27.599,-7.741 27.599,-23.393 0,-15.819 -8.751,-23.561 -27.599,-23.561 l -7.405,0 0,46.953 7.405,0 0,0 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.69103849;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:url(#linearGradient4082);fill-opacity:1.0;stroke:#ffffff;stroke-width:0.84551924000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
transform="matrix(0.5913526,0,0,0.5913526,-290.02996,-590.79058)"
|
||||
id="g5005"
|
||||
inkscape:export-xdpi="76.235291"
|
||||
inkscape:export-ydpi="76.235291">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4082);fill-opacity:1.0;stroke:#ffffff;stroke-width:0.84551924000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 801.444,1038.553 15.617,0 c 18.862,0 28.496,10.444 28.496,25.961 0,15.212 -9.634,25.859 -28.496,25.859 l -8.316,0 0,17.139 -7.301,0 0,-68.959 0,0 z m 15.211,45.431 c 15.517,0 21.297,-8.112 21.297,-19.471 0,-11.359 -5.78,-19.471 -21.297,-19.471 l -7.91,0 0,38.941 7.91,0 0,10e-4 z"
|
||||
id="path5007" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4082);fill-opacity:1.0;stroke:#ffffff;stroke-width:0.84551924000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 852.858,1038.553 41.984,0 0,6.49 -34.684,0 0,32.35 30.931,0 0,6.389 -30.931,0 0,17.24 36.103,0 0,6.49 -43.403,0 0,-68.959 z"
|
||||
id="path5009" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4082);fill-opacity:1.0;stroke:#ffffff;stroke-width:0.84551924000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 913.197,1059.545 c -1.927,-2.333 -4.767,-6.39 -4.767,-6.39 0,0 0.608,4.868 0.608,7.81 l 0,46.547 -6.896,0 0,-69.669 1.217,0 41.173,48.677 c 1.927,2.333 4.259,5.163 4.259,5.163 0,0 0,-3.642 0,-6.582 l 0,-46.548 6.795,0 0,69.669 -1.217,0 -41.172,-48.677 z"
|
||||
id="path5011" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4082);fill-opacity:1.0;stroke:#ffffff;stroke-width:0.84551924000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 677.015,1070.032 c 0,-34.836 26.253,-58.564 58.564,-58.564 32.311,0 58.564,23.729 58.564,58.564 0,34.835 -26.253,58.564 -58.564,58.564 -32.311,0 -58.564,-23.728 -58.564,-58.564 z m 110.06,0 c 0,-29.955 -22.045,-52.338 -51.496,-52.338 -29.451,0 -51.496,22.383 -51.496,52.338 0,29.956 22.045,52.338 51.496,52.338 29.451,0 51.496,-22.382 51.496,-52.338 z"
|
||||
id="path5013" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4082);fill-opacity:1.0;stroke:#ffffff;stroke-width:0.84551924000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 967.521,1012.814 23.561,0 0,93.737 51.833,0 0,20.699 -75.394,0 0,-114.436 z"
|
||||
id="path5015" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4082);fill-opacity:1.0;stroke:#ffffff;stroke-width:0.84551924000000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 1054.85,1012.814 31.639,0 c 31.975,0 51.16,16.661 51.16,44.26 0,27.6 -19.354,44.092 -51.16,44.092 l -8.078,0 0,26.085 -23.561,0 0,-114.437 z m 30.965,67.653 c 19.185,0 27.599,-7.741 27.599,-23.393 0,-15.819 -8.751,-23.561 -27.599,-23.561 l -7.405,0 0,46.953 7.405,0 0,0 z"
|
||||
id="path5017" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 16 KiB |
|
@ -1,489 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="640"
|
||||
height="480"
|
||||
id="svg3208"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
version="1.0"
|
||||
sodipodi:docname="openlp-default-dualdisplay.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape">
|
||||
<defs
|
||||
id="defs3210">
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter4005">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="4.333215"
|
||||
id="feGaussianBlur4007" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
id="linearGradient3208">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.25098041;"
|
||||
offset="0"
|
||||
id="stop3210" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3212" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient6359">
|
||||
<stop
|
||||
style="stop-color:#000d26;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6361" />
|
||||
<stop
|
||||
style="stop-color:#507fda;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop6363" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3195">
|
||||
<stop
|
||||
style="stop-color:#cdcdff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3197" />
|
||||
<stop
|
||||
style="stop-color:#ebebff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3199" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter6926">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="3.5771872"
|
||||
id="feGaussianBlur6928" />
|
||||
</filter>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective3216" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter4203"
|
||||
x="-0.0062387524"
|
||||
width="1.0124775"
|
||||
y="-0.15678384"
|
||||
height="1.3135677">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="1.5096395"
|
||||
id="feGaussianBlur4205" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3195"
|
||||
id="linearGradient4257"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="117.59262"
|
||||
y1="384.05795"
|
||||
x2="418.20981"
|
||||
y2="436.03787" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3208"
|
||||
id="linearGradient4284"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.5557126,0,0,0.6014434,52.878388,26.36294)"
|
||||
x1="470.25891"
|
||||
y1="276.68851"
|
||||
x2="469.44925"
|
||||
y2="104.30029" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6359"
|
||||
id="linearGradient4287"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="815.75"
|
||||
y1="480.55844"
|
||||
x2="201.10622"
|
||||
y2="371.85938"
|
||||
gradientTransform="matrix(0.4996316,0,0,0.4996316,81.506404,23.922274)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.56875"
|
||||
inkscape:cx="320"
|
||||
inkscape:cy="233.85153"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
width="940px"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="958"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4" />
|
||||
<metadata
|
||||
id="metadata3213">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g4335">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.00028753;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;filter:url(#filter6926)"
|
||||
id="path3204"
|
||||
sodipodi:cx="475.31134"
|
||||
sodipodi:cy="395.26932"
|
||||
sodipodi:rx="357.71872"
|
||||
sodipodi:ry="357.71872"
|
||||
d="M 833.03006,395.26932 A 357.71872,357.71872 0 1 1 117.59262,395.26932 A 357.71872,357.71872 0 1 1 833.03006,395.26932 z"
|
||||
transform="matrix(0.4892111,0,0,0.4892111,84.981623,16.35095)"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
transform="matrix(0.4892111,0,0,0.4892111,84.981623,16.35095)"
|
||||
d="M 833.03006,395.26932 A 357.71872,357.71872 0 1 1 117.59262,395.26932 A 357.71872,357.71872 0 1 1 833.03006,395.26932 z"
|
||||
sodipodi:ry="357.71872"
|
||||
sodipodi:rx="357.71872"
|
||||
sodipodi:cy="395.26932"
|
||||
sodipodi:cx="475.31134"
|
||||
id="path3206"
|
||||
style="fill:#051e52;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.00028753;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
|
||||
sodipodi:type="arc"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#linearGradient4257);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.00028753;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
|
||||
id="path3208"
|
||||
sodipodi:cx="475.31134"
|
||||
sodipodi:cy="395.26932"
|
||||
sodipodi:rx="357.71872"
|
||||
sodipodi:ry="357.71872"
|
||||
d="M 833.03006,395.26932 A 357.71872,357.71872 0 1 1 117.59262,395.26932 A 357.71872,357.71872 0 1 1 833.03006,395.26932 z"
|
||||
transform="matrix(0.4844149,0,0,0.4844149,87.261306,18.246736)"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4287);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
|
||||
d="M 317.50427,38.146161 C 289.95456,38.146161 263.9191,44.655333 240.84204,56.210966 L 364.3135,155.26293 L 484.0065,251.28588 C 487.32257,237.97549 489.08088,224.055 489.08088,209.72278 C 489.08088,115.01691 412.21014,38.146162 317.50427,38.146161 z M 197.45216,87.203739 C 191.33851,93.195216 185.67847,99.642637 180.51153,106.4864 L 347.37287,188.76948 L 469.73577,249.1156 L 347.88811,176.65341 L 197.45216,87.203739 z M 155.56118,152.95213 C 152.7793,160.87961 150.57364,169.07097 148.97228,177.48092 L 336.28729,223.7593 L 461.13274,254.61155 L 336.31852,213.07968 L 155.56118,152.95213 z M 147.14551,230.05154 C 148.14622,238.51516 149.75063,246.78897 151.93885,254.83014 L 327.18463,259.82646 L 460.19593,263.63615 L 331.21291,249.78698 L 147.14551,230.05154 z M 465.36399,271.66148 L 328.32441,286.29132 L 173.423,302.826 C 177.99257,309.87987 183.05773,316.58335 188.5837,322.87372 L 324.23368,297.76723 L 465.36399,271.66148 z M 475.93433,275.65853 L 331.49395,323.34212 L 229.50665,357.0048 C 255.2432,372.42482 285.33914,381.28377 317.50427,381.28378 C 388.85034,381.28378 450.07456,337.66845 475.93433,275.65853 z"
|
||||
id="path3210"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:url(#linearGradient4284);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.80000019;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
|
||||
d="M 317.50427,38.146161 C 289.95456,38.146161 263.9191,44.655333 240.84204,56.210966 L 364.3135,155.26293 L 404.61191,187.59846 C 434.6307,183.86026 461.79776,178.22379 484.70911,171.15746 C 467.19476,94.998806 398.95232,38.146162 317.50427,38.146161 z M 197.45216,87.203739 C 191.33851,93.195216 185.67847,99.642637 180.51153,106.4864 L 347.37287,188.76948 L 353.75879,191.9234 C 359.82695,191.63189 365.81668,191.26566 371.72991,190.83046 L 347.88811,176.65341 L 197.45216,87.203739 z M 155.56118,152.95213 C 153.5201,158.76858 151.7871,164.73129 150.3775,170.81396 C 183.06204,181.02563 224.53781,188.28421 270.72626,191.26763 L 155.56118,152.95213 z"
|
||||
id="path3212" />
|
||||
<g
|
||||
style="fill:#ffffff;fill-opacity:1;filter:url(#filter4005)"
|
||||
id="g2762"
|
||||
transform="matrix(0.6503605,0,0,0.6503605,-272.58365,-486.18544)">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2764"
|
||||
d="M 801.444,1038.553 L 817.061,1038.553 C 835.923,1038.553 845.557,1048.997 845.557,1064.514 C 845.557,1079.726 835.923,1090.373 817.061,1090.373 L 808.745,1090.373 L 808.745,1107.512 L 801.444,1107.512 L 801.444,1038.553 L 801.444,1038.553 z M 816.655,1083.984 C 832.172,1083.984 837.952,1075.872 837.952,1064.513 C 837.952,1053.154 832.172,1045.042 816.655,1045.042 L 808.745,1045.042 L 808.745,1083.983 L 816.655,1083.983 L 816.655,1083.984 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2766"
|
||||
d="M 852.858,1038.553 L 894.842,1038.553 L 894.842,1045.043 L 860.158,1045.043 L 860.158,1077.393 L 891.089,1077.393 L 891.089,1083.782 L 860.158,1083.782 L 860.158,1101.022 L 896.261,1101.022 L 896.261,1107.512 L 852.858,1107.512 L 852.858,1038.553 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2768"
|
||||
d="M 913.197,1059.545 C 911.27,1057.212 908.43,1053.155 908.43,1053.155 C 908.43,1053.155 909.038,1058.023 909.038,1060.965 L 909.038,1107.512 L 902.142,1107.512 L 902.142,1037.843 L 903.359,1037.843 L 944.532,1086.52 C 946.459,1088.853 948.791,1091.683 948.791,1091.683 C 948.791,1091.683 948.791,1088.041 948.791,1085.101 L 948.791,1038.553 L 955.586,1038.553 L 955.586,1108.222 L 954.369,1108.222 L 913.197,1059.545 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2770"
|
||||
d="M 677.015,1070.032 C 677.015,1035.196 703.268,1011.468 735.579,1011.468 C 767.89,1011.468 794.143,1035.197 794.143,1070.032 C 794.143,1104.867 767.89,1128.596 735.579,1128.596 C 703.268,1128.596 677.015,1104.868 677.015,1070.032 z M 787.075,1070.032 C 787.075,1040.077 765.03,1017.694 735.579,1017.694 C 706.128,1017.694 684.083,1040.077 684.083,1070.032 C 684.083,1099.988 706.128,1122.37 735.579,1122.37 C 765.03,1122.37 787.075,1099.988 787.075,1070.032 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2772"
|
||||
d="M 967.521,1012.814 L 991.082,1012.814 L 991.082,1106.551 L 1042.915,1106.551 L 1042.915,1127.25 L 967.521,1127.25 L 967.521,1012.814 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2774"
|
||||
d="M 1054.85,1012.814 L 1086.489,1012.814 C 1118.464,1012.814 1137.649,1029.475 1137.649,1057.074 C 1137.649,1084.674 1118.295,1101.166 1086.489,1101.166 L 1078.411,1101.166 L 1078.411,1127.251 L 1054.85,1127.251 L 1054.85,1012.814 z M 1085.815,1080.467 C 1105,1080.467 1113.414,1072.726 1113.414,1057.074 C 1113.414,1041.255 1104.663,1033.513 1085.815,1033.513 L 1078.41,1033.513 L 1078.41,1080.466 L 1085.815,1080.466 L 1085.815,1080.467 z" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
transform="matrix(0.6503605,0,0,0.6503605,-272.58365,-486.18544)"
|
||||
id="g3221">
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="M 801.444,1038.553 L 817.061,1038.553 C 835.923,1038.553 845.557,1048.997 845.557,1064.514 C 845.557,1079.726 835.923,1090.373 817.061,1090.373 L 808.745,1090.373 L 808.745,1107.512 L 801.444,1107.512 L 801.444,1038.553 L 801.444,1038.553 z M 816.655,1083.984 C 832.172,1083.984 837.952,1075.872 837.952,1064.513 C 837.952,1053.154 832.172,1045.042 816.655,1045.042 L 808.745,1045.042 L 808.745,1083.983 L 816.655,1083.983 L 816.655,1083.984 z"
|
||||
id="path3223" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="M 852.858,1038.553 L 894.842,1038.553 L 894.842,1045.043 L 860.158,1045.043 L 860.158,1077.393 L 891.089,1077.393 L 891.089,1083.782 L 860.158,1083.782 L 860.158,1101.022 L 896.261,1101.022 L 896.261,1107.512 L 852.858,1107.512 L 852.858,1038.553 z"
|
||||
id="path3225" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="M 913.197,1059.545 C 911.27,1057.212 908.43,1053.155 908.43,1053.155 C 908.43,1053.155 909.038,1058.023 909.038,1060.965 L 909.038,1107.512 L 902.142,1107.512 L 902.142,1037.843 L 903.359,1037.843 L 944.532,1086.52 C 946.459,1088.853 948.791,1091.683 948.791,1091.683 C 948.791,1091.683 948.791,1088.041 948.791,1085.101 L 948.791,1038.553 L 955.586,1038.553 L 955.586,1108.222 L 954.369,1108.222 L 913.197,1059.545 z"
|
||||
id="path3227" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="M 677.015,1070.032 C 677.015,1035.196 703.268,1011.468 735.579,1011.468 C 767.89,1011.468 794.143,1035.197 794.143,1070.032 C 794.143,1104.867 767.89,1128.596 735.579,1128.596 C 703.268,1128.596 677.015,1104.868 677.015,1070.032 z M 787.075,1070.032 C 787.075,1040.077 765.03,1017.694 735.579,1017.694 C 706.128,1017.694 684.083,1040.077 684.083,1070.032 C 684.083,1099.988 706.128,1122.37 735.579,1122.37 C 765.03,1122.37 787.075,1099.988 787.075,1070.032 z"
|
||||
id="path3229" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="M 967.521,1012.814 L 991.082,1012.814 L 991.082,1106.551 L 1042.915,1106.551 L 1042.915,1127.25 L 967.521,1127.25 L 967.521,1012.814 z"
|
||||
id="path3335" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="M 1054.85,1012.814 L 1086.489,1012.814 C 1118.464,1012.814 1137.649,1029.475 1137.649,1057.074 C 1137.649,1084.674 1118.295,1101.166 1086.489,1101.166 L 1078.411,1101.166 L 1078.411,1127.251 L 1054.85,1127.251 L 1054.85,1012.814 z M 1085.815,1080.467 C 1105,1080.467 1113.414,1072.726 1113.414,1057.074 C 1113.414,1041.255 1104.663,1033.513 1085.815,1033.513 L 1078.41,1033.513 L 1078.41,1080.466 L 1085.815,1080.466 L 1085.815,1080.467 z"
|
||||
id="path3337" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g4356">
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1;filter:url(#filter4203)"
|
||||
transform="translate(4.4621514,71.394422)"
|
||||
id="g3339">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3025"
|
||||
d="M 22.673731,370.71529 C 22.673731,364.06085 27.839035,359.16086 34.328304,359.16086 C 40.81705,359.16086 45.981829,364.06085 45.981829,370.71529 C 45.981829,377.36973 40.81705,382.26971 34.328304,382.26971 C 27.839035,382.26971 22.673731,377.37025 22.673731,370.71529 z M 41.214502,370.71529 C 41.214502,366.51058 38.433386,363.29898 34.328304,363.29898 C 30.222698,363.29898 27.441583,366.51058 27.441583,370.71529 C 27.441583,374.91999 30.222698,378.1316 34.328304,378.1316 C 38.433386,378.1316 41.214502,374.91999 41.214502,370.71529 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3027"
|
||||
d="M 49.922267,359.45869 L 56.146219,359.45869 C 62.436763,359.45869 66.21046,362.73583 66.21046,368.16541 C 66.21046,373.59498 62.403205,376.83961 56.146219,376.83961 L 54.556936,376.83961 L 54.556936,381.97136 L 49.922267,381.97136 L 49.922267,359.45869 z M 56.013561,372.76809 C 59.787782,372.76809 61.443133,371.2454 61.443133,368.16593 C 61.443133,365.05343 59.721715,363.53074 56.013561,363.53074 L 54.556936,363.53074 L 54.556936,372.76809 L 56.013561,372.76809 L 56.013561,372.76809 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3013"
|
||||
d="M 70.150962,359.45843 L 85.049122,359.45843 L 85.049122,363.53048 L 74.785631,363.53048 L 74.785631,370.68199 L 83.824257,370.68199 L 83.824257,374.65494 L 74.785631,374.65494 L 74.785631,377.89957 L 85.512641,377.89957 L 85.512641,381.97162 L 70.150962,381.97162 L 70.150962,359.45843 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3015"
|
||||
d="M 209.80292,381.97162 L 204.43941,381.97162 L 200.73126,376.27726 C 200.3013,376.34332 199.83778,376.37636 199.40729,376.37636 L 197.81801,376.37636 L 197.81801,381.97162 L 193.18334,381.97162 L 193.18334,359.45843 L 199.40729,359.45843 C 205.69784,359.45843 209.47153,362.4713 209.47153,367.96694 C 209.47153,371.47637 207.91581,373.69487 205.13469,374.95277 L 209.80292,381.97162 z M 199.27463,372.33734 C 203.04886,372.33734 204.70421,371.14604 204.70421,367.96694 C 204.70421,364.7889 202.98279,363.53048 199.27463,363.53048 L 197.81801,363.53048 L 197.81801,372.33734 L 199.27463,372.33734 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3017"
|
||||
d="M 534.09128,363.53048 L 527.6686,363.53048 L 527.6686,359.45843 L 545.14968,359.45843 L 545.14968,363.53048 L 538.72647,363.53048 L 538.72647,381.97162 L 534.09128,381.97162 L 534.09128,363.53048 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3019"
|
||||
d="M 295.01444,374.82011 L 286.47289,359.45843 L 291.60463,359.45843 L 295.57706,366.70904 C 296.43803,368.2978 297.3981,370.97982 297.3981,370.97982 C 297.3981,370.97982 298.2921,368.33136 299.15308,366.70904 L 302.96086,359.45843 L 307.69462,359.45843 L 299.68319,374.48925 L 299.68319,381.97162 L 295.01496,381.97162 L 295.01496,374.82011 L 295.01444,374.82011 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3021"
|
||||
d="M 171.03352,373.67756 L 171.03352,359.30951 L 175.66819,359.30951 L 175.66819,373.41329 C 175.66819,376.69044 177.0923,377.94834 180.17124,377.94834 C 183.21715,377.94834 184.60771,376.69044 184.60771,373.41329 L 184.60771,359.30951 L 189.2429,359.30951 L 189.2429,373.67756 C 189.2429,379.37193 185.30247,382.12054 180.17124,382.12054 C 174.97291,382.12001 171.03352,379.37193 171.03352,373.67756 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3023"
|
||||
d="M 332.19508,359.45843 L 336.82975,359.45843 L 336.82975,381.97162 L 332.19508,381.97162 L 332.19508,359.45843 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3031"
|
||||
d="M 123.72152,377.51864 L 127.49574,375.3337 C 128.48885,376.95602 129.77978,378.14785 132.06434,378.14785 C 133.98448,378.14785 135.20987,377.18778 135.20987,375.86329 C 135.20987,374.27453 133.95198,373.71138 131.83311,372.78435 L 130.67431,372.28779 C 127.33005,370.8642 125.11208,369.07672 125.11208,365.30249 C 125.11208,361.8261 127.76106,359.17712 131.89917,359.17712 C 134.84546,359.17712 136.96433,360.20378 138.48754,362.88527 L 134.87849,365.20287 C 134.08359,363.77928 133.22314,363.21666 131.89865,363.21666 C 130.54112,363.21666 129.68068,364.07763 129.68068,365.20287 C 129.68068,366.59343 130.54165,367.15657 132.52786,368.01702 L 133.68666,368.51357 C 137.62657,370.20196 139.84454,371.92337 139.84454,375.79722 C 139.84454,379.96889 136.5674,382.25293 132.16397,382.25293 C 127.86016,382.25293 125.07904,380.20013 123.72152,377.51864 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3041"
|
||||
d="M 465.62309,377.8828 L 469.39678,375.59876 C 470.12562,376.88969 470.78734,377.98242 472.37663,377.98242 C 473.89984,377.98242 474.85991,377.38624 474.85991,375.06865 L 474.85991,359.30951 L 479.49511,359.30951 L 479.49511,375.13471 C 479.49511,379.9356 476.68096,382.12054 472.57535,382.12054 C 468.8672,382.12054 466.71529,380.20039 465.62309,377.8828 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3045"
|
||||
d="M 269.79773,359.45843 L 274.4324,359.45843 L 274.4324,377.89905 L 284.62982,377.89905 L 284.62982,381.97162 L 269.79773,381.97162 L 269.79773,359.45843 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3051"
|
||||
d="M 213.74336,370.69825 C 213.74336,364.04381 218.87458,359.17686 225.33082,359.17686 C 229.40339,359.17686 232.31664,360.63296 234.33641,363.77849 L 230.79342,366.29481 C 229.73372,364.57287 227.9132,363.34801 225.33082,363.34801 C 221.25824,363.34801 218.51068,366.49354 218.51068,370.69825 C 218.51068,374.90295 221.25824,378.11455 225.33082,378.11455 C 228.24459,378.11455 229.86638,376.724 231.12481,374.80385 L 234.73386,377.28662 C 232.78016,380.33305 229.66818,382.25319 225.33082,382.25319 C 218.8751,382.25267 213.74336,377.35321 213.74336,370.69825 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3057"
|
||||
d="M 96.140027,371.50967 C 95.014786,370.44997 93.458536,368.43072 93.458536,368.43072 C 93.458536,368.43072 93.789921,370.91349 93.789921,372.53581 L 93.789921,381.97136 L 89.45308,381.97136 L 89.45308,359.25996 L 89.916599,359.25996 L 101.2723,369.92038 C 102.36503,370.94652 103.92075,372.99933 103.92075,372.99933 C 103.92075,372.99933 103.62293,370.45049 103.62293,368.89424 L 103.62293,359.45869 L 107.95977,359.45869 L 107.95977,382.17009 L 107.49625,382.17009 L 96.140027,371.50967 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 143.78498,370.71503 C 143.78498,364.06059 148.95028,359.1606 155.43955,359.1606 C 161.9283,359.1606 167.09308,364.06059 167.09308,370.71503 C 167.09308,377.36946 161.9283,382.26945 155.43955,382.26945 C 148.95028,382.26945 143.78498,377.36999 143.78498,370.71503 z M 162.32575,370.71503 C 162.32575,366.51032 159.54464,363.29872 155.43955,363.29872 C 151.33395,363.29872 148.55283,366.51032 148.55283,370.71503 C 148.55283,374.91973 151.33395,378.13133 155.43955,378.13133 C 159.54464,378.13133 162.32575,374.91973 162.32575,370.71503 z"
|
||||
id="path3231" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 238.6743,359.45843 L 253.57246,359.45843 L 253.57246,363.53048 L 243.30897,363.53048 L 243.30897,370.68199 L 252.34759,370.68199 L 252.34759,374.65494 L 243.30897,374.65494 L 243.30897,377.89957 L 254.03598,377.89957 L 254.03598,381.97162 L 238.6743,381.97162 L 238.6743,359.45843 z"
|
||||
id="path3233" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 328.25464,381.97162 L 322.89114,381.97162 L 319.18298,376.27726 C 318.75302,376.34332 318.2895,376.37636 317.85901,376.37636 L 316.26973,376.37636 L 316.26973,381.97162 L 311.63506,381.97162 L 311.63506,359.45843 L 317.85901,359.45843 C 324.14956,359.45843 327.92326,362.4713 327.92326,367.96694 C 327.92326,371.47637 326.36753,373.69487 323.58641,374.95277 L 328.25464,381.97162 z M 317.72636,372.33734 C 321.50058,372.33734 323.15593,371.14604 323.15593,367.96694 C 323.15593,364.7889 321.43451,363.53048 317.72636,363.53048 L 316.26973,363.53048 L 316.26973,372.33734 L 317.72636,372.33734 z"
|
||||
id="path3235" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 365.70113,377.51864 L 369.47535,375.3337 C 370.46845,376.95602 371.75938,378.14785 374.04395,378.14785 C 375.96409,378.14785 377.18948,377.18778 377.18948,375.86329 C 377.18948,374.27453 375.93158,373.71138 373.81271,372.78435 L 372.65391,372.28779 C 369.30965,370.8642 367.09168,369.07672 367.09168,365.30249 C 367.09168,361.8261 369.74066,359.17712 373.87878,359.17712 C 376.82506,359.17712 378.94393,360.20378 380.46715,362.88527 L 376.8581,365.20287 C 376.06319,363.77928 375.20275,363.21666 373.87826,363.21666 C 372.52073,363.21666 371.66028,364.07763 371.66028,365.20287 C 371.66028,366.59343 372.52126,367.15657 374.50747,368.01702 L 375.66627,368.51357 C 379.60618,370.20196 381.82415,371.92337 381.82415,375.79722 C 381.82415,379.96889 378.54701,382.25293 374.14357,382.25293 C 369.83976,382.25293 367.05865,380.20013 365.70113,377.51864 z"
|
||||
id="path3237" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 340.77019,370.69825 C 340.77019,364.04381 345.90141,359.17686 352.35764,359.17686 C 356.43022,359.17686 359.34347,360.63296 361.36323,363.77849 L 357.82025,366.29481 C 356.76055,364.57287 354.94003,363.34801 352.35764,363.34801 C 348.28507,363.34801 345.53751,366.49354 345.53751,370.69825 C 345.53751,374.90295 348.28507,378.11455 352.35764,378.11455 C 355.27142,378.11455 356.89321,376.724 358.15163,374.80385 L 361.76069,377.28662 C 359.80698,380.33305 356.69501,382.25319 352.35764,382.25319 C 345.90193,382.25267 340.77019,377.35321 340.77019,370.69825 z"
|
||||
id="path3239" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 397.5859,359.45869 L 403.80985,359.45869 C 410.1004,359.45869 413.8741,362.73583 413.8741,368.16541 C 413.8741,373.59498 410.06684,376.83961 403.80985,376.83961 L 402.22057,376.83961 L 402.22057,381.97136 L 397.5859,381.97136 L 397.5859,359.45869 z M 403.6772,372.76809 C 407.45142,372.76809 409.10677,371.2454 409.10677,368.16593 C 409.10677,365.05343 407.38535,363.53074 403.6772,363.53074 L 402.22057,363.53074 L 402.22057,372.76809 L 403.6772,372.76809 L 403.6772,372.76809 z"
|
||||
id="path3241" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 483.43554,359.45843 L 498.33371,359.45843 L 498.33371,363.53048 L 488.07021,363.53048 L 488.07021,370.68199 L 497.10884,370.68199 L 497.10884,374.65494 L 488.07021,374.65494 L 488.07021,377.89957 L 498.79723,377.89957 L 498.79723,381.97162 L 483.43554,381.97162 L 483.43554,359.45843 z"
|
||||
id="path3243" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 434.43411,381.97162 L 429.07061,381.97162 L 425.36245,376.27726 C 424.93249,376.34332 424.46897,376.37636 424.03849,376.37636 L 422.4492,376.37636 L 422.4492,381.97162 L 417.81453,381.97162 L 417.81453,359.45843 L 424.03849,359.45843 C 430.32903,359.45843 434.10273,362.4713 434.10273,367.96694 C 434.10273,371.47637 432.547,373.69487 429.76589,374.95277 L 434.43411,381.97162 z M 423.90583,372.33734 C 427.68005,372.33734 429.3354,371.14604 429.3354,367.96694 C 429.3354,364.7889 427.61398,363.53048 423.90583,363.53048 L 422.4492,363.53048 L 422.4492,372.33734 L 423.90583,372.33734 z"
|
||||
id="path3245" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 549.09011,359.45843 L 553.72478,359.45843 L 553.72478,381.97162 L 549.09011,381.97162 L 549.09011,359.45843 z"
|
||||
id="path3247" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 502.73766,370.69825 C 502.73766,364.04381 507.86888,359.17686 514.32512,359.17686 C 518.39769,359.17686 521.31094,360.63296 523.33071,363.77849 L 519.78773,366.29481 C 518.72803,364.57287 516.90751,363.34801 514.32512,363.34801 C 510.25255,363.34801 507.50499,366.49354 507.50499,370.69825 C 507.50499,374.90295 510.25255,378.11455 514.32512,378.11455 C 517.23889,378.11455 518.86069,376.724 520.11911,374.80385 L 523.72816,377.28662 C 521.77446,380.33305 518.66249,382.25319 514.32512,382.25319 C 507.86941,382.25267 502.73766,377.35321 502.73766,370.69825 z"
|
||||
id="path3249" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 591.6007,371.50967 C 590.47546,370.44997 588.91921,368.43072 588.91921,368.43072 C 588.91921,368.43072 589.2506,370.91349 589.2506,372.53581 L 589.2506,381.97136 L 584.91376,381.97136 L 584.91376,359.25996 L 585.37728,359.25996 L 596.73297,369.92038 C 597.8257,370.94652 599.38143,372.99933 599.38143,372.99933 C 599.38143,372.99933 599.0836,370.45049 599.0836,368.89424 L 599.0836,359.45869 L 603.42044,359.45869 L 603.42044,382.17009 L 602.95693,382.17009 L 591.6007,371.50967 z"
|
||||
id="path3251" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
id="path3253"
|
||||
d="M 438.37455,370.71503 C 438.37455,364.06059 443.53985,359.1606 450.02912,359.1606 C 456.51787,359.1606 461.68265,364.06059 461.68265,370.71503 C 461.68265,377.36946 456.51787,382.26945 450.02912,382.26945 C 443.53985,382.26945 438.37455,377.36999 438.37455,370.71503 z M 456.91532,370.71503 C 456.91532,366.51032 454.13421,363.29872 450.02912,363.29872 C 445.92352,363.29872 443.1424,366.51032 443.1424,370.71503 C 443.1424,374.91973 445.92352,378.13133 450.02912,378.13133 C 454.13421,378.13133 456.91532,374.91973 456.91532,370.71503 z" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-opacity:1"
|
||||
d="M 557.66522,370.71503 C 557.66522,364.06059 562.83052,359.1606 569.31979,359.1606 C 575.80854,359.1606 580.97332,364.06059 580.97332,370.71503 C 580.97332,377.36946 575.80854,382.26945 569.31979,382.26945 C 562.83052,382.26945 557.66522,377.36999 557.66522,370.71503 z M 576.20599,370.71503 C 576.20599,366.51032 573.42488,363.29872 569.31979,363.29872 C 565.21419,363.29872 562.43307,366.51032 562.43307,370.71503 C 562.43307,374.91973 565.21419,378.13133 569.31979,378.13133 C 573.42488,378.13133 576.20599,374.91973 576.20599,370.71503 z"
|
||||
id="path3255" />
|
||||
</g>
|
||||
<g
|
||||
id="g4137"
|
||||
transform="translate(4.4621514,71.394422)"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1">
|
||||
<path
|
||||
d="M 22.673731,370.71529 C 22.673731,364.06085 27.839035,359.16086 34.328304,359.16086 C 40.81705,359.16086 45.981829,364.06085 45.981829,370.71529 C 45.981829,377.36973 40.81705,382.26971 34.328304,382.26971 C 27.839035,382.26971 22.673731,377.37025 22.673731,370.71529 z M 41.214502,370.71529 C 41.214502,366.51058 38.433386,363.29898 34.328304,363.29898 C 30.222698,363.29898 27.441583,366.51058 27.441583,370.71529 C 27.441583,374.91999 30.222698,378.1316 34.328304,378.1316 C 38.433386,378.1316 41.214502,374.91999 41.214502,370.71529 z"
|
||||
id="path4139"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 49.922267,359.45869 L 56.146219,359.45869 C 62.436763,359.45869 66.21046,362.73583 66.21046,368.16541 C 66.21046,373.59498 62.403205,376.83961 56.146219,376.83961 L 54.556936,376.83961 L 54.556936,381.97136 L 49.922267,381.97136 L 49.922267,359.45869 z M 56.013561,372.76809 C 59.787782,372.76809 61.443133,371.2454 61.443133,368.16593 C 61.443133,365.05343 59.721715,363.53074 56.013561,363.53074 L 54.556936,363.53074 L 54.556936,372.76809 L 56.013561,372.76809 L 56.013561,372.76809 z"
|
||||
id="path4141"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 70.150962,359.45843 L 85.049122,359.45843 L 85.049122,363.53048 L 74.785631,363.53048 L 74.785631,370.68199 L 83.824257,370.68199 L 83.824257,374.65494 L 74.785631,374.65494 L 74.785631,377.89957 L 85.512641,377.89957 L 85.512641,381.97162 L 70.150962,381.97162 L 70.150962,359.45843 z"
|
||||
id="path4143"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 209.80292,381.97162 L 204.43941,381.97162 L 200.73126,376.27726 C 200.3013,376.34332 199.83778,376.37636 199.40729,376.37636 L 197.81801,376.37636 L 197.81801,381.97162 L 193.18334,381.97162 L 193.18334,359.45843 L 199.40729,359.45843 C 205.69784,359.45843 209.47153,362.4713 209.47153,367.96694 C 209.47153,371.47637 207.91581,373.69487 205.13469,374.95277 L 209.80292,381.97162 z M 199.27463,372.33734 C 203.04886,372.33734 204.70421,371.14604 204.70421,367.96694 C 204.70421,364.7889 202.98279,363.53048 199.27463,363.53048 L 197.81801,363.53048 L 197.81801,372.33734 L 199.27463,372.33734 z"
|
||||
id="path4145"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 534.09128,363.53048 L 527.6686,363.53048 L 527.6686,359.45843 L 545.14968,359.45843 L 545.14968,363.53048 L 538.72647,363.53048 L 538.72647,381.97162 L 534.09128,381.97162 L 534.09128,363.53048 z"
|
||||
id="path4147"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 295.01444,374.82011 L 286.47289,359.45843 L 291.60463,359.45843 L 295.57706,366.70904 C 296.43803,368.2978 297.3981,370.97982 297.3981,370.97982 C 297.3981,370.97982 298.2921,368.33136 299.15308,366.70904 L 302.96086,359.45843 L 307.69462,359.45843 L 299.68319,374.48925 L 299.68319,381.97162 L 295.01496,381.97162 L 295.01496,374.82011 L 295.01444,374.82011 z"
|
||||
id="path4149"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 171.03352,373.67756 L 171.03352,359.30951 L 175.66819,359.30951 L 175.66819,373.41329 C 175.66819,376.69044 177.0923,377.94834 180.17124,377.94834 C 183.21715,377.94834 184.60771,376.69044 184.60771,373.41329 L 184.60771,359.30951 L 189.2429,359.30951 L 189.2429,373.67756 C 189.2429,379.37193 185.30247,382.12054 180.17124,382.12054 C 174.97291,382.12001 171.03352,379.37193 171.03352,373.67756 z"
|
||||
id="path4151"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 332.19508,359.45843 L 336.82975,359.45843 L 336.82975,381.97162 L 332.19508,381.97162 L 332.19508,359.45843 z"
|
||||
id="path4153"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 123.72152,377.51864 L 127.49574,375.3337 C 128.48885,376.95602 129.77978,378.14785 132.06434,378.14785 C 133.98448,378.14785 135.20987,377.18778 135.20987,375.86329 C 135.20987,374.27453 133.95198,373.71138 131.83311,372.78435 L 130.67431,372.28779 C 127.33005,370.8642 125.11208,369.07672 125.11208,365.30249 C 125.11208,361.8261 127.76106,359.17712 131.89917,359.17712 C 134.84546,359.17712 136.96433,360.20378 138.48754,362.88527 L 134.87849,365.20287 C 134.08359,363.77928 133.22314,363.21666 131.89865,363.21666 C 130.54112,363.21666 129.68068,364.07763 129.68068,365.20287 C 129.68068,366.59343 130.54165,367.15657 132.52786,368.01702 L 133.68666,368.51357 C 137.62657,370.20196 139.84454,371.92337 139.84454,375.79722 C 139.84454,379.96889 136.5674,382.25293 132.16397,382.25293 C 127.86016,382.25293 125.07904,380.20013 123.72152,377.51864 z"
|
||||
id="path4155"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 465.62309,377.8828 L 469.39678,375.59876 C 470.12562,376.88969 470.78734,377.98242 472.37663,377.98242 C 473.89984,377.98242 474.85991,377.38624 474.85991,375.06865 L 474.85991,359.30951 L 479.49511,359.30951 L 479.49511,375.13471 C 479.49511,379.9356 476.68096,382.12054 472.57535,382.12054 C 468.8672,382.12054 466.71529,380.20039 465.62309,377.8828 z"
|
||||
id="path4157"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 269.79773,359.45843 L 274.4324,359.45843 L 274.4324,377.89905 L 284.62982,377.89905 L 284.62982,381.97162 L 269.79773,381.97162 L 269.79773,359.45843 z"
|
||||
id="path4159"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 213.74336,370.69825 C 213.74336,364.04381 218.87458,359.17686 225.33082,359.17686 C 229.40339,359.17686 232.31664,360.63296 234.33641,363.77849 L 230.79342,366.29481 C 229.73372,364.57287 227.9132,363.34801 225.33082,363.34801 C 221.25824,363.34801 218.51068,366.49354 218.51068,370.69825 C 218.51068,374.90295 221.25824,378.11455 225.33082,378.11455 C 228.24459,378.11455 229.86638,376.724 231.12481,374.80385 L 234.73386,377.28662 C 232.78016,380.33305 229.66818,382.25319 225.33082,382.25319 C 218.8751,382.25267 213.74336,377.35321 213.74336,370.69825 z"
|
||||
id="path4161"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 96.140027,371.50967 C 95.014786,370.44997 93.458536,368.43072 93.458536,368.43072 C 93.458536,368.43072 93.789921,370.91349 93.789921,372.53581 L 93.789921,381.97136 L 89.45308,381.97136 L 89.45308,359.25996 L 89.916599,359.25996 L 101.2723,369.92038 C 102.36503,370.94652 103.92075,372.99933 103.92075,372.99933 C 103.92075,372.99933 103.62293,370.45049 103.62293,368.89424 L 103.62293,359.45869 L 107.95977,359.45869 L 107.95977,382.17009 L 107.49625,382.17009 L 96.140027,371.50967 z"
|
||||
id="path4163"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4165"
|
||||
d="M 143.78498,370.71503 C 143.78498,364.06059 148.95028,359.1606 155.43955,359.1606 C 161.9283,359.1606 167.09308,364.06059 167.09308,370.71503 C 167.09308,377.36946 161.9283,382.26945 155.43955,382.26945 C 148.95028,382.26945 143.78498,377.36999 143.78498,370.71503 z M 162.32575,370.71503 C 162.32575,366.51032 159.54464,363.29872 155.43955,363.29872 C 151.33395,363.29872 148.55283,366.51032 148.55283,370.71503 C 148.55283,374.91973 151.33395,378.13133 155.43955,378.13133 C 159.54464,378.13133 162.32575,374.91973 162.32575,370.71503 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4167"
|
||||
d="M 238.6743,359.45843 L 253.57246,359.45843 L 253.57246,363.53048 L 243.30897,363.53048 L 243.30897,370.68199 L 252.34759,370.68199 L 252.34759,374.65494 L 243.30897,374.65494 L 243.30897,377.89957 L 254.03598,377.89957 L 254.03598,381.97162 L 238.6743,381.97162 L 238.6743,359.45843 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4169"
|
||||
d="M 328.25464,381.97162 L 322.89114,381.97162 L 319.18298,376.27726 C 318.75302,376.34332 318.2895,376.37636 317.85901,376.37636 L 316.26973,376.37636 L 316.26973,381.97162 L 311.63506,381.97162 L 311.63506,359.45843 L 317.85901,359.45843 C 324.14956,359.45843 327.92326,362.4713 327.92326,367.96694 C 327.92326,371.47637 326.36753,373.69487 323.58641,374.95277 L 328.25464,381.97162 z M 317.72636,372.33734 C 321.50058,372.33734 323.15593,371.14604 323.15593,367.96694 C 323.15593,364.7889 321.43451,363.53048 317.72636,363.53048 L 316.26973,363.53048 L 316.26973,372.33734 L 317.72636,372.33734 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4171"
|
||||
d="M 365.70113,377.51864 L 369.47535,375.3337 C 370.46845,376.95602 371.75938,378.14785 374.04395,378.14785 C 375.96409,378.14785 377.18948,377.18778 377.18948,375.86329 C 377.18948,374.27453 375.93158,373.71138 373.81271,372.78435 L 372.65391,372.28779 C 369.30965,370.8642 367.09168,369.07672 367.09168,365.30249 C 367.09168,361.8261 369.74066,359.17712 373.87878,359.17712 C 376.82506,359.17712 378.94393,360.20378 380.46715,362.88527 L 376.8581,365.20287 C 376.06319,363.77928 375.20275,363.21666 373.87826,363.21666 C 372.52073,363.21666 371.66028,364.07763 371.66028,365.20287 C 371.66028,366.59343 372.52126,367.15657 374.50747,368.01702 L 375.66627,368.51357 C 379.60618,370.20196 381.82415,371.92337 381.82415,375.79722 C 381.82415,379.96889 378.54701,382.25293 374.14357,382.25293 C 369.83976,382.25293 367.05865,380.20013 365.70113,377.51864 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4173"
|
||||
d="M 340.77019,370.69825 C 340.77019,364.04381 345.90141,359.17686 352.35764,359.17686 C 356.43022,359.17686 359.34347,360.63296 361.36323,363.77849 L 357.82025,366.29481 C 356.76055,364.57287 354.94003,363.34801 352.35764,363.34801 C 348.28507,363.34801 345.53751,366.49354 345.53751,370.69825 C 345.53751,374.90295 348.28507,378.11455 352.35764,378.11455 C 355.27142,378.11455 356.89321,376.724 358.15163,374.80385 L 361.76069,377.28662 C 359.80698,380.33305 356.69501,382.25319 352.35764,382.25319 C 345.90193,382.25267 340.77019,377.35321 340.77019,370.69825 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4175"
|
||||
d="M 397.5859,359.45869 L 403.80985,359.45869 C 410.1004,359.45869 413.8741,362.73583 413.8741,368.16541 C 413.8741,373.59498 410.06684,376.83961 403.80985,376.83961 L 402.22057,376.83961 L 402.22057,381.97136 L 397.5859,381.97136 L 397.5859,359.45869 z M 403.6772,372.76809 C 407.45142,372.76809 409.10677,371.2454 409.10677,368.16593 C 409.10677,365.05343 407.38535,363.53074 403.6772,363.53074 L 402.22057,363.53074 L 402.22057,372.76809 L 403.6772,372.76809 L 403.6772,372.76809 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4177"
|
||||
d="M 483.43554,359.45843 L 498.33371,359.45843 L 498.33371,363.53048 L 488.07021,363.53048 L 488.07021,370.68199 L 497.10884,370.68199 L 497.10884,374.65494 L 488.07021,374.65494 L 488.07021,377.89957 L 498.79723,377.89957 L 498.79723,381.97162 L 483.43554,381.97162 L 483.43554,359.45843 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4179"
|
||||
d="M 434.43411,381.97162 L 429.07061,381.97162 L 425.36245,376.27726 C 424.93249,376.34332 424.46897,376.37636 424.03849,376.37636 L 422.4492,376.37636 L 422.4492,381.97162 L 417.81453,381.97162 L 417.81453,359.45843 L 424.03849,359.45843 C 430.32903,359.45843 434.10273,362.4713 434.10273,367.96694 C 434.10273,371.47637 432.547,373.69487 429.76589,374.95277 L 434.43411,381.97162 z M 423.90583,372.33734 C 427.68005,372.33734 429.3354,371.14604 429.3354,367.96694 C 429.3354,364.7889 427.61398,363.53048 423.90583,363.53048 L 422.4492,363.53048 L 422.4492,372.33734 L 423.90583,372.33734 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4181"
|
||||
d="M 549.09011,359.45843 L 553.72478,359.45843 L 553.72478,381.97162 L 549.09011,381.97162 L 549.09011,359.45843 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4183"
|
||||
d="M 502.73766,370.69825 C 502.73766,364.04381 507.86888,359.17686 514.32512,359.17686 C 518.39769,359.17686 521.31094,360.63296 523.33071,363.77849 L 519.78773,366.29481 C 518.72803,364.57287 516.90751,363.34801 514.32512,363.34801 C 510.25255,363.34801 507.50499,366.49354 507.50499,370.69825 C 507.50499,374.90295 510.25255,378.11455 514.32512,378.11455 C 517.23889,378.11455 518.86069,376.724 520.11911,374.80385 L 523.72816,377.28662 C 521.77446,380.33305 518.66249,382.25319 514.32512,382.25319 C 507.86941,382.25267 502.73766,377.35321 502.73766,370.69825 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4185"
|
||||
d="M 591.6007,371.50967 C 590.47546,370.44997 588.91921,368.43072 588.91921,368.43072 C 588.91921,368.43072 589.2506,370.91349 589.2506,372.53581 L 589.2506,381.97136 L 584.91376,381.97136 L 584.91376,359.25996 L 585.37728,359.25996 L 596.73297,369.92038 C 597.8257,370.94652 599.38143,372.99933 599.38143,372.99933 C 599.38143,372.99933 599.0836,370.45049 599.0836,368.89424 L 599.0836,359.45869 L 603.42044,359.45869 L 603.42044,382.17009 L 602.95693,382.17009 L 591.6007,371.50967 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
d="M 438.37455,370.71503 C 438.37455,364.06059 443.53985,359.1606 450.02912,359.1606 C 456.51787,359.1606 461.68265,364.06059 461.68265,370.71503 C 461.68265,377.36946 456.51787,382.26945 450.02912,382.26945 C 443.53985,382.26945 438.37455,377.36999 438.37455,370.71503 z M 456.91532,370.71503 C 456.91532,366.51032 454.13421,363.29872 450.02912,363.29872 C 445.92352,363.29872 443.1424,366.51032 443.1424,370.71503 C 443.1424,374.91973 445.92352,378.13133 450.02912,378.13133 C 454.13421,378.13133 456.91532,374.91973 456.91532,370.71503 z"
|
||||
id="path4187"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4189"
|
||||
d="M 557.66522,370.71503 C 557.66522,364.06059 562.83052,359.1606 569.31979,359.1606 C 575.80854,359.1606 580.97332,364.06059 580.97332,370.71503 C 580.97332,377.36946 575.80854,382.26945 569.31979,382.26945 C 562.83052,382.26945 557.66522,377.36999 557.66522,370.71503 z M 576.20599,370.71503 C 576.20599,366.51032 573.42488,363.29872 569.31979,363.29872 C 565.21419,363.29872 562.43307,366.51032 562.43307,370.71503 C 562.43307,374.91973 565.21419,378.13133 569.31979,378.13133 C 573.42488,378.13133 576.20599,374.91973 576.20599,370.71503 z"
|
||||
style="fill:#000d26;fill-opacity:1;stroke:#cdcdff;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 69 KiB |
|
@ -1,296 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="370"
|
||||
height="370"
|
||||
id="svg4079"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.47pre4 r22446"
|
||||
sodipodi:docname="openlp-splash-screen.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.0"
|
||||
inkscape:export-filename="/home/raoul/Projects/openlp/bitsandbobs/resources/images/openlp-splash-screen2.png"
|
||||
inkscape:export-xdpi="53.549999"
|
||||
inkscape:export-ydpi="53.549999">
|
||||
<defs
|
||||
id="defs4081">
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter4005">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="4.333215"
|
||||
id="feGaussianBlur4007" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
id="linearGradient3208">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.25098041;"
|
||||
offset="0"
|
||||
id="stop3210" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3212" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3208"
|
||||
id="linearGradient4051"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1122448,0,0,1.2037738,-57.29825,4.8849318)"
|
||||
x1="470.25891"
|
||||
y1="276.68851"
|
||||
x2="469.44925"
|
||||
y2="104.30029" />
|
||||
<linearGradient
|
||||
id="linearGradient6359">
|
||||
<stop
|
||||
style="stop-color:#000d26;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6361" />
|
||||
<stop
|
||||
style="stop-color:#507fda;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop6363" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6359"
|
||||
id="linearGradient4049"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="815.75"
|
||||
y1="480.55844"
|
||||
x2="201.10622"
|
||||
y2="371.85938" />
|
||||
<linearGradient
|
||||
id="linearGradient3195">
|
||||
<stop
|
||||
style="stop-color:#cdcdff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3197" />
|
||||
<stop
|
||||
style="stop-color:#ebebff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3199" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3195"
|
||||
id="linearGradient4047"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="117.59262"
|
||||
y1="384.05795"
|
||||
x2="418.20981"
|
||||
y2="436.03787" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter6926">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="3.5771872"
|
||||
id="feGaussianBlur6928" />
|
||||
</filter>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective4087" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3195"
|
||||
id="linearGradient3817"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="117.59262"
|
||||
y1="384.05795"
|
||||
x2="418.20981"
|
||||
y2="436.03787" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6359"
|
||||
id="linearGradient3819"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="815.75"
|
||||
y1="480.55844"
|
||||
x2="201.10622"
|
||||
y2="371.85938" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3208"
|
||||
id="linearGradient3821"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1122448,0,0,1.2037738,-57.29825,4.8849318)"
|
||||
x1="470.25891"
|
||||
y1="276.68851"
|
||||
x2="469.44925"
|
||||
y2="104.30029" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3208"
|
||||
id="linearGradient3824"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.55571269,0,0,0.60144348,-66.059425,16.146882)"
|
||||
x1="470.25891"
|
||||
y1="276.68851"
|
||||
x2="469.44925"
|
||||
y2="104.30029" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient6359"
|
||||
id="linearGradient3827"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="815.75"
|
||||
y1="480.55844"
|
||||
x2="201.10622"
|
||||
y2="371.85938"
|
||||
gradientTransform="matrix(0.49963164,0,0,0.49963164,-37.431406,13.706216)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:cx="224.70154"
|
||||
inkscape:cy="190.60628"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="961"
|
||||
inkscape:window-x="-3"
|
||||
inkscape:window-y="-4"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata4084">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-13.571437,-14.505051)">
|
||||
<g
|
||||
id="g3832">
|
||||
<path
|
||||
transform="matrix(0.48921117,0,0,0.48921117,-33.956187,6.1348916)"
|
||||
d="m 833.03006,395.26932 c 0,197.56259 -160.15613,357.71872 -357.71872,357.71872 -197.56259,0 -357.71872,-160.15613 -357.71872,-357.71872 0,-197.5626 160.15613,-357.718722 357.71872,-357.718722 197.56259,0 357.71872,160.156122 357.71872,357.718722 z"
|
||||
sodipodi:ry="357.71872"
|
||||
sodipodi:rx="357.71872"
|
||||
sodipodi:cy="395.26932"
|
||||
sodipodi:cx="475.31134"
|
||||
id="path3206"
|
||||
style="fill:#051e52;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
|
||||
sodipodi:type="arc"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#linearGradient3817);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
|
||||
id="path3208"
|
||||
sodipodi:cx="475.31134"
|
||||
sodipodi:cy="395.26932"
|
||||
sodipodi:rx="357.71872"
|
||||
sodipodi:ry="357.71872"
|
||||
d="m 833.03006,395.26932 c 0,197.56259 -160.15613,357.71872 -357.71872,357.71872 -197.56259,0 -357.71872,-160.15613 -357.71872,-357.71872 0,-197.5626 160.15613,-357.718722 357.71872,-357.718722 197.56259,0 357.71872,160.156122 357.71872,357.718722 z"
|
||||
transform="matrix(0.48441496,0,0,0.48441496,-31.676504,8.0306779)"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:url(#linearGradient3827);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
|
||||
d="m 198.56648,27.930104 c -27.54972,0 -53.58518,6.509173 -76.66223,18.064807 l 123.47147,99.051969 119.693,96.02296 c 3.31607,-13.31039 5.07438,-27.23088 5.07438,-41.56311 0,-94.70587 -76.87075,-171.576625 -171.57662,-171.576626 z M 78.514361,76.987686 C 72.400709,82.979164 66.740672,89.426585 61.573726,96.270345 L 228.43508,178.55343 350.79799,238.89956 228.95033,166.43736 78.514361,76.987686 z m -41.89099,65.748404 c -2.781874,7.92747 -4.987533,16.11884 -6.588892,24.52879 L 217.3495,213.54326 342.19496,244.39551 217.38073,202.86363 36.623371,142.73609 z m -8.41567,77.0994 c 1.000717,8.46362 2.605124,16.73744 4.793341,24.77861 l 175.245798,4.99632 133.01131,3.80969 L 212.27512,239.57094 28.207701,219.83549 z M 346.42621,261.44544 209.38662,276.07528 54.485202,292.60997 c 4.569566,7.05386 9.634722,13.75734 15.160698,20.04772 L 205.29589,287.5512 346.42621,261.44544 z m 10.57034,3.99706 -144.44039,47.68359 -101.98731,33.66268 c 25.73655,15.42002 55.8325,24.27897 87.99763,24.27898 71.34607,0 132.5703,-43.61534 158.43007,-105.62525 z"
|
||||
id="path3210"
|
||||
inkscape:export-filename="/home/raoul/openlp-logo-0.2.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90" />
|
||||
<path
|
||||
style="fill:url(#linearGradient3824);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
|
||||
d="m 198.56648,27.930104 c -27.54972,0 -53.58518,6.509173 -76.66223,18.064807 l 123.47147,99.051969 40.29841,32.33554 c 30.01879,-3.7382 57.18585,-9.37467 80.0972,-16.44101 C 348.25699,84.782754 280.01453,27.930105 198.56648,27.930104 z M 78.514361,76.987686 C 72.400709,82.979164 66.740672,89.426585 61.573726,96.270345 l 166.861354,82.283085 6.38592,3.15392 c 6.06816,-0.29151 12.05789,-0.65773 17.97112,-1.09294 L 228.95033,166.43736 78.514361,76.987686 z m -41.89099,65.748404 c -2.04108,5.81644 -3.774072,11.77916 -5.183678,17.86183 32.684548,10.21166 74.160317,17.47024 120.348767,20.45367 L 36.623371,142.73609 z"
|
||||
id="path3212" />
|
||||
<g
|
||||
style="fill:#ffffff;fill-opacity:1;filter:url(#filter4005)"
|
||||
id="g2762"
|
||||
transform="matrix(0.6503605,0,0,0.6503605,-391.52146,-496.40149)">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2764"
|
||||
d="m 801.444,1038.553 15.617,0 c 18.862,0 28.496,10.444 28.496,25.961 0,15.212 -9.634,25.859 -28.496,25.859 l -8.316,0 0,17.139 -7.301,0 0,-68.959 0,0 z m 15.211,45.431 c 15.517,0 21.297,-8.112 21.297,-19.471 0,-11.359 -5.78,-19.471 -21.297,-19.471 l -7.91,0 0,38.941 7.91,0 0,10e-4 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2766"
|
||||
d="m 852.858,1038.553 41.984,0 0,6.49 -34.684,0 0,32.35 30.931,0 0,6.389 -30.931,0 0,17.24 36.103,0 0,6.49 -43.403,0 0,-68.959 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2768"
|
||||
d="m 913.197,1059.545 c -1.927,-2.333 -4.767,-6.39 -4.767,-6.39 0,0 0.608,4.868 0.608,7.81 l 0,46.547 -6.896,0 0,-69.669 1.217,0 41.173,48.677 c 1.927,2.333 4.259,5.163 4.259,5.163 0,0 0,-3.642 0,-6.582 l 0,-46.548 6.795,0 0,69.669 -1.217,0 -41.172,-48.677 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2770"
|
||||
d="m 677.015,1070.032 c 0,-34.836 26.253,-58.564 58.564,-58.564 32.311,0 58.564,23.729 58.564,58.564 0,34.835 -26.253,58.564 -58.564,58.564 -32.311,0 -58.564,-23.728 -58.564,-58.564 z m 110.06,0 c 0,-29.955 -22.045,-52.338 -51.496,-52.338 -29.451,0 -51.496,22.383 -51.496,52.338 0,29.956 22.045,52.338 51.496,52.338 29.451,0 51.496,-22.382 51.496,-52.338 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2772"
|
||||
d="m 967.521,1012.814 23.561,0 0,93.737 51.833,0 0,20.699 -75.394,0 0,-114.436 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1"
|
||||
id="path2774"
|
||||
d="m 1054.85,1012.814 31.639,0 c 31.975,0 51.16,16.661 51.16,44.26 0,27.6 -19.354,44.092 -51.16,44.092 l -8.078,0 0,26.085 -23.561,0 0,-114.437 z m 30.965,67.653 c 19.185,0 27.599,-7.741 27.599,-23.393 0,-15.819 -8.751,-23.561 -27.599,-23.561 l -7.405,0 0,46.953 7.405,0 0,0 z" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
transform="matrix(0.6503605,0,0,0.6503605,-391.52146,-496.40149)"
|
||||
id="g3221">
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="m 801.444,1038.553 15.617,0 c 18.862,0 28.496,10.444 28.496,25.961 0,15.212 -9.634,25.859 -28.496,25.859 l -8.316,0 0,17.139 -7.301,0 0,-68.959 0,0 z m 15.211,45.431 c 15.517,0 21.297,-8.112 21.297,-19.471 0,-11.359 -5.78,-19.471 -21.297,-19.471 l -7.91,0 0,38.941 7.91,0 0,10e-4 z"
|
||||
id="path3223" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="m 852.858,1038.553 41.984,0 0,6.49 -34.684,0 0,32.35 30.931,0 0,6.389 -30.931,0 0,17.24 36.103,0 0,6.49 -43.403,0 0,-68.959 z"
|
||||
id="path3225" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="m 913.197,1059.545 c -1.927,-2.333 -4.767,-6.39 -4.767,-6.39 0,0 0.608,4.868 0.608,7.81 l 0,46.547 -6.896,0 0,-69.669 1.217,0 41.173,48.677 c 1.927,2.333 4.259,5.163 4.259,5.163 0,0 0,-3.642 0,-6.582 l 0,-46.548 6.795,0 0,69.669 -1.217,0 -41.172,-48.677 z"
|
||||
id="path3227" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="m 677.015,1070.032 c 0,-34.836 26.253,-58.564 58.564,-58.564 32.311,0 58.564,23.729 58.564,58.564 0,34.835 -26.253,58.564 -58.564,58.564 -32.311,0 -58.564,-23.728 -58.564,-58.564 z m 110.06,0 c 0,-29.955 -22.045,-52.338 -51.496,-52.338 -29.451,0 -51.496,22.383 -51.496,52.338 0,29.956 22.045,52.338 51.496,52.338 29.451,0 51.496,-22.382 51.496,-52.338 z"
|
||||
id="path3229" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="m 967.521,1012.814 23.561,0 0,93.737 51.833,0 0,20.699 -75.394,0 0,-114.436 z"
|
||||
id="path3231" />
|
||||
<path
|
||||
style="fill:#000d26;fill-opacity:1"
|
||||
d="m 1054.85,1012.814 31.639,0 c 31.975,0 51.16,16.661 51.16,44.26 0,27.6 -19.354,44.092 -51.16,44.092 l -8.078,0 0,26.085 -23.561,0 0,-114.437 z m 30.965,67.653 c 19.185,0 27.599,-7.741 27.599,-23.393 0,-15.819 -8.751,-23.561 -27.599,-23.561 l -7.405,0 0,46.953 7.405,0 0,0 z"
|
||||
id="path3233" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 531 B |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 170 B |