mirror of https://gitlab.com/openlp/openlp.git
Head 2087
This commit is contained in:
commit
7ce17e99f8
|
@ -29,12 +29,12 @@
|
|||
The :mod:`advancedtab` provides an advanced settings facility.
|
||||
"""
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import SettingsTab, translate, build_icon, Receiver
|
||||
from openlp.core.lib.settings import Settings
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
@ -432,8 +432,7 @@ class AdvancedTab(SettingsTab):
|
|||
translate('OpenLP.AdvancedTab',
|
||||
'<strong>WARNING:</strong> New data directory location contains '
|
||||
'OpenLP data files. These files WILL be replaced during a copy.'))
|
||||
self.x11GroupBox.setTitle(translate('OpenLP.AdvancedTab',
|
||||
'X11'))
|
||||
self.x11GroupBox.setTitle(translate('OpenLP.AdvancedTab', 'X11'))
|
||||
self.x11BypassCheckBox.setText(translate('OpenLP.AdvancedTab',
|
||||
'Bypass X11 Window Manager'))
|
||||
# Slide Limits
|
||||
|
@ -493,8 +492,14 @@ class AdvancedTab(SettingsTab):
|
|||
QtCore.QVariant(True)).toBool()
|
||||
self.serviceNameCheckBox.setChecked(default_service_enabled)
|
||||
self.serviceNameCheckBoxToggled(default_service_enabled)
|
||||
self.x11BypassCheckBox.setChecked(
|
||||
settings.value(u'x11 bypass wm', QtCore.QVariant(True)).toBool())
|
||||
# Fix for bug #1014422.
|
||||
x11_bypass_default = True
|
||||
if sys.platform.startswith(u'linux'):
|
||||
# Default to False on Gnome.
|
||||
x11_bypass_default = bool(not
|
||||
os.environ.get(u'GNOME_DESKTOP_SESSION_ID'))
|
||||
self.x11BypassCheckBox.setChecked(settings.value(
|
||||
u'x11 bypass wm', QtCore.QVariant(x11_bypass_default)).toBool())
|
||||
self.defaultColor = settings.value(u'default color',
|
||||
QtCore.QVariant(u'#ffffff')).toString()
|
||||
self.defaultFileEdit.setText(settings.value(u'default image',
|
||||
|
@ -766,7 +771,7 @@ class AdvancedTab(SettingsTab):
|
|||
self.dataExists = False
|
||||
self.dataDirectoryCopyCheckBox.setChecked(True)
|
||||
self.newDataDirectoryHasFilesLabel.hide()
|
||||
|
||||
|
||||
def onDataDirectoryCancelButtonClicked(self):
|
||||
"""
|
||||
Cancel the data directory location change
|
||||
|
|
|
@ -31,6 +31,7 @@ and play multimedia within OpenLP.
|
|||
"""
|
||||
import cgi
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
|
||||
|
@ -135,8 +136,14 @@ class MainDisplay(Display):
|
|||
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
|
||||
windowFlags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | \
|
||||
QtCore.Qt.WindowStaysOnTopHint
|
||||
# Fix for bug #1014422.
|
||||
x11_bypass_default = True
|
||||
if sys.platform.startswith(u'linux'):
|
||||
# Default to False on Gnome.
|
||||
x11_bypass_default = bool(not
|
||||
os.environ.get(u'GNOME_DESKTOP_SESSION_ID'))
|
||||
if Settings().value(u'advanced/x11 bypass wm',
|
||||
QtCore.QVariant(True)).toBool():
|
||||
QtCore.QVariant(x11_bypass_default)).toBool():
|
||||
windowFlags |= QtCore.Qt.X11BypassWindowManagerHint
|
||||
# TODO: The following combination of windowFlags works correctly
|
||||
# on Mac OS X. For next OpenLP version we should test it on other
|
||||
|
|
|
@ -30,7 +30,6 @@ import os
|
|||
import zipfile
|
||||
import shutil
|
||||
import logging
|
||||
import locale
|
||||
import re
|
||||
|
||||
from xml.etree.ElementTree import ElementTree, XML
|
||||
|
@ -46,7 +45,8 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
|||
create_widget_action
|
||||
from openlp.core.theme import Theme
|
||||
from openlp.core.ui import FileRenameForm, ThemeForm
|
||||
from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding
|
||||
from openlp.core.utils import AppLocation, delete_file, locale_compare, \
|
||||
get_filesystem_encoding
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -457,9 +457,8 @@ class ThemeManager(QtGui.QWidget):
|
|||
self.configUpdated()
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
||||
# Sort the themes by its name considering language specific characters.
|
||||
# lower() is needed for windows!
|
||||
files.sort(key=lambda file_name: unicode(file_name).lower(),
|
||||
cmp=locale.strcoll)
|
||||
files.sort(key=lambda file_name: unicode(file_name),
|
||||
cmp=locale_compare)
|
||||
# now process the file list of png files
|
||||
for name in files:
|
||||
# check to see file is in theme root directory
|
||||
|
|
|
@ -488,10 +488,24 @@ def format_time(text, local_time):
|
|||
return re.sub('\%[a-zA-Z]', match_formatting, text)
|
||||
|
||||
|
||||
def locale_compare(string1, string2):
|
||||
"""
|
||||
Compares two strings according to the current locale settings.
|
||||
|
||||
As any other compare function, returns a negative, or a positive value,
|
||||
or 0, depending on whether string1 collates before or after string2 or
|
||||
is equal to it. Comparison is case insensitive.
|
||||
"""
|
||||
# Function locale.strcol() from standard Python library does not work
|
||||
# properly on Windows and probably somewhere else.
|
||||
return int(QtCore.QString.localeAwareCompare(
|
||||
QtCore.QString(string1).toLower(), QtCore.QString(string2).toLower()))
|
||||
|
||||
|
||||
from languagemanager import LanguageManager
|
||||
from actions import ActionList
|
||||
|
||||
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
||||
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
||||
u'ActionList', u'get_web_page', u'get_uno_command', u'get_uno_instance',
|
||||
u'delete_file', u'clean_filename', u'format_time']
|
||||
u'delete_file', u'clean_filename', u'format_time', u'locale_compare']
|
||||
|
|
|
@ -105,6 +105,7 @@ CSS = """
|
|||
font-size: %spt;
|
||||
color: %s;
|
||||
background-color: %s;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
"""
|
||||
|
||||
|
|
|
@ -80,6 +80,10 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
|||
item_name = QtGui.QListWidgetItem(alert.text)
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
|
||||
self.alertListWidget.addItem(item_name)
|
||||
if alert.text == unicode(self.alertTextEdit.text()):
|
||||
self.item_id = alert.id
|
||||
self.alertListWidget.setCurrentRow(
|
||||
self.alertListWidget.row(item_name))
|
||||
|
||||
def onDisplayClicked(self):
|
||||
self.triggerAlert(unicode(self.alertTextEdit.text()))
|
||||
|
@ -112,7 +116,6 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
|||
alert = AlertItem()
|
||||
alert.text = unicode(self.alertTextEdit.text())
|
||||
self.manager.save_object(alert)
|
||||
self.alertTextEdit.setText(u'')
|
||||
self.loadList()
|
||||
|
||||
def onSaveClick(self):
|
||||
|
@ -125,6 +128,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
|||
self.manager.save_object(alert)
|
||||
self.item_id = None
|
||||
self.loadList()
|
||||
self.saveButton.setEnabled(False)
|
||||
|
||||
def onTextChanged(self):
|
||||
"""
|
||||
|
|
|
@ -57,8 +57,6 @@ class AlertsManager(QtCore.QObject):
|
|||
"""
|
||||
if message:
|
||||
self.displayAlert(message[0])
|
||||
else:
|
||||
self.displayAlert(u'')
|
||||
|
||||
def displayAlert(self, text=u''):
|
||||
"""
|
||||
|
@ -68,14 +66,15 @@ class AlertsManager(QtCore.QObject):
|
|||
display text
|
||||
"""
|
||||
log.debug(u'display alert called %s' % text)
|
||||
self.alertList.append(text)
|
||||
if self.timer_id != 0:
|
||||
Receiver.send_message(u'mainwindow_status_text',
|
||||
translate('AlertsPlugin.AlertsManager',
|
||||
'Alert message created and displayed.'))
|
||||
return
|
||||
Receiver.send_message(u'mainwindow_status_text', u'')
|
||||
self.generateAlert()
|
||||
if text:
|
||||
self.alertList.append(text)
|
||||
if self.timer_id != 0:
|
||||
Receiver.send_message(u'mainwindow_status_text',
|
||||
translate('AlertsPlugin.AlertsManager',
|
||||
'Alert message created and displayed.'))
|
||||
return
|
||||
Receiver.send_message(u'mainwindow_status_text', u'')
|
||||
self.generateAlert()
|
||||
|
||||
def generateAlert(self):
|
||||
"""
|
||||
|
|
|
@ -30,7 +30,6 @@ The bible import functions for OpenLP
|
|||
"""
|
||||
import logging
|
||||
import os
|
||||
import locale
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
@ -39,7 +38,7 @@ from openlp.core.lib.db import delete_database
|
|||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.core.lib.settings import Settings
|
||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||
from openlp.core.utils import AppLocation
|
||||
from openlp.core.utils import AppLocation, locale_compare
|
||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB, clean_filename
|
||||
|
||||
|
@ -523,7 +522,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
"""
|
||||
self.webTranslationComboBox.clear()
|
||||
bibles = self.web_bible_list[index].keys()
|
||||
bibles.sort(cmp=locale.strcoll)
|
||||
bibles.sort(cmp=locale_compare)
|
||||
self.webTranslationComboBox.addItems(bibles)
|
||||
|
||||
def onOsisBrowseButtonClicked(self):
|
||||
|
|
|
@ -355,37 +355,8 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False):
|
|||
log.debug(u'Matched reference %s' % reference)
|
||||
book = match.group(u'book')
|
||||
if not book_ref_id:
|
||||
book_names = BibleStrings().BookNames
|
||||
# escape reserved characters
|
||||
book_escaped = book
|
||||
for character in u'\\.^$*+?{}[]()':
|
||||
book_escaped = book_escaped.replace(
|
||||
character, u'\\' + character)
|
||||
regex_book = re.compile(u'\s*%s\s*' % u'\s*'.join(
|
||||
book_escaped.split()), re.UNICODE | re.IGNORECASE)
|
||||
if language_selection == LanguageSelection.Bible:
|
||||
db_book = bible.get_book(book)
|
||||
if db_book:
|
||||
book_ref_id = db_book.book_reference_id
|
||||
elif language_selection == LanguageSelection.Application:
|
||||
books = filter(lambda key:
|
||||
regex_book.match(unicode(book_names[key])), book_names.keys())
|
||||
books = filter(None, map(BiblesResourcesDB.get_book, books))
|
||||
for value in books:
|
||||
if bible.get_book_by_book_ref_id(value[u'id']):
|
||||
book_ref_id = value[u'id']
|
||||
break
|
||||
elif language_selection == LanguageSelection.English:
|
||||
books = BiblesResourcesDB.get_books_like(book)
|
||||
if books:
|
||||
book_list = filter(
|
||||
lambda value: regex_book.match(value[u'name']), books)
|
||||
if not book_list:
|
||||
book_list = books
|
||||
for value in book_list:
|
||||
if bible.get_book_by_book_ref_id(value[u'id']):
|
||||
book_ref_id = value[u'id']
|
||||
break
|
||||
book_ref_id = bible.get_book_ref_id_by_localised_name(
|
||||
book, language_selection)
|
||||
elif not bible.get_book_by_book_ref_id(book_ref_id):
|
||||
book_ref_id = False
|
||||
ranges = match.group(u'ranges')
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
import chardet
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sqlite3
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
@ -44,6 +45,8 @@ import upgrade
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
RESERVED_CHARACTERS = u'\\.^$*+?{}[]()'
|
||||
|
||||
class BibleMeta(BaseModel):
|
||||
"""
|
||||
Bible Meta Data
|
||||
|
@ -352,6 +355,53 @@ class BibleDB(QtCore.QObject, Manager):
|
|||
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.
|
||||
|
||||
``book``
|
||||
The name of the book, according to the selected language.
|
||||
|
||||
``language_selection``
|
||||
The language selection the user has chosen in the settings
|
||||
section of the Bible.
|
||||
"""
|
||||
log.debug(u'get_book_ref_id_by_localised_name("%s", "%s")',
|
||||
book, language_selection)
|
||||
from openlp.plugins.bibles.lib import LanguageSelection, \
|
||||
BibleStrings
|
||||
book_names = BibleStrings().BookNames
|
||||
# escape reserved characters
|
||||
book_escaped = book
|
||||
for character in RESERVED_CHARACTERS:
|
||||
book_escaped = book_escaped.replace(
|
||||
character, u'\\' + character)
|
||||
regex_book = re.compile(u'\s*%s\s*' % u'\s*'.join(
|
||||
book_escaped.split()), re.UNICODE | re.IGNORECASE)
|
||||
if language_selection == LanguageSelection.Bible:
|
||||
db_book = self.get_book(book)
|
||||
if db_book:
|
||||
return db_book.book_reference_id
|
||||
elif language_selection == LanguageSelection.Application:
|
||||
books = filter(lambda key:
|
||||
regex_book.match(unicode(book_names[key])), book_names.keys())
|
||||
books = filter(None, map(BiblesResourcesDB.get_book, books))
|
||||
for value in books:
|
||||
if self.get_book_by_book_ref_id(value[u'id']):
|
||||
return value[u'id']
|
||||
elif language_selection == LanguageSelection.English:
|
||||
books = BiblesResourcesDB.get_books_like(book)
|
||||
if books:
|
||||
book_list = filter(
|
||||
lambda value: regex_book.match(value[u'name']), books)
|
||||
if not book_list:
|
||||
book_list = books
|
||||
for value in book_list:
|
||||
if self.get_book_by_book_ref_id(value[u'id']):
|
||||
return value[u'id']
|
||||
return False
|
||||
|
||||
def get_verses(self, reference_list, show_error=True):
|
||||
"""
|
||||
This is probably the most used function. It retrieves the list of
|
||||
|
|
|
@ -277,8 +277,9 @@ class BibleManager(object):
|
|||
"""
|
||||
log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)',
|
||||
bible, book, chapter)
|
||||
db_book = self.db_cache[bible].get_book(book)
|
||||
book_ref_id = db_book.book_reference_id
|
||||
language_selection = self.get_language_selection(bible)
|
||||
book_ref_id = self.db_cache[bible].get_book_ref_id_by_localised_name(
|
||||
book, language_selection)
|
||||
return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
|
||||
|
||||
def get_verse_count_by_book_ref_id(self, bible, book_ref_id, chapter):
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
###############################################################################
|
||||
|
||||
import logging
|
||||
import locale
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
@ -38,6 +37,7 @@ from openlp.core.lib.settings import Settings
|
|||
from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, \
|
||||
create_horizontal_adjusting_combo_box, critical_error_message_box, \
|
||||
find_and_set_in_combo_box, build_icon
|
||||
from openlp.core.utils import locale_compare
|
||||
from openlp.plugins.bibles.forms import BibleImportForm, EditBibleForm
|
||||
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
|
||||
VerseReferenceList, get_reference_separator, LanguageSelection, \
|
||||
|
@ -381,7 +381,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
# Get all bibles and sort the list.
|
||||
bibles = self.plugin.manager.get_bibles().keys()
|
||||
bibles = filter(None, bibles)
|
||||
bibles.sort(cmp=locale.strcoll)
|
||||
bibles.sort(cmp=locale_compare)
|
||||
# Load the bibles into the combo boxes.
|
||||
self.quickVersionComboBox.addItems(bibles)
|
||||
self.quickSecondComboBox.addItems(bibles)
|
||||
|
@ -538,7 +538,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||
data = BiblesResourcesDB.get_book_by_id(
|
||||
book.book_reference_id)
|
||||
books.append(data[u'name'] + u' ')
|
||||
books.sort(cmp=locale.strcoll)
|
||||
books.sort(cmp=locale_compare)
|
||||
set_case_insensitive_completer(books, self.quickSearchEdit)
|
||||
|
||||
def onImportClick(self):
|
||||
|
|
|
@ -34,12 +34,21 @@ from sqlalchemy import Column, Table, types
|
|||
from sqlalchemy.orm import mapper
|
||||
|
||||
from openlp.core.lib.db import BaseModel, init_db
|
||||
from openlp.core.utils import locale_compare
|
||||
|
||||
class CustomSlide(BaseModel):
|
||||
"""
|
||||
CustomSlide model
|
||||
"""
|
||||
pass
|
||||
# By default sort the customs by its title considering language specific
|
||||
# characters.
|
||||
def __lt__(self, other):
|
||||
r = locale_compare(self.title, other.title)
|
||||
return True if r < 0 else False
|
||||
|
||||
def __eq__(self, other):
|
||||
return 0 == locale_compare(self.title, other.title)
|
||||
|
||||
|
||||
def init_schema(url):
|
||||
"""
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
###############################################################################
|
||||
|
||||
import logging
|
||||
import locale
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from sqlalchemy.sql import or_, func
|
||||
|
@ -109,10 +108,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||
# Sort out what custom we want to select after loading the list.
|
||||
self.saveAutoSelectId()
|
||||
self.listView.clear()
|
||||
# Sort the customs by its title considering language specific
|
||||
# characters. lower() is needed for windows!
|
||||
custom_slides.sort(
|
||||
cmp=locale.strcoll, key=lambda custom: custom.title.lower())
|
||||
custom_slides.sort()
|
||||
for custom_slide in custom_slides:
|
||||
custom_name = QtGui.QListWidgetItem(custom_slide.title)
|
||||
custom_name.setData(
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
import logging
|
||||
import os
|
||||
import locale
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
@ -37,7 +36,8 @@ from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \
|
|||
Receiver, create_thumb, validate_thumb
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.core.lib.settings import Settings
|
||||
from openlp.core.utils import AppLocation, delete_file, get_images_filter
|
||||
from openlp.core.utils import AppLocation, delete_file, locale_compare, \
|
||||
get_images_filter
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -126,10 +126,10 @@ class ImageMediaItem(MediaManagerItem):
|
|||
if not initialLoad:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.plugin.formParent.displayProgressBar(len(images))
|
||||
# Sort the themes by its filename considering language specific
|
||||
# characters. lower() is needed for windows!
|
||||
images.sort(cmp=locale.strcoll,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1].lower())
|
||||
# Sort the images by its filename considering language specific
|
||||
# characters.
|
||||
images.sort(cmp=locale_compare,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1])
|
||||
for imageFile in images:
|
||||
filename = os.path.split(unicode(imageFile))[1]
|
||||
thumb = os.path.join(self.servicePath, filename)
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
import logging
|
||||
import os
|
||||
import locale
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
@ -40,6 +39,7 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
|||
create_horizontal_adjusting_combo_box
|
||||
from openlp.core.ui import DisplayController, Display
|
||||
from openlp.core.ui.media import get_media_players, set_media_players
|
||||
from openlp.core.utils import locale_compare
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -292,10 +292,10 @@ class MediaMediaItem(MediaManagerItem):
|
|||
u'media', self.getFileList())
|
||||
|
||||
def loadList(self, media):
|
||||
# Sort the themes by its filename considering language specific
|
||||
# characters. lower() is needed for windows!
|
||||
media.sort(cmp=locale.strcoll,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1].lower())
|
||||
# Sort the media by its filename considering language specific
|
||||
# characters.
|
||||
media.sort(cmp=locale_compare,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1])
|
||||
for track in media:
|
||||
track_info = QtCore.QFileInfo(track)
|
||||
if track_info.isFile():
|
||||
|
@ -317,8 +317,8 @@ class MediaMediaItem(MediaManagerItem):
|
|||
|
||||
def getList(self, type=MediaType.Audio):
|
||||
media = SettingsManager.load_list(self.settingsSection, u'media')
|
||||
media.sort(cmp=locale.strcoll,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1].lower())
|
||||
media.sort(cmp=locale_compare,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1])
|
||||
ext = []
|
||||
if type == MediaType.Audio:
|
||||
ext = self.plugin.audio_extensions_list
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
import logging
|
||||
import os
|
||||
import locale
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
@ -38,6 +37,7 @@ from openlp.core.lib import MediaManagerItem, build_icon, SettingsManager, \
|
|||
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
|
||||
create_horizontal_adjusting_combo_box
|
||||
from openlp.core.lib.settings import Settings
|
||||
from openlp.core.utils import locale_compare
|
||||
from openlp.plugins.presentations.lib import MessageListener
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -164,10 +164,10 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
if not initialLoad:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.plugin.formParent.displayProgressBar(len(files))
|
||||
# Sort the themes by its filename considering language specific
|
||||
# characters. lower() is needed for windows!
|
||||
files.sort(cmp=locale.strcoll,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1].lower())
|
||||
# Sort the presentations by its filename considering language specific
|
||||
# characters.
|
||||
files.sort(cmp=locale_compare,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1])
|
||||
for file in files:
|
||||
if not initialLoad:
|
||||
self.plugin.formParent.incrementProgressBar()
|
||||
|
|
|
@ -66,10 +66,10 @@
|
|||
<a href="#" id="service-refresh" data-role="button" data-icon="refresh">${refresh}</a>
|
||||
<div data-role="navbar">
|
||||
<ul>
|
||||
<li><a href="#service-manager" data-theme="e">Service</a></li>
|
||||
<li><a href="#slide-controller">Slides</a></li>
|
||||
<li><a href="#alerts">Alerts</a></li>
|
||||
<li><a href="#search">Search</a></li>
|
||||
<li><a href="#service-manager" data-theme="e">${service}</a></li>
|
||||
<li><a href="#slide-controller">${slides}</a></li>
|
||||
<li><a href="#alerts">${alerts}</a></li>
|
||||
<li><a href="#search">${search}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -97,10 +97,10 @@
|
|||
<a href="#" id="controller-refresh" data-role="button" data-icon="refresh">${refresh}</a>
|
||||
<div data-role="navbar">
|
||||
<ul>
|
||||
<li><a href="#service-manager">Service</a></li>
|
||||
<li><a href="#slide-controller" data-theme="e">Slides</a></li>
|
||||
<li><a href="#alerts">Alerts</a></li>
|
||||
<li><a href="#search">Search</a></li>
|
||||
<li><a href="#service-manager">${service}</a></li>
|
||||
<li><a href="#slide-controller" data-theme="e">${slides}</a></li>
|
||||
<li><a href="#alerts">${alerts}</a></li>
|
||||
<li><a href="#search">${search}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -127,10 +127,10 @@
|
|||
<h1>${alerts}</h1>
|
||||
<div data-role="navbar">
|
||||
<ul>
|
||||
<li><a href="#service-manager">Service</a></li>
|
||||
<li><a href="#slide-controller">Slides</a></li>
|
||||
<li><a href="#alerts" data-theme="e">Alerts</a></li>
|
||||
<li><a href="#search">Search</a></li>
|
||||
<li><a href="#service-manager">${service}</a></li>
|
||||
<li><a href="#slide-controller">${slides}</a></li>
|
||||
<li><a href="#alerts" data-theme="e">${alerts}</a></li>
|
||||
<li><a href="#search">${search}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -148,10 +148,10 @@
|
|||
<h1>${search}</h1>
|
||||
<div data-role="navbar">
|
||||
<ul>
|
||||
<li><a href="#service-manager">Service</a></li>
|
||||
<li><a href="#slide-controller">Slides</a></li>
|
||||
<li><a href="#alerts">Alerts</a></li>
|
||||
<li><a href="#search" data-theme="e">Search</a></li>
|
||||
<li><a href="#service-manager">${service}</a></li>
|
||||
<li><a href="#slide-controller">${slides}</a></li>
|
||||
<li><a href="#alerts">${alerts}</a></li>
|
||||
<li><a href="#search" data-theme="e">${search}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -308,7 +308,9 @@ class HttpConnection(object):
|
|||
'add_and_go_to_service': translate('RemotePlugin.Mobile',
|
||||
'Add & Go to Service'),
|
||||
'no_results': translate('RemotePlugin.Mobile', 'No Results'),
|
||||
'options': translate('RemotePlugin.Mobile', 'Options')
|
||||
'options': translate('RemotePlugin.Mobile', 'Options'),
|
||||
'service': translate('RemotePlugin.Mobile', 'Service'),
|
||||
'slides': translate('RemotePlugin.Mobile', 'Slides')
|
||||
}
|
||||
|
||||
def ready_read(self):
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
The :mod:`songexportform` module provides the wizard for exporting songs to the
|
||||
OpenLyrics format.
|
||||
"""
|
||||
import locale
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
@ -252,7 +251,7 @@ class SongExportForm(OpenLPWizard):
|
|||
# Load the list of songs.
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
songs = self.plugin.manager.get_all_objects(Song)
|
||||
songs.sort(cmp=locale.strcoll, key=lambda song: song.title.lower())
|
||||
songs.sort()
|
||||
for song in songs:
|
||||
# No need to export temporary songs.
|
||||
if song.temporary:
|
||||
|
|
|
@ -35,6 +35,7 @@ from sqlalchemy.orm import mapper, relation
|
|||
from sqlalchemy.sql.expression import func
|
||||
|
||||
from openlp.core.lib.db import BaseModel, init_db
|
||||
from openlp.core.utils import locale_compare
|
||||
|
||||
class Author(BaseModel):
|
||||
"""
|
||||
|
@ -63,7 +64,14 @@ class Song(BaseModel):
|
|||
"""
|
||||
Song model
|
||||
"""
|
||||
pass
|
||||
# By default sort the songs by its title considering language specific
|
||||
# characters.
|
||||
def __lt__(self, other):
|
||||
r = locale_compare(self.title, other.title)
|
||||
return True if r < 0 else False
|
||||
|
||||
def __eq__(self, other):
|
||||
return 0 == locale_compare(self.title, other.title)
|
||||
|
||||
|
||||
class Topic(BaseModel):
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
###############################################################################
|
||||
|
||||
import logging
|
||||
import locale
|
||||
import re
|
||||
import os
|
||||
import shutil
|
||||
|
@ -260,10 +259,7 @@ class SongMediaItem(MediaManagerItem):
|
|||
log.debug(u'display results Song')
|
||||
self.saveAutoSelectId()
|
||||
self.listView.clear()
|
||||
# Sort the songs by its title considering language specific characters.
|
||||
# lower() is needed for windows!
|
||||
searchresults.sort(
|
||||
cmp=locale.strcoll, key=lambda song: song.title.lower())
|
||||
searchresults.sort()
|
||||
for song in searchresults:
|
||||
# Do not display temporary songs
|
||||
if song.temporary:
|
||||
|
|
|
@ -154,18 +154,20 @@ class SundayPlusImport(SongImport):
|
|||
# If any line inside any verse contains CCLI or
|
||||
# only Public Domain, we treat this as special data:
|
||||
# we remove that line and add data to specific field.
|
||||
processed_lines = []
|
||||
for i in xrange(len(lines)):
|
||||
lines[i] = lines[i].strip()
|
||||
line = lines[i]
|
||||
if line[:4].lower() == u'ccli':
|
||||
line = lines[i].strip()
|
||||
if line[:3].lower() == u'ccl':
|
||||
m = re.search(r'[0-9]+', line)
|
||||
if m:
|
||||
self.ccliNumber = int(m.group(0))
|
||||
lines.pop(i)
|
||||
continue
|
||||
elif line.lower() == u'public domain':
|
||||
self.copyright = u'Public Domain'
|
||||
lines.pop(i)
|
||||
self.addVerse('\n'.join(lines).strip(), verse_type)
|
||||
continue
|
||||
processed_lines.append(line)
|
||||
self.addVerse('\n'.join(processed_lines).strip(),
|
||||
verse_type)
|
||||
if end == -1:
|
||||
break
|
||||
i = end + 1
|
||||
|
|
|
@ -260,7 +260,7 @@ class OpenLyrics(object):
|
|||
IMPLEMENTED_VERSION = u'0.8'
|
||||
START_TAGS_REGEX = re.compile(r'\{(\w+)\}')
|
||||
END_TAGS_REGEX = re.compile(r'\{\/(\w+)\}')
|
||||
VERSE_NUMBER_REGEX = re.compile(u'[a-zA-Z]*')
|
||||
VERSE_TAG_SPLITTER = re.compile(u'([a-zA-Z]+)([0-9]*)([a-zA-Z]?)')
|
||||
|
||||
def __init__(self, manager):
|
||||
self.manager = manager
|
||||
|
@ -325,10 +325,22 @@ class OpenLyrics(object):
|
|||
# Process the song's lyrics.
|
||||
lyrics = etree.SubElement(song_xml, u'lyrics')
|
||||
verse_list = sxml.get_verses(song.lyrics)
|
||||
# Add a suffix letter to each verse
|
||||
verse_tags = []
|
||||
for verse in verse_list:
|
||||
verse_tag = verse[0][u'type'][0].lower()
|
||||
verse_number = verse[0][u'label']
|
||||
verse_def = verse_tag + verse_number
|
||||
verse_tags.append(verse_def)
|
||||
# Create the letter from the number of duplicates
|
||||
verse[0][u'suffix'] = chr(96 + verse_tags.count(verse_def))
|
||||
# If the verse tag is a duplicate use the suffix letter
|
||||
for verse in verse_list:
|
||||
verse_tag = verse[0][u'type'][0].lower()
|
||||
verse_number = verse[0][u'label']
|
||||
verse_def = verse_tag + verse_number
|
||||
if verse_tags.count(verse_def) > 1:
|
||||
verse_def += verse[0][u'suffix']
|
||||
verse_element = \
|
||||
self._add_text_to_element(u'verse', lyrics, None, verse_def)
|
||||
if u'lang' in verse[0]:
|
||||
|
@ -742,11 +754,10 @@ class OpenLyrics(object):
|
|||
if lines.get(u'break') is not None:
|
||||
text += u'\n[---]'
|
||||
verse_def = verse.get(u'name', u' ').lower()
|
||||
if verse_def[0] in VerseType.Tags:
|
||||
verse_tag = verse_def[0]
|
||||
else:
|
||||
verse_tag, verse_number, verse_part = \
|
||||
OpenLyrics.VERSE_TAG_SPLITTER.search(verse_def).groups()
|
||||
if verse_tag not in VerseType.Tags:
|
||||
verse_tag = VerseType.Tags[VerseType.Other]
|
||||
verse_number = OpenLyrics.VERSE_NUMBER_REGEX.sub(u'', verse_def)
|
||||
# OpenLyrics allows e. g. "c", but we need "c1". However, this does
|
||||
# not correct the verse order.
|
||||
if not verse_number:
|
||||
|
@ -757,13 +768,13 @@ class OpenLyrics(object):
|
|||
if song_xml.get(u'modifiedIn') in (u'1.9.6', u'OpenLP 1.9.6') and \
|
||||
song_xml.get(u'version') == u'0.7' and \
|
||||
(verse_tag, verse_number, lang) in verses:
|
||||
verses[(verse_tag, verse_number, lang)] += u'\n[---]\n' + text
|
||||
verses[(verse_tag, verse_number, lang, None)] += u'\n[---]\n' + text
|
||||
# Merge v1a, v1b, .... to v1.
|
||||
elif (verse_tag, verse_number, lang) in verses:
|
||||
elif (verse_tag, verse_number, lang, verse_part) in verses:
|
||||
verses[(verse_tag, verse_number, lang)] += u'\n' + text
|
||||
else:
|
||||
verses[(verse_tag, verse_number, lang)] = text
|
||||
verse_def_list.append((verse_tag, verse_number, lang))
|
||||
verses[(verse_tag, verse_number, lang, verse_part)] = text
|
||||
verse_def_list.append((verse_tag, verse_number, lang, verse_part))
|
||||
# We have to use a list to keep the order, as dicts are not sorted.
|
||||
for verse in verse_def_list:
|
||||
sxml.add_verse_to_lyrics(
|
||||
|
|
Loading…
Reference in New Issue