forked from openlp/openlp
Head
This commit is contained in:
commit
ba71bd5b6d
47
documentation/openlp.1
Normal file
47
documentation/openlp.1
Normal file
@ -0,0 +1,47 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.9.
|
||||
.TH OPENLP "1" "May 2012" "OpenLP 1.9.9" "User Commands"
|
||||
.SH NAME
|
||||
OpenLP \- Church worship presentation software
|
||||
.SH SYNOPSIS
|
||||
.B openlp
|
||||
[\fIoptions\fR] [\fIqt-options\fR]
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-version\fR
|
||||
show program's version number and exit
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-e\fR, \fB\-\-no\-error\-form\fR
|
||||
Disable the error notification form.
|
||||
.TP
|
||||
\fB\-l\fR LEVEL, \fB\-\-log\-level\fR=\fILEVEL\fR
|
||||
Set logging to LEVEL level. Valid values are "debug",
|
||||
"info", "warning".
|
||||
.TP
|
||||
\fB\-p\fR, \fB\-\-portable\fR
|
||||
Specify if this should be run as a portable app, off a
|
||||
USB flash drive (not implemented).
|
||||
.TP
|
||||
\fB\-d\fR, \fB\-\-dev\-version\fR
|
||||
Ignore the version file and pull the version directly
|
||||
from Bazaar
|
||||
.TP
|
||||
\fB\-s\fR STYLE, \fB\-\-style\fR=\fISTYLE\fR
|
||||
Set the Qt4 style (passed directly to Qt4).
|
||||
.TP
|
||||
\fB\-\-testing\fR
|
||||
Run by testing framework
|
||||
.SH "SEE ALSO"
|
||||
The full documentation for
|
||||
.B OpenLP
|
||||
is maintained as a Texinfo manual. If the
|
||||
.B info
|
||||
and
|
||||
.B OpenLP
|
||||
programs are properly installed at your site, the command
|
||||
.IP
|
||||
.B info OpenLP
|
||||
.PP
|
||||
should give you access to the complete manual.
|
@ -1 +1 @@
|
||||
1.9.5-bzr1421
|
||||
1.9.9-bzr1956
|
||||
|
@ -49,7 +49,7 @@ from openlp.core.ui.firsttimeform import FirstTimeForm
|
||||
from openlp.core.ui.exceptionform import ExceptionForm
|
||||
from openlp.core.ui import SplashScreen, ScreenList
|
||||
from openlp.core.utils import AppLocation, LanguageManager, VersionThread, \
|
||||
get_application_version, DelayStartThread
|
||||
get_application_version
|
||||
|
||||
|
||||
__all__ = [u'OpenLP', u'main']
|
||||
@ -145,7 +145,6 @@ class OpenLP(QtGui.QApplication):
|
||||
VersionThread(self.mainWindow).start()
|
||||
Receiver.send_message(u'live_display_blank_check')
|
||||
self.mainWindow.appStartup()
|
||||
DelayStartThread(self.mainWindow).start()
|
||||
# Skip exec_() for gui tests
|
||||
if not testing:
|
||||
return self.exec_()
|
||||
|
@ -62,6 +62,7 @@ class ServiceItemAction(object):
|
||||
PreviousLastSlide = 2
|
||||
Next = 3
|
||||
|
||||
|
||||
def translate(context, text, comment=None,
|
||||
encoding=QtCore.QCoreApplication.CodecForTr, n=-1,
|
||||
translate=QtCore.QCoreApplication.translate):
|
||||
@ -83,6 +84,7 @@ def translate(context, text, comment=None,
|
||||
"""
|
||||
return translate(context, text, comment, encoding, n)
|
||||
|
||||
|
||||
def get_text_file_string(text_file):
|
||||
"""
|
||||
Open a file and return its content as unicode string. If the supplied file
|
||||
@ -111,6 +113,7 @@ def get_text_file_string(text_file):
|
||||
file_handle.close()
|
||||
return content_string
|
||||
|
||||
|
||||
def str_to_bool(stringvalue):
|
||||
"""
|
||||
Convert a string version of a boolean into a real boolean.
|
||||
@ -122,6 +125,7 @@ def str_to_bool(stringvalue):
|
||||
return stringvalue
|
||||
return unicode(stringvalue).strip().lower() in (u'true', u'yes', u'y')
|
||||
|
||||
|
||||
def build_icon(icon):
|
||||
"""
|
||||
Build a QIcon instance from an existing QIcon, a resource location, or a
|
||||
@ -148,6 +152,7 @@ def build_icon(icon):
|
||||
QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
return button_icon
|
||||
|
||||
|
||||
def image_to_byte(image):
|
||||
"""
|
||||
Resize an image to fit on the current screen for the web and returns
|
||||
@ -166,6 +171,7 @@ def image_to_byte(image):
|
||||
# convert to base64 encoding so does not get missed!
|
||||
return byte_array.toBase64()
|
||||
|
||||
|
||||
def create_thumb(image_path, thumb_path, return_icon=True, size=None):
|
||||
"""
|
||||
Create a thumbnail from the given image path and depending on
|
||||
@ -201,6 +207,7 @@ def create_thumb(image_path, thumb_path, return_icon=True, size=None):
|
||||
# Fallback for files with animation support.
|
||||
return build_icon(unicode(image_path))
|
||||
|
||||
|
||||
def validate_thumb(file_path, thumb_path):
|
||||
"""
|
||||
Validates whether an file's thumb still exists and if is up to date.
|
||||
@ -219,6 +226,7 @@ def validate_thumb(file_path, thumb_path):
|
||||
thumb_date = os.stat(thumb_path).st_mtime
|
||||
return image_date <= thumb_date
|
||||
|
||||
|
||||
def resize_image(image_path, width, height, background=u'#000000'):
|
||||
"""
|
||||
Resize an image to fit on the current screen.
|
||||
@ -266,6 +274,7 @@ def resize_image(image_path, width, height, background=u'#000000'):
|
||||
painter.drawImage((width - realw) / 2, (height - realh) / 2, preview)
|
||||
return new_image
|
||||
|
||||
|
||||
def check_item_selected(list_widget, message):
|
||||
"""
|
||||
Check if a list item is selected so an action may be performed on it
|
||||
@ -282,6 +291,7 @@ def check_item_selected(list_widget, message):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def clean_tags(text):
|
||||
"""
|
||||
Remove Tags from text for display
|
||||
@ -294,6 +304,7 @@ def clean_tags(text):
|
||||
text = text.replace(tag[u'end tag'], u'')
|
||||
return text
|
||||
|
||||
|
||||
def expand_tags(text):
|
||||
"""
|
||||
Expand tags HTML for display
|
||||
@ -303,6 +314,7 @@ def expand_tags(text):
|
||||
text = text.replace(tag[u'end tag'], tag[u'end html'])
|
||||
return text
|
||||
|
||||
|
||||
def check_directory_exists(dir):
|
||||
"""
|
||||
Check a theme directory exists and if not create it
|
||||
@ -317,6 +329,7 @@ def check_directory_exists(dir):
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
|
||||
def create_separated_list(stringlist):
|
||||
"""
|
||||
Returns a string that represents a join of a list of strings with a
|
||||
@ -345,6 +358,7 @@ def create_separated_list(stringlist):
|
||||
return unicode(translate('OpenLP.core.lib', '%1, %2',
|
||||
u'Locale list separator: start').arg(stringlist[0], merged))
|
||||
|
||||
|
||||
from eventreceiver import Receiver
|
||||
from listwidgetwithdnd import ListWidgetWithDnD
|
||||
from formattingtags import FormattingTags
|
||||
|
@ -53,8 +53,7 @@ class OpenLPDockWidget(QtGui.QDockWidget):
|
||||
self.setWindowIcon(build_icon(icon))
|
||||
# Sort out the minimum width.
|
||||
screens = ScreenList.get_instance()
|
||||
screen_width = screens.current[u'size'].width()
|
||||
mainwindow_docbars = screen_width / 5
|
||||
mainwindow_docbars = screens.current[u'size'].width() / 5
|
||||
if mainwindow_docbars > 300:
|
||||
self.setMinimumWidth(300)
|
||||
else:
|
||||
|
@ -46,14 +46,36 @@ class FormattingTags(object):
|
||||
"""
|
||||
Provide access to the html_expands list.
|
||||
"""
|
||||
# Load user defined tags otherwise user defined tags are not present.
|
||||
FormattingTags.load_tags()
|
||||
return FormattingTags.html_expands
|
||||
|
||||
@staticmethod
|
||||
def reset_html_tags():
|
||||
def save_html_tags():
|
||||
"""
|
||||
Resets the html_expands list.
|
||||
Saves all formatting tags except protected ones.
|
||||
"""
|
||||
tags = []
|
||||
for tag in FormattingTags.html_expands:
|
||||
if not tag[u'protected'] and not tag.get(u'temporary'):
|
||||
# Using dict ensures that copy is made and encoding of values
|
||||
# a little later does not affect tags in the original list
|
||||
tags.append(dict(tag))
|
||||
tag = tags[-1]
|
||||
# Remove key 'temporary' from tags.
|
||||
# It is not needed to be saved.
|
||||
if u'temporary' in tag:
|
||||
del tag[u'temporary']
|
||||
for element in tag:
|
||||
if isinstance(tag[element], unicode):
|
||||
tag[element] = tag[element].encode('utf8')
|
||||
# Formatting Tags were also known as display tags.
|
||||
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
||||
QtCore.QVariant(cPickle.dumps(tags) if tags else u''))
|
||||
|
||||
@staticmethod
|
||||
def load_tags():
|
||||
"""
|
||||
Load the Tags from store so can be used in the system or used to
|
||||
update the display.
|
||||
"""
|
||||
temporary_tags = [tag for tag in FormattingTags.html_expands
|
||||
if tag.get(u'temporary')]
|
||||
@ -141,38 +163,6 @@ class FormattingTags(object):
|
||||
FormattingTags.add_html_tags(base_tags)
|
||||
FormattingTags.add_html_tags(temporary_tags)
|
||||
|
||||
@staticmethod
|
||||
def save_html_tags():
|
||||
"""
|
||||
Saves all formatting tags except protected ones.
|
||||
"""
|
||||
tags = []
|
||||
for tag in FormattingTags.html_expands:
|
||||
if not tag[u'protected'] and not tag.get(u'temporary'):
|
||||
# Using dict ensures that copy is made and encoding of values
|
||||
# a little later does not affect tags in the original list
|
||||
tags.append(dict(tag))
|
||||
tag = tags[-1]
|
||||
# Remove key 'temporary' from tags.
|
||||
# It is not needed to be saved.
|
||||
if u'temporary' in tag:
|
||||
del tag[u'temporary']
|
||||
for element in tag:
|
||||
if isinstance(tag[element], unicode):
|
||||
tag[element] = tag[element].encode('utf8')
|
||||
# Formatting Tags were also known as display tags.
|
||||
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
||||
QtCore.QVariant(cPickle.dumps(tags) if tags else u''))
|
||||
|
||||
@staticmethod
|
||||
def load_tags():
|
||||
"""
|
||||
Load the Tags from store so can be used in the system or used to
|
||||
update the display. If Cancel was selected this is needed to reset the
|
||||
dsiplay to the correct version.
|
||||
"""
|
||||
# Initial Load of the Tags
|
||||
FormattingTags.reset_html_tags()
|
||||
# Formatting Tags were also known as display tags.
|
||||
user_expands = QtCore.QSettings().value(u'displayTags/html_tags',
|
||||
QtCore.QVariant(u'')).toString()
|
||||
@ -188,17 +178,13 @@ class FormattingTags(object):
|
||||
FormattingTags.add_html_tags(user_tags)
|
||||
|
||||
@staticmethod
|
||||
def add_html_tags(tags, save=False):
|
||||
def add_html_tags(tags):
|
||||
"""
|
||||
Add a list of tags to the list.
|
||||
|
||||
``tags``
|
||||
The list with tags to add.
|
||||
|
||||
``save``
|
||||
Defaults to ``False``. If set to ``True`` the given ``tags`` are
|
||||
saved to the config.
|
||||
|
||||
Each **tag** has to be a ``dict`` and should have the following keys:
|
||||
|
||||
* desc
|
||||
@ -226,8 +212,6 @@ class FormattingTags(object):
|
||||
displaying text containing the tag. It has to be a ``boolean``.
|
||||
"""
|
||||
FormattingTags.html_expands.extend(tags)
|
||||
if save:
|
||||
FormattingTags.save_html_tags()
|
||||
|
||||
@staticmethod
|
||||
def remove_html_tag(tag_id):
|
||||
|
@ -100,6 +100,7 @@ class Image(object):
|
||||
variables ``image`` and ``image_bytes`` to ``None`` and add the image object
|
||||
to the queue of images to process.
|
||||
"""
|
||||
secondary_priority = 0
|
||||
def __init__(self, name, path, source, background):
|
||||
self.name = name
|
||||
self.path = path
|
||||
@ -108,25 +109,40 @@ class Image(object):
|
||||
self.priority = Priority.Normal
|
||||
self.source = source
|
||||
self.background = background
|
||||
self.secondary_priority = Image.secondary_priority
|
||||
Image.secondary_priority += 1
|
||||
|
||||
|
||||
class PriorityQueue(Queue.PriorityQueue):
|
||||
"""
|
||||
Customised ``Queue.PriorityQueue``.
|
||||
|
||||
Each item in the queue must be tuple with three values. The first value
|
||||
is the :class:`Image`'s ``priority`` attribute, the second value
|
||||
the :class:`Image`'s ``secondary_priority`` attribute. The last value the
|
||||
:class:`Image` instance itself::
|
||||
|
||||
(image.priority, image.secondary_priority, image)
|
||||
|
||||
Doing this, the :class:`Queue.PriorityQueue` will sort the images according
|
||||
to their priorities, but also according to there number. However, the number
|
||||
only has an impact on the result if there are more images with the same
|
||||
priority. In such case the image which has been added earlier is privileged.
|
||||
"""
|
||||
def modify_priority(self, image, new_priority):
|
||||
"""
|
||||
Modifies the priority of the given ``image``.
|
||||
|
||||
``image``
|
||||
The image to remove. This should be an ``Image`` instance.
|
||||
The image to remove. This should be an :class:`Image` instance.
|
||||
|
||||
``new_priority``
|
||||
The image's new priority.
|
||||
The image's new priority. See the :class:`Priority` class for
|
||||
priorities.
|
||||
"""
|
||||
self.remove(image)
|
||||
image.priority = new_priority
|
||||
self.put((image.priority, image))
|
||||
self.put((image.priority, image.secondary_priority, image))
|
||||
|
||||
def remove(self, image):
|
||||
"""
|
||||
@ -135,8 +151,8 @@ class PriorityQueue(Queue.PriorityQueue):
|
||||
``image``
|
||||
The image to remove. This should be an ``Image`` instance.
|
||||
"""
|
||||
if (image.priority, image) in self.queue:
|
||||
self.queue.remove((image.priority, image))
|
||||
if (image.priority, image.secondary_priority, image) in self.queue:
|
||||
self.queue.remove((image.priority, image.secondary_priority, image))
|
||||
|
||||
|
||||
class ImageManager(QtCore.QObject):
|
||||
@ -261,7 +277,8 @@ class ImageManager(QtCore.QObject):
|
||||
if not name in self._cache:
|
||||
image = Image(name, path, source, background)
|
||||
self._cache[name] = image
|
||||
self._conversion_queue.put((image.priority, image))
|
||||
self._conversion_queue.put(
|
||||
(image.priority, image.secondary_priority, image))
|
||||
else:
|
||||
log.debug(u'Image in cache %s:%s' % (name, path))
|
||||
# We want only one thread.
|
||||
@ -282,7 +299,7 @@ class ImageManager(QtCore.QObject):
|
||||
Actually does the work.
|
||||
"""
|
||||
log.debug(u'_process_cache')
|
||||
image = self._conversion_queue.get()[1]
|
||||
image = self._conversion_queue.get()[2]
|
||||
# Generate the QImage for the image.
|
||||
if image.image is None:
|
||||
image.image = resize_image(image.path, self.width, self.height,
|
||||
|
@ -373,12 +373,12 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
Process a list for files either from the File Dialog or from Drag and
|
||||
Drop
|
||||
|
||||
``files``
|
||||
The files to be loaded
|
||||
``files``
|
||||
The files to be loaded.
|
||||
"""
|
||||
names = []
|
||||
fullList = []
|
||||
for count in range(0, self.listView.count()):
|
||||
for count in range(self.listView.count()):
|
||||
names.append(unicode(self.listView.item(count).text()))
|
||||
fullList.append(unicode(self.listView.item(count).
|
||||
data(QtCore.Qt.UserRole).toString()))
|
||||
@ -582,7 +582,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
Common method for generating a service item
|
||||
"""
|
||||
serviceItem = ServiceItem(self.plugin)
|
||||
serviceItem.add_icon(self.plugin.icon_path)
|
||||
serviceItem.add_icon(self.plugin.iconPath)
|
||||
if self.generateSlideData(serviceItem, item, xmlVersion, remote):
|
||||
return serviceItem
|
||||
else:
|
||||
|
@ -155,9 +155,9 @@ class Plugin(QtCore.QObject):
|
||||
self.version = get_application_version()[u'version']
|
||||
self.settingsSection = self.name
|
||||
self.icon = None
|
||||
self.media_item_class = media_item_class
|
||||
self.settings_tab_class = settings_tab_class
|
||||
self.settings_tab = None
|
||||
self.mediaItemClass = media_item_class
|
||||
self.settingsTabClass = settings_tab_class
|
||||
self.settingsTab = None
|
||||
self.mediaItem = None
|
||||
self.weight = 0
|
||||
self.status = PluginStatus.Inactive
|
||||
@ -166,9 +166,9 @@ class Plugin(QtCore.QObject):
|
||||
self.renderer = plugin_helpers[u'renderer']
|
||||
self.serviceManager = plugin_helpers[u'service']
|
||||
self.settingsForm = plugin_helpers[u'settings form']
|
||||
self.mediadock = plugin_helpers[u'toolbox']
|
||||
self.mediaDock = plugin_helpers[u'toolbox']
|
||||
self.pluginManager = plugin_helpers[u'pluginmanager']
|
||||
self.formparent = plugin_helpers[u'formparent']
|
||||
self.formParent = plugin_helpers[u'formparent']
|
||||
self.mediaController = plugin_helpers[u'mediacontroller']
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'%s_add_service_item' % self.name),
|
||||
@ -219,8 +219,8 @@ class Plugin(QtCore.QObject):
|
||||
Construct a MediaManagerItem object with all the buttons and things
|
||||
you need, and return it for integration into OpenLP.
|
||||
"""
|
||||
if self.media_item_class:
|
||||
self.mediaItem = self.media_item_class(self.mediadock.media_dock,
|
||||
if self.mediaItemClass:
|
||||
self.mediaItem = self.mediaItemClass(self.mediaDock.media_dock,
|
||||
self, self.icon)
|
||||
|
||||
def addImportMenuItem(self, importMenu):
|
||||
@ -255,10 +255,10 @@ class Plugin(QtCore.QObject):
|
||||
Create a tab for the settings window to display the configurable options
|
||||
for this plugin to the user.
|
||||
"""
|
||||
if self.settings_tab_class:
|
||||
self.settings_tab = self.settings_tab_class(parent, self.name,
|
||||
if self.settingsTabClass:
|
||||
self.settingsTab = self.settingsTabClass(parent, self.name,
|
||||
self.getString(StringContent.VisibleName)[u'title'],
|
||||
self.icon_path)
|
||||
self.iconPath)
|
||||
|
||||
def addToMenu(self, menubar):
|
||||
"""
|
||||
@ -294,14 +294,14 @@ class Plugin(QtCore.QObject):
|
||||
"""
|
||||
if self.mediaItem:
|
||||
self.mediaItem.initialise()
|
||||
self.mediadock.insert_dock(self.mediaItem, self.icon, self.weight)
|
||||
self.mediaDock.insert_dock(self.mediaItem, self.icon, self.weight)
|
||||
|
||||
def finalise(self):
|
||||
"""
|
||||
Called by the plugin Manager to cleanup things.
|
||||
"""
|
||||
if self.mediaItem:
|
||||
self.mediadock.remove_dock(self.mediaItem)
|
||||
self.mediaDock.remove_dock(self.mediaItem)
|
||||
|
||||
def appStartup(self):
|
||||
"""
|
||||
|
@ -125,13 +125,12 @@ class Renderer(object):
|
||||
Set the appropriate theme depending on the theme level.
|
||||
Called by the service item when building a display frame
|
||||
|
||||
``theme``
|
||||
``override_theme``
|
||||
The name of the song-level theme. None means the service
|
||||
item wants to use the given value.
|
||||
|
||||
``override_levels``
|
||||
Used to force the theme data passed in to be used.
|
||||
|
||||
"""
|
||||
log.debug(u'set override theme to %s', override_theme)
|
||||
theme_level = self.theme_level
|
||||
@ -236,8 +235,8 @@ class Renderer(object):
|
||||
# the first two slides (and neglect the last for now).
|
||||
if len(slides) == 3:
|
||||
html_text = expand_tags(u'\n'.join(slides[:2]))
|
||||
# We check both slides to determine if the optional break is
|
||||
# needed (there is only one optional break).
|
||||
# We check both slides to determine if the optional split is
|
||||
# needed (there is only one optional split).
|
||||
else:
|
||||
html_text = expand_tags(u'\n'.join(slides))
|
||||
html_text = html_text.replace(u'\n', u'<br>')
|
||||
@ -248,14 +247,18 @@ class Renderer(object):
|
||||
else:
|
||||
# The first optional slide fits, which means we have to
|
||||
# render the first optional slide.
|
||||
text_contains_break = u'[---]' in text
|
||||
if text_contains_break:
|
||||
text_contains_split = u'[---]' in text
|
||||
if text_contains_split:
|
||||
try:
|
||||
text_to_render, text = \
|
||||
text.split(u'\n[---]\n', 1)
|
||||
except:
|
||||
text_to_render = text.split(u'\n[---]\n')[0]
|
||||
text = u''
|
||||
text_to_render, raw_tags, html_tags = \
|
||||
self._get_start_tags(text_to_render)
|
||||
if text:
|
||||
text = raw_tags + text
|
||||
else:
|
||||
text_to_render = text
|
||||
text = u''
|
||||
@ -264,7 +267,7 @@ class Renderer(object):
|
||||
if len(slides) > 1 and text:
|
||||
# Add all slides apart from the last one the list.
|
||||
pages.extend(slides[:-1])
|
||||
if text_contains_break:
|
||||
if text_contains_split:
|
||||
text = slides[-1] + u'\n[---]\n' + text
|
||||
else:
|
||||
text = slides[-1] + u'\n'+ text
|
||||
@ -364,7 +367,7 @@ class Renderer(object):
|
||||
self.web.setVisible(False)
|
||||
self.web.resize(self.page_width, self.page_height)
|
||||
self.web_frame = self.web.page().mainFrame()
|
||||
# Adjust width and height to account for shadow. outline done in css
|
||||
# Adjust width and height to account for shadow. outline done in css.
|
||||
html = u"""<!DOCTYPE html><html><head><script>
|
||||
function show_text(newtext) {
|
||||
var main = document.getElementById('main');
|
||||
@ -493,19 +496,22 @@ class Renderer(object):
|
||||
(raw_text.find(tag[u'start tag']), tag[u'start tag'],
|
||||
tag[u'end tag']))
|
||||
html_tags.append(
|
||||
(raw_text.find(tag[u'start tag']), tag[u'start html']))
|
||||
(raw_text.find(tag[u'start tag']), tag[u'start html']))
|
||||
# Sort the lists, so that the tags which were opened first on the first
|
||||
# slide (the text we are checking) will be opened first on the next
|
||||
# slide as well.
|
||||
raw_tags.sort(key=lambda tag: tag[0])
|
||||
html_tags.sort(key=lambda tag: tag[0])
|
||||
# Create a list with closing tags for the raw_text.
|
||||
end_tags = [tag[2] for tag in raw_tags]
|
||||
end_tags = []
|
||||
start_tags = []
|
||||
for tag in raw_tags:
|
||||
start_tags.append(tag[1])
|
||||
end_tags.append(tag[2])
|
||||
end_tags.reverse()
|
||||
# Remove the indexes.
|
||||
raw_tags = [tag[1] for tag in raw_tags]
|
||||
html_tags = [tag[1] for tag in html_tags]
|
||||
return raw_text + u''.join(end_tags), u''.join(raw_tags), \
|
||||
return raw_text + u''.join(end_tags), u''.join(start_tags), \
|
||||
u''.join(html_tags)
|
||||
|
||||
def _binary_chop(self, formatted, previous_html, previous_raw, html_list,
|
||||
|
@ -195,8 +195,7 @@ class ServiceItem(object):
|
||||
# avoid tracebacks.
|
||||
if self.raw_footer is None:
|
||||
self.raw_footer = []
|
||||
self.foot_text = \
|
||||
u'<br>'.join([footer for footer in self.raw_footer if footer])
|
||||
self.foot_text = u'<br>'.join(filter(None, self.raw_footer))
|
||||
|
||||
def add_from_image(self, path, title, background=None):
|
||||
"""
|
||||
@ -314,17 +313,12 @@ class ServiceItem(object):
|
||||
self.from_plugin = header[u'from_plugin']
|
||||
self.capabilities = header[u'capabilities']
|
||||
# Added later so may not be present in older services.
|
||||
if u'search' in header:
|
||||
self.search_string = header[u'search']
|
||||
self.data_string = header[u'data']
|
||||
if u'xml_version' in header:
|
||||
self.xml_version = header[u'xml_version']
|
||||
if u'start_time' in header:
|
||||
self.start_time = header[u'start_time']
|
||||
if u'end_time' in header:
|
||||
self.end_time = header[u'end_time']
|
||||
if u'media_length' in header:
|
||||
self.media_length = header[u'media_length']
|
||||
self.search_string = header.get(u'search', u'')
|
||||
self.data_string = header.get(u'data', u'')
|
||||
self.xml_version = header.get(u'xml_version')
|
||||
self.start_time = header.get(u'start_time', 0)
|
||||
self.end_time = header.get(u'end_time', 0)
|
||||
self.media_length = header.get(u'media_length', 0)
|
||||
if u'background_audio' in header:
|
||||
self.background_audio = []
|
||||
for filename in header[u'background_audio']:
|
||||
|
@ -104,7 +104,7 @@ class SettingsManager(object):
|
||||
u'%s count' % name, QtCore.QVariant(0)).toInt()[0]
|
||||
new_count = len(list)
|
||||
settings.setValue(u'%s count' % name, QtCore.QVariant(new_count))
|
||||
for counter in range (0, new_count):
|
||||
for counter in range(new_count):
|
||||
settings.setValue(
|
||||
u'%s %d' % (name, counter), QtCore.QVariant(list[counter-1]))
|
||||
if old_count > new_count:
|
||||
@ -130,7 +130,7 @@ class SettingsManager(object):
|
||||
u'%s count' % name, QtCore.QVariant(0)).toInt()[0]
|
||||
list = []
|
||||
if list_count:
|
||||
for counter in range(0, list_count):
|
||||
for counter in range(list_count):
|
||||
item = unicode(
|
||||
settings.value(u'%s %d' % (name, counter)).toString())
|
||||
if item:
|
||||
|
@ -47,7 +47,7 @@ class SettingsTab(QtGui.QWidget):
|
||||
self.tabTitleVisible = visible_title
|
||||
self.settingsSection = self.tabTitle.lower()
|
||||
if icon_path:
|
||||
self.icon_path = icon_path
|
||||
self.iconPath = icon_path
|
||||
self.setupUi()
|
||||
self.retranslateUi()
|
||||
self.initialise()
|
||||
|
@ -143,6 +143,7 @@ class UiStrings(object):
|
||||
self.View = translate('OpenLP.Ui', 'View')
|
||||
self.ViewMode = translate('OpenLP.Ui', 'View Mode')
|
||||
|
||||
|
||||
def add_welcome_page(parent, image):
|
||||
"""
|
||||
Generate an opening welcome page for a wizard using a provided image.
|
||||
@ -170,6 +171,7 @@ def add_welcome_page(parent, image):
|
||||
parent.welcomeLayout.addStretch()
|
||||
parent.addPage(parent.welcomePage)
|
||||
|
||||
|
||||
def create_button_box(dialog, name, standard_buttons, custom_buttons=[]):
|
||||
"""
|
||||
Creates a QDialogButtonBox with the given buttons. The ``accepted()`` and
|
||||
@ -216,6 +218,7 @@ def create_button_box(dialog, name, standard_buttons, custom_buttons=[]):
|
||||
dialog.reject)
|
||||
return button_box
|
||||
|
||||
|
||||
def critical_error_message_box(title=None, message=None, parent=None,
|
||||
question=False):
|
||||
"""
|
||||
@ -242,6 +245,7 @@ def critical_error_message_box(title=None, message=None, parent=None,
|
||||
data[u'title'] = title if title else UiStrings().Error
|
||||
return Receiver.send_message(u'openlp_error_message', data)
|
||||
|
||||
|
||||
def create_horizontal_adjusting_combo_box(parent, name):
|
||||
"""
|
||||
Creates a QComboBox with adapting width for media items.
|
||||
@ -258,6 +262,7 @@ def create_horizontal_adjusting_combo_box(parent, name):
|
||||
combo.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
return combo
|
||||
|
||||
|
||||
def create_button(parent, name, **kwargs):
|
||||
"""
|
||||
Return an button with the object name set and the given parameters.
|
||||
@ -324,6 +329,7 @@ def create_button(parent, name, **kwargs):
|
||||
log.warn(u'Parameter %s was not consumed in create_button().', key)
|
||||
return button
|
||||
|
||||
|
||||
def create_action(parent, name, **kwargs):
|
||||
"""
|
||||
Return an action with the object name set and the given parameters.
|
||||
@ -411,6 +417,7 @@ def create_action(parent, name, **kwargs):
|
||||
log.warn(u'Parameter %s was not consumed in create_action().', key)
|
||||
return action
|
||||
|
||||
|
||||
def create_widget_action(parent, name=u'', **kwargs):
|
||||
"""
|
||||
Return a new QAction by calling ``create_action(parent, name, **kwargs)``.
|
||||
@ -422,6 +429,7 @@ def create_widget_action(parent, name=u'', **kwargs):
|
||||
parent.addAction(action)
|
||||
return action
|
||||
|
||||
|
||||
def set_case_insensitive_completer(cache, widget):
|
||||
"""
|
||||
Sets a case insensitive text completer for a widget.
|
||||
@ -436,6 +444,7 @@ def set_case_insensitive_completer(cache, widget):
|
||||
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
|
||||
widget.setCompleter(completer)
|
||||
|
||||
|
||||
def create_valign_selection_widgets(parent):
|
||||
"""
|
||||
Creates a standard label and combo box for asking users to select a
|
||||
@ -455,6 +464,7 @@ def create_valign_selection_widgets(parent):
|
||||
label.setBuddy(combo_box)
|
||||
return label, combo_box
|
||||
|
||||
|
||||
def find_and_set_in_combo_box(combo_box, value_to_find):
|
||||
"""
|
||||
Find a string in a combo box and set it as the selected item if present
|
||||
|
@ -209,7 +209,7 @@ class Theme(object):
|
||||
val = int(element_text[1:], 16)
|
||||
except ValueError: # nope
|
||||
pass
|
||||
elif DELPHI_COLORS.has_key(element_text):
|
||||
elif element_text in DELPHI_COLORS:
|
||||
val = DELPHI_COLORS[element_text]
|
||||
delphi_color_change = True
|
||||
else:
|
||||
|
@ -59,7 +59,7 @@ class AdvancedTab(SettingsTab):
|
||||
'#strftime-strptime-behavior for more information.'))
|
||||
self.defaultImage = u':/graphics/openlp-splash-screen.png'
|
||||
self.defaultColor = u'#ffffff'
|
||||
self.icon_path = u':/system/system_settings.png'
|
||||
self.iconPath = u':/system/system_settings.png'
|
||||
advanced_translated = translate('OpenLP.AdvancedTab', 'Advanced')
|
||||
SettingsTab.__init__(self, parent, u'Advanced', advanced_translated)
|
||||
|
||||
|
@ -77,6 +77,8 @@ try:
|
||||
UNO_VERSION = node.getByName(u'ooSetupVersion')
|
||||
except ImportError:
|
||||
UNO_VERSION = u'-'
|
||||
except:
|
||||
UNO_VERSION = u'- (Possible non-standard UNO installation)'
|
||||
try:
|
||||
WEBKIT_VERSION = QtWebKit.qWebKitVersion()
|
||||
except AttributeError:
|
||||
|
@ -57,6 +57,14 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
QtCore.SIGNAL(u'clicked()'), self.onDeleteClicked)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
|
||||
self.close)
|
||||
QtCore.QObject.connect(self.descriptionLineEdit,
|
||||
QtCore.SIGNAL(u'textEdited(QString)'), self.onTextEdited)
|
||||
QtCore.QObject.connect(self.tagLineEdit,
|
||||
QtCore.SIGNAL(u'textEdited(QString)'), self.onTextEdited)
|
||||
QtCore.QObject.connect(self.startTagLineEdit,
|
||||
QtCore.SIGNAL(u'textEdited(QString)'), self.onTextEdited)
|
||||
QtCore.QObject.connect(self.endTagLineEdit,
|
||||
QtCore.SIGNAL(u'textEdited(QString)'), self.onTextEdited)
|
||||
# Forces reloading of tags from openlp configuration.
|
||||
FormattingTags.load_tags()
|
||||
|
||||
@ -65,7 +73,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
Load Display and set field state.
|
||||
"""
|
||||
# Create initial copy from master
|
||||
self._resetTable()
|
||||
self._reloadTable()
|
||||
self.selected = -1
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
@ -73,9 +81,9 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
"""
|
||||
Table Row selected so display items and set field state.
|
||||
"""
|
||||
row = self.tagTableWidget.currentRow()
|
||||
html = FormattingTags.html_expands[row]
|
||||
self.selected = row
|
||||
self.savePushButton.setEnabled(False)
|
||||
self.selected = self.tagTableWidget.currentRow()
|
||||
html = FormattingTags.get_html_tags()[self.selected]
|
||||
self.descriptionLineEdit.setText(html[u'desc'])
|
||||
self.tagLineEdit.setText(self._strip(html[u'start tag']))
|
||||
self.startTagLineEdit.setText(html[u'start html'])
|
||||
@ -85,21 +93,26 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
self.tagLineEdit.setEnabled(False)
|
||||
self.startTagLineEdit.setEnabled(False)
|
||||
self.endTagLineEdit.setEnabled(False)
|
||||
self.savePushButton.setEnabled(False)
|
||||
self.deletePushButton.setEnabled(False)
|
||||
else:
|
||||
self.descriptionLineEdit.setEnabled(True)
|
||||
self.tagLineEdit.setEnabled(True)
|
||||
self.startTagLineEdit.setEnabled(True)
|
||||
self.endTagLineEdit.setEnabled(True)
|
||||
self.savePushButton.setEnabled(True)
|
||||
self.deletePushButton.setEnabled(True)
|
||||
|
||||
def onTextEdited(self, text):
|
||||
"""
|
||||
Enable the ``savePushButton`` when any of the selected tag's properties
|
||||
has been changed.
|
||||
"""
|
||||
self.savePushButton.setEnabled(True)
|
||||
|
||||
def onNewClicked(self):
|
||||
"""
|
||||
Add a new tag to list only if it is not a duplicate.
|
||||
"""
|
||||
for html in FormattingTags.html_expands:
|
||||
for html in FormattingTags.get_html_tags():
|
||||
if self._strip(html[u'start tag']) == u'n':
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.FormattingTagForm', 'Update Error'),
|
||||
@ -117,11 +130,13 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
u'temporary': False
|
||||
}
|
||||
FormattingTags.add_html_tags([tag])
|
||||
self._resetTable()
|
||||
FormattingTags.save_html_tags()
|
||||
self._reloadTable()
|
||||
# Highlight new row
|
||||
self.tagTableWidget.selectRow(self.tagTableWidget.rowCount() - 1)
|
||||
self.onRowSelected()
|
||||
self.tagTableWidget.scrollToBottom()
|
||||
#self.savePushButton.setEnabled(False)
|
||||
|
||||
def onDeleteClicked(self):
|
||||
"""
|
||||
@ -130,14 +145,14 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
if self.selected != -1:
|
||||
FormattingTags.remove_html_tag(self.selected)
|
||||
self.selected = -1
|
||||
self._resetTable()
|
||||
FormattingTags.save_html_tags()
|
||||
FormattingTags.save_html_tags()
|
||||
self._reloadTable()
|
||||
|
||||
def onSavedClicked(self):
|
||||
"""
|
||||
Update Custom Tag details if not duplicate and save the data.
|
||||
"""
|
||||
html_expands = FormattingTags.html_expands
|
||||
html_expands = FormattingTags.get_html_tags()
|
||||
if self.selected != -1:
|
||||
html = html_expands[self.selected]
|
||||
tag = unicode(self.tagLineEdit.text())
|
||||
@ -157,10 +172,10 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
# Keep temporary tags when the user changes one.
|
||||
html[u'temporary'] = False
|
||||
self.selected = -1
|
||||
self._resetTable()
|
||||
FormattingTags.save_html_tags()
|
||||
self._reloadTable()
|
||||
|
||||
def _resetTable(self):
|
||||
def _reloadTable(self):
|
||||
"""
|
||||
Reset List for loading.
|
||||
"""
|
||||
@ -169,7 +184,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
self.newPushButton.setEnabled(True)
|
||||
self.savePushButton.setEnabled(False)
|
||||
self.deletePushButton.setEnabled(False)
|
||||
for linenumber, html in enumerate(FormattingTags.html_expands):
|
||||
for linenumber, html in enumerate(FormattingTags.get_html_tags()):
|
||||
self.tagTableWidget.setRowCount(self.tagTableWidget.rowCount() + 1)
|
||||
self.tagTableWidget.setItem(linenumber, 0,
|
||||
QtGui.QTableWidgetItem(html[u'desc']))
|
||||
|
@ -43,7 +43,7 @@ class GeneralTab(SettingsTab):
|
||||
Initialise the general settings tab
|
||||
"""
|
||||
self.screens = ScreenList.get_instance()
|
||||
self.icon_path = u':/icon/openlp-logo-16x16.png'
|
||||
self.iconPath = u':/icon/openlp-logo-16x16.png'
|
||||
generalTranslated = translate('OpenLP.GeneralTab', 'General')
|
||||
SettingsTab.__init__(self, parent, u'General', generalTranslated)
|
||||
|
||||
|
@ -554,9 +554,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
# (not for use by plugins)
|
||||
self.uiSettingsSection = u'user interface'
|
||||
self.generalSettingsSection = u'general'
|
||||
self.advancedlSettingsSection = u'advanced'
|
||||
self.advancedSettingsSection = u'advanced'
|
||||
self.shortcutsSettingsSection = u'shortcuts'
|
||||
self.servicemanagerSettingsSection = u'servicemanager'
|
||||
self.serviceManagerSettingsSection = u'servicemanager'
|
||||
self.songsSettingsSection = u'songs'
|
||||
self.themesSettingsSection = u'themes'
|
||||
self.displayTagsSection = u'displayTags'
|
||||
@ -568,8 +568,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.shortcutForm = ShortcutListForm(self)
|
||||
self.recentFiles = QtCore.QStringList()
|
||||
# Set up the path with plugins
|
||||
pluginpath = AppLocation.get_directory(AppLocation.PluginsDir)
|
||||
self.pluginManager = PluginManager(pluginpath)
|
||||
plugin_path = AppLocation.get_directory(AppLocation.PluginsDir)
|
||||
self.pluginManager = PluginManager(plugin_path)
|
||||
self.pluginHelpers = {}
|
||||
self.imageManager = ImageManager()
|
||||
self.mediaController = MediaController(self)
|
||||
@ -661,7 +661,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.pluginHelpers[u'pluginmanager'] = self.pluginManager
|
||||
self.pluginHelpers[u'formparent'] = self
|
||||
self.pluginHelpers[u'mediacontroller'] = self.mediaController
|
||||
self.pluginManager.find_plugins(pluginpath, self.pluginHelpers)
|
||||
self.pluginManager.find_plugins(plugin_path, self.pluginHelpers)
|
||||
# hook methods have to happen after find_plugins. Find plugins needs
|
||||
# the controllers hence the hooks have moved from setupUI() to here
|
||||
# Find and insert settings tabs
|
||||
@ -730,7 +730,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
if self.liveController.display.isVisible():
|
||||
self.liveController.display.setFocus()
|
||||
self.activateWindow()
|
||||
if len(self.arguments):
|
||||
if self.arguments:
|
||||
args = []
|
||||
for a in self.arguments:
|
||||
args.extend([a])
|
||||
@ -944,10 +944,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
setting_sections = []
|
||||
# Add main sections.
|
||||
setting_sections.extend([self.generalSettingsSection])
|
||||
setting_sections.extend([self.advancedlSettingsSection])
|
||||
setting_sections.extend([self.advancedSettingsSection])
|
||||
setting_sections.extend([self.uiSettingsSection])
|
||||
setting_sections.extend([self.shortcutsSettingsSection])
|
||||
setting_sections.extend([self.servicemanagerSettingsSection])
|
||||
setting_sections.extend([self.serviceManagerSettingsSection])
|
||||
setting_sections.extend([self.themesSettingsSection])
|
||||
setting_sections.extend([self.displayTagsSection])
|
||||
setting_sections.extend([self.headerSection])
|
||||
@ -1027,10 +1027,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
setting_sections = []
|
||||
# Add main sections.
|
||||
setting_sections.extend([self.generalSettingsSection])
|
||||
setting_sections.extend([self.advancedlSettingsSection])
|
||||
setting_sections.extend([self.advancedSettingsSection])
|
||||
setting_sections.extend([self.uiSettingsSection])
|
||||
setting_sections.extend([self.shortcutsSettingsSection])
|
||||
setting_sections.extend([self.servicemanagerSettingsSection])
|
||||
setting_sections.extend([self.serviceManagerSettingsSection])
|
||||
setting_sections.extend([self.themesSettingsSection])
|
||||
setting_sections.extend([self.displayTagsSection])
|
||||
# Add plugin sections.
|
||||
@ -1314,10 +1314,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
u'/enable slide loop'):
|
||||
if QtCore.QSettings().value(self.generalSettingsSection +
|
||||
u'/enable slide loop', QtCore.QVariant(True)).toBool():
|
||||
QtCore.QSettings().setValue(self.advancedlSettingsSection +
|
||||
QtCore.QSettings().setValue(self.advancedSettingsSection +
|
||||
u'/slide limits', QtCore.QVariant(SlideLimits.Wrap))
|
||||
else:
|
||||
QtCore.QSettings().setValue(self.advancedlSettingsSection +
|
||||
QtCore.QSettings().setValue(self.advancedSettingsSection +
|
||||
u'/slide limits', QtCore.QVariant(SlideLimits.End))
|
||||
QtCore.QSettings().remove(self.generalSettingsSection +
|
||||
u'/enable slide loop')
|
||||
|
@ -69,12 +69,13 @@ class MediaInfo(object):
|
||||
def get_media_players():
|
||||
"""
|
||||
This method extract the configured media players and overridden player from
|
||||
the settings
|
||||
the settings.
|
||||
|
||||
``players_list``
|
||||
this is a python list with all active media players
|
||||
A list with all active media players.
|
||||
|
||||
``overridden_player``
|
||||
here an special media player is choosen for all media actions
|
||||
Here an special media player is chosen for all media actions.
|
||||
"""
|
||||
log.debug(u'get_media_players')
|
||||
players = unicode(QtCore.QSettings().value(u'media/players').toString())
|
||||
@ -92,15 +93,17 @@ def get_media_players():
|
||||
players_list = players.replace(u'[', u'').replace(u']', u'').split(u',')
|
||||
return players_list, overridden_player
|
||||
|
||||
|
||||
def set_media_players(players_list, overridden_player=u'auto'):
|
||||
"""
|
||||
This method saves the configured media players and overridden player to the
|
||||
settings
|
||||
|
||||
``players_list``
|
||||
this is a python list with all active media players
|
||||
A list with all active media players.
|
||||
|
||||
``overridden_player``
|
||||
here an special media player is choosen for all media actions
|
||||
Here an special media player is chosen for all media actions.
|
||||
"""
|
||||
log.debug(u'set_media_players')
|
||||
players = u','.join(players_list)
|
||||
|
@ -84,10 +84,7 @@ class MediaController(object):
|
||||
def set_active_players(self):
|
||||
savedPlayers = get_media_players()[0]
|
||||
for player in self.mediaPlayers.keys():
|
||||
if player in savedPlayers:
|
||||
self.mediaPlayers[player].isActive = True
|
||||
else:
|
||||
self.mediaPlayers[player].isActive = False
|
||||
self.mediaPlayers[player].isActive = player in savedPlayers
|
||||
|
||||
def register_controllers(self, controller):
|
||||
"""
|
||||
@ -106,8 +103,8 @@ class MediaController(object):
|
||||
AppLocation.get_directory(AppLocation.AppDir),
|
||||
u'core', u'ui', u'media')
|
||||
for filename in os.listdir(controller_dir):
|
||||
if filename.endswith(u'player.py') and \
|
||||
not filename == 'media_player.py':
|
||||
if filename.endswith(u'player.py') and not \
|
||||
filename == 'media_player.py':
|
||||
path = os.path.join(controller_dir, filename)
|
||||
if os.path.isfile(path):
|
||||
modulename = u'openlp.core.ui.media.' + \
|
||||
@ -122,38 +119,36 @@ class MediaController(object):
|
||||
for controller_class in controller_classes:
|
||||
controller = controller_class(self)
|
||||
self.register_controllers(controller)
|
||||
if self.mediaPlayers:
|
||||
savedPlayers, overriddenPlayer = get_media_players()
|
||||
invalidMediaPlayers = [mediaPlayer for mediaPlayer in savedPlayers \
|
||||
if not mediaPlayer in self.mediaPlayers or \
|
||||
not self.mediaPlayers[mediaPlayer].check_available()]
|
||||
if len(invalidMediaPlayers) > 0:
|
||||
for invalidPlayer in invalidMediaPlayers:
|
||||
savedPlayers.remove(invalidPlayer)
|
||||
set_media_players(savedPlayers, overriddenPlayer)
|
||||
self.set_active_players()
|
||||
return True
|
||||
else:
|
||||
if not self.mediaPlayers:
|
||||
return False
|
||||
savedPlayers, overriddenPlayer = get_media_players()
|
||||
invalidMediaPlayers = [mediaPlayer for mediaPlayer in savedPlayers
|
||||
if not mediaPlayer in self.mediaPlayers or not
|
||||
self.mediaPlayers[mediaPlayer].check_available()]
|
||||
if invalidMediaPlayers:
|
||||
for invalidPlayer in invalidMediaPlayers:
|
||||
savedPlayers.remove(invalidPlayer)
|
||||
set_media_players(savedPlayers, overriddenPlayer)
|
||||
self.set_active_players()
|
||||
return True
|
||||
|
||||
def video_state(self):
|
||||
"""
|
||||
Check if there is a running media Player and do updating stuff (e.g.
|
||||
update the UI)
|
||||
"""
|
||||
if len(self.curDisplayMediaPlayer.keys()) == 0:
|
||||
if not self.curDisplayMediaPlayer.keys():
|
||||
self.timer.stop()
|
||||
else:
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
self.curDisplayMediaPlayer[display].resize(display)
|
||||
self.curDisplayMediaPlayer[display].update_ui(display)
|
||||
if self.curDisplayMediaPlayer[display] \
|
||||
.state == MediaState.Playing:
|
||||
if self.curDisplayMediaPlayer[display].state == \
|
||||
MediaState.Playing:
|
||||
return
|
||||
# no players are active anymore
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
if self.curDisplayMediaPlayer[display] \
|
||||
.state != MediaState.Paused:
|
||||
if self.curDisplayMediaPlayer[display].state != MediaState.Paused:
|
||||
display.controller.seekSlider.setSliderPosition(0)
|
||||
self.timer.stop()
|
||||
|
||||
@ -333,8 +328,7 @@ class MediaController(object):
|
||||
'Unsupported File')))
|
||||
return False
|
||||
# dont care about actual theme, set a black background
|
||||
if controller.isLive and ( \
|
||||
controller.media_info.is_background == False):
|
||||
if controller.isLive and not controller.media_info.is_background:
|
||||
display.frame.evaluateJavaScript(u'show_video( \
|
||||
"setBackBoard", null, null, null,"visible");')
|
||||
# now start playing
|
||||
@ -395,7 +389,7 @@ class MediaController(object):
|
||||
"""
|
||||
Responds to the request to play a loaded video
|
||||
|
||||
``msg``
|
||||
``msg``
|
||||
First element is the controller which should be used
|
||||
"""
|
||||
log.debug(u'video_play')
|
||||
@ -497,15 +491,15 @@ class MediaController(object):
|
||||
First element is the boolean for Live indication
|
||||
"""
|
||||
isLive = msg[1]
|
||||
if isLive:
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
if display.controller == controller:
|
||||
if self.curDisplayMediaPlayer[display] \
|
||||
.state == MediaState.Playing:
|
||||
self.curDisplayMediaPlayer[display].pause(display)
|
||||
self.curDisplayMediaPlayer[display] \
|
||||
.set_visible(display, False)
|
||||
if not isLive:
|
||||
return
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
if display.controller != controller or \
|
||||
self.curDisplayMediaPlayer[display].state != MediaState.Playing:
|
||||
continue
|
||||
self.curDisplayMediaPlayer[display].pause(display)
|
||||
self.curDisplayMediaPlayer[display].set_visible(display, False)
|
||||
|
||||
def video_blank(self, msg):
|
||||
"""
|
||||
@ -517,16 +511,16 @@ class MediaController(object):
|
||||
"""
|
||||
isLive = msg[1]
|
||||
hide_mode = msg[2]
|
||||
if isLive:
|
||||
Receiver.send_message(u'live_display_hide', hide_mode)
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
if display.controller == controller:
|
||||
if self.curDisplayMediaPlayer[display] \
|
||||
.state == MediaState.Playing:
|
||||
self.curDisplayMediaPlayer[display].pause(display)
|
||||
self.curDisplayMediaPlayer[display] \
|
||||
.set_visible(display, False)
|
||||
if not isLive:
|
||||
return
|
||||
Receiver.send_message(u'live_display_hide', hide_mode)
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
if display.controller != controller or \
|
||||
self.curDisplayMediaPlayer[display].state != MediaState.Playing:
|
||||
continue
|
||||
self.curDisplayMediaPlayer[display].pause(display)
|
||||
self.curDisplayMediaPlayer[display].set_visible(display, False)
|
||||
|
||||
def video_unblank(self, msg):
|
||||
"""
|
||||
@ -538,19 +532,18 @@ class MediaController(object):
|
||||
"""
|
||||
Receiver.send_message(u'live_display_show')
|
||||
isLive = msg[1]
|
||||
if isLive:
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
if display.controller == controller:
|
||||
if self.curDisplayMediaPlayer[display] \
|
||||
.state == MediaState.Paused:
|
||||
if self.curDisplayMediaPlayer[display].play(display):
|
||||
self.curDisplayMediaPlayer[display] \
|
||||
.set_visible(display, True)
|
||||
# Start Timer for ui updates
|
||||
if not self.timer.isActive():
|
||||
self.timer.start()
|
||||
|
||||
if not isLive:
|
||||
return
|
||||
controller = self.parent.liveController
|
||||
for display in self.curDisplayMediaPlayer.keys():
|
||||
if display.controller != controller or \
|
||||
self.curDisplayMediaPlayer[display].state != MediaState.Paused:
|
||||
continue
|
||||
if self.curDisplayMediaPlayer[display].play(display):
|
||||
self.curDisplayMediaPlayer[display].set_visible(display, True)
|
||||
# Start Timer for ui updates
|
||||
if not self.timer.isActive():
|
||||
self.timer.start()
|
||||
|
||||
def get_audio_extensions_list(self):
|
||||
audio_list = []
|
||||
@ -565,9 +558,8 @@ class MediaController(object):
|
||||
video_list = []
|
||||
for player in self.mediaPlayers.values():
|
||||
if player.isActive:
|
||||
for item in player.video_extensions_list:
|
||||
if not item in video_list:
|
||||
video_list.append(item)
|
||||
video_list.extend([item for item in player.video_extensions_list
|
||||
if item not in video_list])
|
||||
return video_list
|
||||
|
||||
def finalise(self):
|
||||
|
@ -2,25 +2,26 @@
|
||||
|
||||
# Python ctypes bindings for VLC
|
||||
#
|
||||
# Copyright (C) 2009-2010 the VideoLAN team
|
||||
# Copyright (C) 2009-2012 the VideoLAN team
|
||||
# $Id: $
|
||||
#
|
||||
# Authors: Olivier Aubert <olivier.aubert at liris.cnrs.fr>
|
||||
# Jean Brouwers <MrJean1 at gmail.com>
|
||||
# Geoff Salmon <geoff.salmon at gmail.com>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This library is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
# This library 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
|
||||
# Lesser 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
|
||||
|
||||
"""This module provides bindings for the LibVLC public API, see
|
||||
U{http://wiki.videolan.org/LibVLC}.
|
||||
@ -47,7 +48,7 @@ import sys
|
||||
from inspect import getargspec
|
||||
|
||||
__version__ = "N/A"
|
||||
build_date = "Tue Jan 17 12:20:48 2012"
|
||||
build_date = "Fri Apr 27 16:47:21 2012"
|
||||
|
||||
# Internal guard to prevent internal classes to be directly
|
||||
# instanciated.
|
||||
@ -126,7 +127,7 @@ class VLCException(Exception):
|
||||
try:
|
||||
_Ints = (int, long)
|
||||
except NameError: # no long in Python 3+
|
||||
_Ints = int
|
||||
_Ints = int
|
||||
_Seqs = (list, tuple)
|
||||
|
||||
# Default instance. It is used to instanciate classes directly in the
|
||||
@ -904,6 +905,11 @@ class Instance(_Ctype):
|
||||
def media_new(self, mrl, *options):
|
||||
"""Create a new Media instance.
|
||||
|
||||
If mrl contains a colon (:), it will be treated as a
|
||||
URL. Else, it will be considered as a local path. If you need
|
||||
more control, directly use media_new_location/media_new_path
|
||||
methods.
|
||||
|
||||
Options can be specified as supplementary string parameters, e.g.
|
||||
|
||||
C{m = i.media_new('foo.avi', 'sub-filter=marq{marquee=Hello}', 'vout-filter=invert')}
|
||||
@ -914,7 +920,12 @@ class Instance(_Ctype):
|
||||
|
||||
@param options: optional media option=value strings
|
||||
"""
|
||||
m = libvlc_media_new_location(self, mrl)
|
||||
if ':' in mrl:
|
||||
# Assume it is a URL
|
||||
m = libvlc_media_new_location(self, mrl)
|
||||
else:
|
||||
# Else it should be a local path.
|
||||
m = libvlc_media_new_path(self, mrl)
|
||||
for o in options:
|
||||
libvlc_media_add_option(m, o)
|
||||
m._instance = self
|
||||
@ -1511,7 +1522,7 @@ class Media(_Ctype):
|
||||
|
||||
def save_meta(self):
|
||||
'''Save the meta previously set.
|
||||
@return: true if the write operation was successfull.
|
||||
@return: true if the write operation was successful.
|
||||
'''
|
||||
return libvlc_media_save_meta(self)
|
||||
|
||||
@ -2230,7 +2241,7 @@ class MediaPlayer(_Ctype):
|
||||
@param format: a four-characters string identifying the sample format (e.g. "S16N" or "FL32").
|
||||
@param rate: sample rate (expressed in Hz).
|
||||
@param channels: channels count.
|
||||
@version: LibVLC 1.2.0 or later.
|
||||
@version: LibVLC 2.0.0 or later.
|
||||
'''
|
||||
return libvlc_audio_set_format(self, format, rate, channels)
|
||||
|
||||
@ -2378,7 +2389,7 @@ class MediaPlayer(_Ctype):
|
||||
def navigate(self, navigate):
|
||||
'''Navigate through DVD Menu.
|
||||
@param navigate: the Navigation mode.
|
||||
@version: libVLC 1.2.0 or later.
|
||||
@version: libVLC 2.0.0 or later.
|
||||
'''
|
||||
return libvlc_media_player_navigate(self, navigate)
|
||||
|
||||
@ -2489,7 +2500,7 @@ class MediaPlayer(_Ctype):
|
||||
'''Get the current subtitle delay. Positive values means subtitles are being
|
||||
displayed later, negative values earlier.
|
||||
@return: time (in microseconds) the display of subtitles is being delayed.
|
||||
@version: LibVLC 1.2.0 or later.
|
||||
@version: LibVLC 2.0.0 or later.
|
||||
'''
|
||||
return libvlc_video_get_spu_delay(self)
|
||||
|
||||
@ -2500,7 +2511,7 @@ class MediaPlayer(_Ctype):
|
||||
The subtitle delay will be reset to zero each time the media changes.
|
||||
@param i_delay: time (in microseconds) the display of subtitles should be delayed.
|
||||
@return: 0 on success, -1 on error.
|
||||
@version: LibVLC 1.2.0 or later.
|
||||
@version: LibVLC 2.0.0 or later.
|
||||
'''
|
||||
return libvlc_video_set_spu_delay(self, i_delay)
|
||||
|
||||
@ -3247,7 +3258,7 @@ def libvlc_media_set_meta(p_md, e_meta, psz_value):
|
||||
def libvlc_media_save_meta(p_md):
|
||||
'''Save the meta previously set.
|
||||
@param p_md: the media desriptor.
|
||||
@return: true if the write operation was successfull.
|
||||
@return: true if the write operation was successful.
|
||||
'''
|
||||
f = _Cfunctions.get('libvlc_media_save_meta', None) or \
|
||||
_Cfunction('libvlc_media_save_meta', ((1,),), None,
|
||||
@ -4084,7 +4095,7 @@ def libvlc_audio_set_format(mp, format, rate, channels):
|
||||
@param format: a four-characters string identifying the sample format (e.g. "S16N" or "FL32").
|
||||
@param rate: sample rate (expressed in Hz).
|
||||
@param channels: channels count.
|
||||
@version: LibVLC 1.2.0 or later.
|
||||
@version: LibVLC 2.0.0 or later.
|
||||
'''
|
||||
f = _Cfunctions.get('libvlc_audio_set_format', None) or \
|
||||
_Cfunction('libvlc_audio_set_format', ((1,), (1,), (1,), (1,),), None,
|
||||
@ -4328,7 +4339,7 @@ def libvlc_media_player_navigate(p_mi, navigate):
|
||||
'''Navigate through DVD Menu.
|
||||
@param p_mi: the Media Player.
|
||||
@param navigate: the Navigation mode.
|
||||
@version: libVLC 1.2.0 or later.
|
||||
@version: libVLC 2.0.0 or later.
|
||||
'''
|
||||
f = _Cfunctions.get('libvlc_media_player_navigate', None) or \
|
||||
_Cfunction('libvlc_media_player_navigate', ((1,), (1,),), None,
|
||||
@ -4554,7 +4565,7 @@ def libvlc_video_get_spu_delay(p_mi):
|
||||
displayed later, negative values earlier.
|
||||
@param p_mi: media player.
|
||||
@return: time (in microseconds) the display of subtitles is being delayed.
|
||||
@version: LibVLC 1.2.0 or later.
|
||||
@version: LibVLC 2.0.0 or later.
|
||||
'''
|
||||
f = _Cfunctions.get('libvlc_video_get_spu_delay', None) or \
|
||||
_Cfunction('libvlc_video_get_spu_delay', ((1,),), None,
|
||||
@ -4569,7 +4580,7 @@ def libvlc_video_set_spu_delay(p_mi, i_delay):
|
||||
@param p_mi: media player.
|
||||
@param i_delay: time (in microseconds) the display of subtitles should be delayed.
|
||||
@return: 0 on success, -1 on error.
|
||||
@version: LibVLC 1.2.0 or later.
|
||||
@version: LibVLC 2.0.0 or later.
|
||||
'''
|
||||
f = _Cfunctions.get('libvlc_video_set_spu_delay', None) or \
|
||||
_Cfunction('libvlc_video_set_spu_delay', ((1,), (1,),), None,
|
||||
|
@ -25,30 +25,42 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
import logging
|
||||
import sys, os
|
||||
from datetime import datetime
|
||||
try:
|
||||
import vlc
|
||||
vlc_available = bool(vlc.get_default_instance())
|
||||
except (ImportError, NameError):
|
||||
vlc_available = False
|
||||
except OSError, e:
|
||||
if sys.platform.startswith('win'):
|
||||
if isinstance(e, WindowsError) and e.winerror == 126:
|
||||
vlc_available = False
|
||||
else:
|
||||
raise
|
||||
else:
|
||||
raise
|
||||
from distutils.version import LooseVersion
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver
|
||||
from openlp.core.lib.mediaplayer import MediaPlayer
|
||||
from openlp.core.ui.media import MediaState
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
VLC_AVAILABLE = False
|
||||
try:
|
||||
import vlc
|
||||
VLC_AVAILABLE = bool(vlc.get_default_instance())
|
||||
except (ImportError, NameError):
|
||||
pass
|
||||
except OSError, e:
|
||||
if sys.platform.startswith('win'):
|
||||
if not isinstance(e, WindowsError) and e.winerror != 126:
|
||||
raise
|
||||
else:
|
||||
raise
|
||||
|
||||
if VLC_AVAILABLE:
|
||||
try:
|
||||
version = vlc.libvlc_get_version()
|
||||
except:
|
||||
version = u'0.0.0'
|
||||
if LooseVersion(version) < LooseVersion('1.1.0'):
|
||||
VLC_AVAILABLE = False
|
||||
log.debug(u'VLC could not be loaded: %s' % version)
|
||||
|
||||
AUDIO_EXT = [
|
||||
u'*.mp3'
|
||||
, u'*.wav'
|
||||
@ -128,7 +140,7 @@ class VlcPlayer(MediaPlayer):
|
||||
self.hasOwnWidget = True
|
||||
|
||||
def check_available(self):
|
||||
return vlc_available
|
||||
return VLC_AVAILABLE
|
||||
|
||||
def load(self, display):
|
||||
log.debug(u'load vid in Vlc Controller')
|
||||
|
@ -64,7 +64,7 @@ class MediaDockManager(object):
|
||||
visible_title = media_item.plugin.getString(StringContent.VisibleName)
|
||||
log.debug(u'Inserting %s dock' % visible_title[u'title'])
|
||||
match = False
|
||||
for dock_index in range(0, self.media_dock.count()):
|
||||
for dock_index in range(self.media_dock.count()):
|
||||
if self.media_dock.widget(dock_index).settingsSection == \
|
||||
media_item.plugin.name:
|
||||
match = True
|
||||
@ -81,7 +81,7 @@ class MediaDockManager(object):
|
||||
"""
|
||||
visible_title = media_item.plugin.getString(StringContent.VisibleName)
|
||||
log.debug(u'remove %s dock' % visible_title[u'title'])
|
||||
for dock_index in range(0, self.media_dock.count()):
|
||||
for dock_index in range(self.media_dock.count()):
|
||||
if self.media_dock.widget(dock_index):
|
||||
if self.media_dock.widget(dock_index).settingsSection == \
|
||||
media_item.plugin.name:
|
||||
|
@ -106,13 +106,13 @@ class ScreenList(object):
|
||||
"""
|
||||
# Do not log at start up.
|
||||
if changed_screen != -1:
|
||||
log.info(u'screen_count_changed %d' % self.desktop.numScreens())
|
||||
log.info(u'screen_count_changed %d' % self.desktop.screenCount())
|
||||
# Remove unplugged screens.
|
||||
for screen in copy.deepcopy(self.screen_list):
|
||||
if screen[u'number'] == self.desktop.numScreens():
|
||||
if screen[u'number'] == self.desktop.screenCount():
|
||||
self.remove_screen(screen[u'number'])
|
||||
# Add new screens.
|
||||
for number in xrange(0, self.desktop.numScreens()):
|
||||
for number in xrange(self.desktop.screenCount()):
|
||||
if not self.screen_exists(number):
|
||||
self.add_screen({
|
||||
u'number': number,
|
||||
|
@ -51,7 +51,7 @@ class ServiceManagerList(QtGui.QTreeWidget):
|
||||
"""
|
||||
Set up key bindings and mouse behaviour for the service list
|
||||
"""
|
||||
def __init__(self, serviceManager, parent=None, name=None):
|
||||
def __init__(self, serviceManager, parent=None):
|
||||
QtGui.QTreeWidget.__init__(self, parent)
|
||||
self.serviceManager = serviceManager
|
||||
|
||||
@ -101,7 +101,6 @@ class ServiceManager(QtGui.QWidget):
|
||||
QtGui.QWidget.__init__(self, parent)
|
||||
self.mainwindow = mainwindow
|
||||
self.serviceItems = []
|
||||
self.serviceName = u''
|
||||
self.suffixes = []
|
||||
self.dropPosition = 0
|
||||
self.expandTabs = False
|
||||
@ -272,7 +271,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate)
|
||||
# Last little bits of setting up
|
||||
self.service_theme = unicode(QtCore.QSettings().value(
|
||||
self.mainwindow.servicemanagerSettingsSection + u'/service theme',
|
||||
self.mainwindow.serviceManagerSettingsSection + u'/service theme',
|
||||
QtCore.QVariant(u'')).toString())
|
||||
self.servicePath = AppLocation.get_section_data_path(u'servicemanager')
|
||||
# build the drag and drop context menu
|
||||
@ -411,7 +410,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.mainwindow,
|
||||
translate('OpenLP.ServiceManager', 'Open File'),
|
||||
SettingsManager.get_last_dir(
|
||||
self.mainwindow.servicemanagerSettingsSection),
|
||||
self.mainwindow.serviceManagerSettingsSection),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'OpenLP Service Files (*.osz)')))
|
||||
if not fileName:
|
||||
@ -419,7 +418,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
else:
|
||||
fileName = loadFile
|
||||
SettingsManager.set_last_dir(
|
||||
self.mainwindow.servicemanagerSettingsSection,
|
||||
self.mainwindow.serviceManagerSettingsSection,
|
||||
split_filename(fileName)[0])
|
||||
self.loadFile(fileName)
|
||||
|
||||
@ -469,7 +468,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
service_file_name = '%s.osd' % basename
|
||||
log.debug(u'ServiceManager.saveFile - %s', path_file_name)
|
||||
SettingsManager.set_last_dir(
|
||||
self.mainwindow.servicemanagerSettingsSection,
|
||||
self.mainwindow.serviceManagerSettingsSection,
|
||||
path)
|
||||
service = []
|
||||
write_list = []
|
||||
@ -483,7 +482,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
service_item = item[u'service_item'].get_service_repr()
|
||||
# Get all the audio files, and ready them for embedding in the
|
||||
# service file.
|
||||
if len(service_item[u'header'][u'background_audio']) > 0:
|
||||
if service_item[u'header'][u'background_audio']:
|
||||
for i, filename in \
|
||||
enumerate(service_item[u'header'][u'background_audio']):
|
||||
new_file = os.path.join(u'audio',
|
||||
@ -622,7 +621,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
else:
|
||||
default_filename = u''
|
||||
directory = unicode(SettingsManager.get_last_dir(
|
||||
self.mainwindow.servicemanagerSettingsSection))
|
||||
self.mainwindow.serviceManagerSettingsSection))
|
||||
path = os.path.join(directory, default_filename)
|
||||
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
|
||||
UiStrings().SaveService, path,
|
||||
@ -822,7 +821,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
"""
|
||||
Called by the SlideController to select the next service item.
|
||||
"""
|
||||
if len(self.serviceManagerList.selectedItems()) == 0:
|
||||
if not self.serviceManagerList.selectedItems():
|
||||
return
|
||||
selected = self.serviceManagerList.selectedItems()[0]
|
||||
lookFor = 0
|
||||
@ -840,7 +839,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
"""
|
||||
Called by the SlideController to select the previous service item.
|
||||
"""
|
||||
if len(self.serviceManagerList.selectedItems()) == 0:
|
||||
if not self.serviceManagerList.selectedItems():
|
||||
return
|
||||
selected = self.serviceManagerList.selectedItems()[0]
|
||||
prevItem = None
|
||||
@ -1107,7 +1106,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.service_theme = unicode(self.themeComboBox.currentText())
|
||||
self.mainwindow.renderer.set_service_theme(self.service_theme)
|
||||
QtCore.QSettings().setValue(
|
||||
self.mainwindow.servicemanagerSettingsSection +
|
||||
self.mainwindow.serviceManagerSettingsSection +
|
||||
u'/service theme',
|
||||
QtCore.QVariant(self.service_theme))
|
||||
self.regenerateServiceItems(True)
|
||||
|
@ -65,8 +65,8 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
self.insertTab(self.advancedTab, 2, PluginStatus.Active)
|
||||
count = 3
|
||||
for plugin in self.plugins:
|
||||
if plugin.settings_tab:
|
||||
self.insertTab(plugin.settings_tab, count, plugin.status)
|
||||
if plugin.settingsTab:
|
||||
self.insertTab(plugin.settingsTab, count, plugin.status)
|
||||
count += 1
|
||||
self.settingListWidget.setCurrentRow(0)
|
||||
return QtGui.QDialog.exec_(self)
|
||||
@ -80,7 +80,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
pos = self.stackedLayout.addWidget(tab)
|
||||
if is_active:
|
||||
item_name = QtGui.QListWidgetItem(tab.tabTitleVisible)
|
||||
icon = build_icon(tab.icon_path)
|
||||
icon = build_icon(tab.iconPath)
|
||||
item_name.setIcon(icon)
|
||||
self.settingListWidget.insertItem(location, item_name)
|
||||
else:
|
||||
@ -92,7 +92,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
"""
|
||||
Process the form saving the settings
|
||||
"""
|
||||
for tabIndex in range(0, self.stackedLayout.count()):
|
||||
for tabIndex in range(self.stackedLayout.count()):
|
||||
self.stackedLayout.widget(tabIndex).save()
|
||||
# Must go after all settings are save
|
||||
Receiver.send_message(u'config_updated')
|
||||
@ -102,7 +102,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
"""
|
||||
Process the form saving the settings
|
||||
"""
|
||||
for tabIndex in range(0, self.stackedLayout.count()):
|
||||
for tabIndex in range(self.stackedLayout.count()):
|
||||
self.stackedLayout.widget(tabIndex).cancel()
|
||||
return QtGui.QDialog.reject(self)
|
||||
|
||||
@ -114,8 +114,8 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
self.themesTab.postSetUp()
|
||||
self.advancedTab.postSetUp()
|
||||
for plugin in self.plugins:
|
||||
if plugin.settings_tab:
|
||||
plugin.settings_tab.postSetUp()
|
||||
if plugin.settingsTab:
|
||||
plugin.settingsTab.postSetUp()
|
||||
|
||||
def tabChanged(self, tabIndex):
|
||||
"""
|
||||
|
@ -151,7 +151,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
if action is None:
|
||||
continue
|
||||
shortcuts = self._actionShortcuts(action)
|
||||
if len(shortcuts) == 0:
|
||||
if not shortcuts:
|
||||
item.setText(1, u'')
|
||||
item.setText(2, u'')
|
||||
elif len(shortcuts) == 1:
|
||||
@ -195,7 +195,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
return
|
||||
shortcuts = self._actionShortcuts(action)
|
||||
new_shortcuts = []
|
||||
if len(shortcuts) != 0:
|
||||
if shortcuts:
|
||||
new_shortcuts.append(shortcuts[0])
|
||||
new_shortcuts.append(
|
||||
QtGui.QKeySequence(self.alternatePushButton.text()))
|
||||
@ -241,7 +241,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
self.primaryPushButton.setChecked(False)
|
||||
self.alternatePushButton.setChecked(False)
|
||||
else:
|
||||
if len(action.defaultShortcuts) != 0:
|
||||
if action.defaultShortcuts:
|
||||
primary_label_text = action.defaultShortcuts[0].toString()
|
||||
if len(action.defaultShortcuts) == 2:
|
||||
alternate_label_text = action.defaultShortcuts[1].toString()
|
||||
@ -313,7 +313,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
self.refreshShortcutList()
|
||||
primary_button_text = u''
|
||||
alternate_button_text = u''
|
||||
if len(temp_shortcuts) != 0:
|
||||
if temp_shortcuts:
|
||||
primary_button_text = temp_shortcuts[0].toString()
|
||||
if len(temp_shortcuts) == 2:
|
||||
alternate_button_text = temp_shortcuts[1].toString()
|
||||
@ -363,7 +363,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
return
|
||||
shortcuts = self._actionShortcuts(action)
|
||||
new_shortcuts = []
|
||||
if len(action.defaultShortcuts) != 0:
|
||||
if action.defaultShortcuts:
|
||||
new_shortcuts.append(action.defaultShortcuts[0])
|
||||
# We have to check if the primary default shortcut is available. But
|
||||
# we only have to check, if the action has a default primary
|
||||
@ -391,7 +391,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
return
|
||||
shortcuts = self._actionShortcuts(action)
|
||||
new_shortcuts = []
|
||||
if len(shortcuts) != 0:
|
||||
if shortcuts:
|
||||
new_shortcuts.append(shortcuts[0])
|
||||
if len(action.defaultShortcuts) == 2:
|
||||
new_shortcuts.append(action.defaultShortcuts[1])
|
||||
|
@ -373,7 +373,7 @@ class SlideController(Controller):
|
||||
u'text': translate('OpenLP.SlideController', 'Go to "Ending"')},
|
||||
{u'key': u'O', u'configurable': True,
|
||||
u'text': translate('OpenLP.SlideController', 'Go to "Other"')}]
|
||||
shortcuts += [{u'key': unicode(number)} for number in range(0, 10)]
|
||||
shortcuts += [{u'key': unicode(number)} for number in range(10)]
|
||||
self.previewListWidget.addActions([create_action(self,
|
||||
u'shortcutAction_%s' % s[u'key'], text=s.get(u'text'),
|
||||
shortcuts=[QtGui.QKeySequence(s[u'key'])],
|
||||
@ -555,7 +555,7 @@ class SlideController(Controller):
|
||||
Process the service item request queue. The key presses can arrive
|
||||
faster than the processing so implement a FIFO queue.
|
||||
"""
|
||||
if len(self.keypress_queue):
|
||||
if self.keypress_queue:
|
||||
while len(self.keypress_queue) and not self.keypress_loop:
|
||||
self.keypress_loop = True
|
||||
keypressCommand = self.keypress_queue.popleft()
|
||||
@ -648,8 +648,8 @@ class SlideController(Controller):
|
||||
|
||||
def onSongBarHandler(self):
|
||||
request = unicode(self.sender().text())
|
||||
slideno = self.slideList[request]
|
||||
self.__updatePreviewSelection(slideno)
|
||||
slide_no = self.slideList[request]
|
||||
self.__updatePreviewSelection(slide_no)
|
||||
self.slideSelected()
|
||||
|
||||
def receiveSpinDelay(self, value):
|
||||
@ -663,7 +663,7 @@ class SlideController(Controller):
|
||||
Updates the Slide Limits variable from the settings.
|
||||
"""
|
||||
self.slide_limits = QtCore.QSettings().value(
|
||||
self.parent().advancedlSettingsSection + u'/slide limits',
|
||||
self.parent().advancedSettingsSection + u'/slide limits',
|
||||
QtCore.QVariant(SlideLimits.End)).toInt()[0]
|
||||
|
||||
def enableToolBar(self, item):
|
||||
@ -694,7 +694,7 @@ class SlideController(Controller):
|
||||
if item.is_text():
|
||||
if QtCore.QSettings().value(
|
||||
self.parent().songsSettingsSection + u'/display songbar',
|
||||
QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
|
||||
QtCore.QVariant(True)).toBool() and self.slideList:
|
||||
self.songMenu.show()
|
||||
if item.is_capable(ItemCapabilities.CanLoop) and \
|
||||
len(item.get_frames()) > 1:
|
||||
|
@ -444,7 +444,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
self.firstTime()
|
||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
||||
# No themes have been found so create one
|
||||
if len(files) == 0:
|
||||
if not files:
|
||||
theme = ThemeXML()
|
||||
theme.theme_name = UiStrings().Default
|
||||
self._writeTheme(theme, None, None)
|
||||
|
@ -39,7 +39,7 @@ class ThemesTab(SettingsTab):
|
||||
self.mainwindow = mainwindow
|
||||
generalTranslated = translate('OpenLP.ThemesTab', 'Themes')
|
||||
SettingsTab.__init__(self, parent, u'Themes', generalTranslated)
|
||||
self.icon_path = u':/themes/theme_new.png'
|
||||
self.iconPath = u':/themes/theme_new.png'
|
||||
|
||||
def setupUi(self):
|
||||
self.setObjectName(u'ThemesTab')
|
||||
|
@ -46,12 +46,14 @@ class WizardStrings(object):
|
||||
# the writers translating their own product name.
|
||||
CCLI = u'CCLI/SongSelect'
|
||||
CSV = u'CSV'
|
||||
DB = u'DreamBeam'
|
||||
EW = u'EasyWorship'
|
||||
ES = u'EasySlides'
|
||||
FP = u'Foilpresenter'
|
||||
OL = u'OpenLyrics'
|
||||
OS = u'OpenSong'
|
||||
OSIS = u'OSIS'
|
||||
PS = u'PowerSong 1.0'
|
||||
SB = u'SongBeamer'
|
||||
SoF = u'Songs of Fellowship'
|
||||
SSP = u'SongShow Plus'
|
||||
|
@ -27,14 +27,15 @@
|
||||
"""
|
||||
The :mod:`openlp.core.utils` module provides the utility libraries for OpenLP.
|
||||
"""
|
||||
from datetime import datetime
|
||||
from distutils.version import LooseVersion
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from subprocess import Popen, PIPE
|
||||
import sys
|
||||
import time
|
||||
import urllib2
|
||||
from datetime import datetime
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from PyQt4 import QtGui, QtCore
|
||||
|
||||
@ -55,7 +56,6 @@ UNO_CONNECTION_TYPE = u'pipe'
|
||||
#UNO_CONNECTION_TYPE = u'socket'
|
||||
CONTROL_CHARS = re.compile(r'[\x00-\x1F\x7F-\x9F]', re.UNICODE)
|
||||
INVALID_FILE_CHARS = re.compile(r'[\\/:\*\?"<>\|\+\[\]%]', re.UNICODE)
|
||||
VERSION_SPLITTER = re.compile(r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))?')
|
||||
|
||||
class VersionThread(QtCore.QThread):
|
||||
"""
|
||||
@ -72,48 +72,8 @@ class VersionThread(QtCore.QThread):
|
||||
time.sleep(1)
|
||||
app_version = get_application_version()
|
||||
version = check_latest_version(app_version)
|
||||
remote_version = {}
|
||||
local_version = {}
|
||||
match = VERSION_SPLITTER.match(version)
|
||||
if match:
|
||||
remote_version[u'major'] = int(match.group(1))
|
||||
remote_version[u'minor'] = int(match.group(2))
|
||||
remote_version[u'release'] = int(match.group(3))
|
||||
if len(match.groups()) > 3 and match.group(4):
|
||||
remote_version[u'revision'] = int(match.group(4))
|
||||
else:
|
||||
return
|
||||
match = VERSION_SPLITTER.match(app_version[u'full'])
|
||||
if match:
|
||||
local_version[u'major'] = int(match.group(1))
|
||||
local_version[u'minor'] = int(match.group(2))
|
||||
local_version[u'release'] = int(match.group(3))
|
||||
if len(match.groups()) > 3 and match.group(4):
|
||||
local_version[u'revision'] = int(match.group(4))
|
||||
else:
|
||||
return
|
||||
if remote_version[u'major'] > local_version[u'major'] or \
|
||||
remote_version[u'minor'] > local_version[u'minor'] or \
|
||||
remote_version[u'release'] > local_version[u'release']:
|
||||
if LooseVersion(str(version)) > LooseVersion(str(app_version[u'full'])):
|
||||
Receiver.send_message(u'openlp_version_check', u'%s' % version)
|
||||
elif remote_version.get(u'revision') and \
|
||||
local_version.get(u'revision') and \
|
||||
remote_version[u'revision'] > local_version[u'revision']:
|
||||
Receiver.send_message(u'openlp_version_check', u'%s' % version)
|
||||
|
||||
|
||||
class DelayStartThread(QtCore.QThread):
|
||||
"""
|
||||
A special Qt thread class to build things after OpenLP has started
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
QtCore.QThread.__init__(self, parent)
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Run the thread.
|
||||
"""
|
||||
Receiver.send_message(u'openlp_phonon_creation')
|
||||
|
||||
|
||||
class AppLocation(object):
|
||||
@ -181,6 +141,7 @@ class AppLocation(object):
|
||||
check_directory_exists(path)
|
||||
return path
|
||||
|
||||
|
||||
def _get_os_dir_path(dir_type):
|
||||
"""
|
||||
Return a path based on which OS and environment we are running in.
|
||||
@ -220,6 +181,7 @@ def _get_os_dir_path(dir_type):
|
||||
u'.openlp', u'data')
|
||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'.openlp')
|
||||
|
||||
|
||||
def _get_frozen_path(frozen_option, non_frozen_option):
|
||||
"""
|
||||
Return a path based on the system status.
|
||||
@ -228,6 +190,7 @@ def _get_frozen_path(frozen_option, non_frozen_option):
|
||||
return frozen_option
|
||||
return non_frozen_option
|
||||
|
||||
|
||||
def get_application_version():
|
||||
"""
|
||||
Returns the application version of the running instance of OpenLP::
|
||||
@ -267,7 +230,7 @@ def get_application_version():
|
||||
if code != 0:
|
||||
raise Exception(u'Error running bzr tags')
|
||||
lines = output.splitlines()
|
||||
if len(lines) == 0:
|
||||
if not lines:
|
||||
tag = u'0.0.0'
|
||||
revision = u'0'
|
||||
else:
|
||||
@ -307,6 +270,7 @@ def get_application_version():
|
||||
log.info(u'Openlp version %s' % APPLICATION_VERSION[u'version'])
|
||||
return APPLICATION_VERSION
|
||||
|
||||
|
||||
def check_latest_version(current_version):
|
||||
"""
|
||||
Check the latest version of OpenLP against the version file on the OpenLP
|
||||
@ -340,6 +304,7 @@ def check_latest_version(current_version):
|
||||
version_string = remote_version
|
||||
return version_string
|
||||
|
||||
|
||||
def add_actions(target, actions):
|
||||
"""
|
||||
Adds multiple actions to a menu or toolbar in one command.
|
||||
@ -357,6 +322,7 @@ def add_actions(target, actions):
|
||||
else:
|
||||
target.addAction(action)
|
||||
|
||||
|
||||
def get_filesystem_encoding():
|
||||
"""
|
||||
Returns the name of the encoding used to convert Unicode filenames into
|
||||
@ -367,6 +333,7 @@ def get_filesystem_encoding():
|
||||
encoding = sys.getdefaultencoding()
|
||||
return encoding
|
||||
|
||||
|
||||
def get_images_filter():
|
||||
"""
|
||||
Returns a filter string for a file dialog containing all the supported
|
||||
@ -383,6 +350,7 @@ def get_images_filter():
|
||||
visible_formats, actual_formats)
|
||||
return IMAGES_FILTER
|
||||
|
||||
|
||||
def split_filename(path):
|
||||
"""
|
||||
Return a list of the parts in a given path.
|
||||
@ -393,6 +361,7 @@ def split_filename(path):
|
||||
else:
|
||||
return os.path.split(path)
|
||||
|
||||
|
||||
def clean_filename(filename):
|
||||
"""
|
||||
Removes invalid characters from the given ``filename``.
|
||||
@ -404,6 +373,7 @@ def clean_filename(filename):
|
||||
filename = unicode(filename, u'utf-8')
|
||||
return INVALID_FILE_CHARS.sub(u'_', CONTROL_CHARS.sub(u'', filename))
|
||||
|
||||
|
||||
def delete_file(file_path_name):
|
||||
"""
|
||||
Deletes a file from the system.
|
||||
@ -421,6 +391,7 @@ def delete_file(file_path_name):
|
||||
log.exception("Unable to delete file %s" % file_path_name)
|
||||
return False
|
||||
|
||||
|
||||
def get_web_page(url, header=None, update_openlp=False):
|
||||
"""
|
||||
Attempts to download the webpage at url and returns that page or None.
|
||||
@ -457,6 +428,7 @@ def get_web_page(url, header=None, update_openlp=False):
|
||||
log.debug(page)
|
||||
return page
|
||||
|
||||
|
||||
def get_uno_command():
|
||||
"""
|
||||
Returns the UNO command to launch an openoffice.org instance.
|
||||
@ -469,6 +441,7 @@ def get_uno_command():
|
||||
CONNECTION = u'"-accept=socket,host=localhost,port=2002;urp;"'
|
||||
return u'%s %s %s' % (COMMAND, OPTIONS, CONNECTION)
|
||||
|
||||
|
||||
def get_uno_instance(resolver):
|
||||
"""
|
||||
Returns a running openoffice.org instance.
|
||||
|
@ -90,7 +90,7 @@ class CategoryActionList(object):
|
||||
|
||||
def append(self, name):
|
||||
weight = 0
|
||||
if len(self.actions) > 0:
|
||||
if self.actions:
|
||||
weight = self.actions[-1][0] + 1
|
||||
self.add(name, weight)
|
||||
|
||||
@ -156,7 +156,7 @@ class CategoryList(object):
|
||||
|
||||
def append(self, name, actions=None):
|
||||
weight = 0
|
||||
if len(self.categories) > 0:
|
||||
if self.categories:
|
||||
weight = self.categories[-1].weight + 1
|
||||
if actions:
|
||||
self.add(name, weight, actions)
|
||||
|
@ -117,8 +117,8 @@ class AlertsPlugin(Plugin):
|
||||
Plugin.__init__(self, u'alerts', plugin_helpers,
|
||||
settings_tab_class=AlertsTab)
|
||||
self.weight = -3
|
||||
self.icon_path = u':/plugins/plugin_alerts.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.iconPath = u':/plugins/plugin_alerts.png'
|
||||
self.icon = build_icon(self.iconPath)
|
||||
self.alertsmanager = AlertsManager(self)
|
||||
self.manager = Manager(u'alerts', init_schema)
|
||||
self.alertForm = AlertForm(self)
|
||||
@ -197,10 +197,10 @@ class AlertsPlugin(Plugin):
|
||||
"""
|
||||
Add CSS to the main display.
|
||||
"""
|
||||
align = VerticalType.Names[self.settings_tab.location]
|
||||
return CSS % (align, self.settings_tab.font_face,
|
||||
self.settings_tab.font_size, self.settings_tab.font_color,
|
||||
self.settings_tab.bg_color)
|
||||
align = VerticalType.Names[self.settingsTab.location]
|
||||
return CSS % (align, self.settingsTab.font_face,
|
||||
self.settingsTab.font_size, self.settingsTab.font_color,
|
||||
self.settingsTab.bg_color)
|
||||
|
||||
def getDisplayHtml(self):
|
||||
"""
|
||||
@ -215,7 +215,7 @@ class AlertsPlugin(Plugin):
|
||||
``frame``
|
||||
The Web frame holding the page.
|
||||
"""
|
||||
align = VerticalType.Names[self.settings_tab.location]
|
||||
align = VerticalType.Names[self.settingsTab.location]
|
||||
frame.evaluateJavaScript(u'update_css("%s", "%s", "%s", "%s", "%s")' %
|
||||
(align, self.settings_tab.font_face, self.settings_tab.font_size,
|
||||
self.settings_tab.font_color, self.settings_tab.bg_color))
|
||||
(align, self.settingsTab.font_face, self.settingsTab.font_size,
|
||||
self.settingsTab.font_color, self.settingsTab.bg_color))
|
||||
|
@ -43,7 +43,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
self.manager = plugin.manager
|
||||
self.plugin = plugin
|
||||
self.item_id = None
|
||||
QtGui.QDialog.__init__(self, plugin.formparent)
|
||||
QtGui.QDialog.__init__(self, plugin.formParent)
|
||||
self.setupUi(self)
|
||||
QtCore.QObject.connect(self.displayButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onDisplayClicked)
|
||||
@ -101,7 +101,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
self.alertTextEdit.setText(u'')
|
||||
|
||||
def onNewClick(self):
|
||||
if len(self.alertTextEdit.text()) == 0:
|
||||
if not self.alertTextEdit.text():
|
||||
QtGui.QMessageBox.information(self,
|
||||
translate('AlertsPlugin.AlertForm', 'New Alert'),
|
||||
translate('AlertsPlugin.AlertForm', 'You haven\'t specified '
|
||||
|
@ -84,7 +84,7 @@ class AlertsManager(QtCore.QObject):
|
||||
if not self.alertList:
|
||||
return
|
||||
text = self.alertList.pop(0)
|
||||
alertTab = self.parent().settings_tab
|
||||
alertTab = self.parent().settingsTab
|
||||
self.parent().liveController.display.alert(text, alertTab.location)
|
||||
# Check to see if we have a timer running.
|
||||
if self.timer_id == 0:
|
||||
@ -100,7 +100,7 @@ class AlertsManager(QtCore.QObject):
|
||||
"""
|
||||
log.debug(u'timer event')
|
||||
if event.timerId() == self.timer_id:
|
||||
alertTab = self.parent().settings_tab
|
||||
alertTab = self.parent().settingsTab
|
||||
self.parent().liveController.display.alert(u'', alertTab.location)
|
||||
self.killTimer(self.timer_id)
|
||||
self.timer_id = 0
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtGui
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||
from openlp.core.lib.ui import create_action, UiStrings
|
||||
@ -44,8 +44,8 @@ class BiblePlugin(Plugin):
|
||||
Plugin.__init__(self, u'bibles', plugin_helpers,
|
||||
BibleMediaItem, BiblesTab)
|
||||
self.weight = -9
|
||||
self.icon_path = u':/plugins/plugin_bibles.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.iconPath = u':/plugins/plugin_bibles.png'
|
||||
self.icon = build_icon(self.iconPath)
|
||||
self.manager = None
|
||||
|
||||
def initialise(self):
|
||||
@ -62,7 +62,7 @@ class BiblePlugin(Plugin):
|
||||
# unicode(UiStrings().Export))
|
||||
# Set to invisible until we can export bibles
|
||||
self.exportBibleItem.setVisible(False)
|
||||
if len(self.manager.old_bible_databases):
|
||||
if self.manager.old_bible_databases:
|
||||
self.toolsUpgradeItem.setVisible(True)
|
||||
|
||||
def finalise(self):
|
||||
@ -81,16 +81,23 @@ class BiblePlugin(Plugin):
|
||||
|
||||
def appStartup(self):
|
||||
"""
|
||||
Perform tasks on application starup
|
||||
Perform tasks on application startup
|
||||
"""
|
||||
if len(self.manager.old_bible_databases):
|
||||
if QtGui.QMessageBox.information(self.formparent,
|
||||
if self.manager.old_bible_databases:
|
||||
if QtGui.QMessageBox.information(self.formParent,
|
||||
translate('OpenLP', 'Information'), translate('OpenLP',
|
||||
'Bible format has changed.\nYou have to upgrade your '
|
||||
'existing Bibles.\nShould OpenLP upgrade now?'),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
|
||||
QtGui.QMessageBox.No)) == QtGui.QMessageBox.Yes:
|
||||
self.onToolsUpgradeItemTriggered()
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settingsSection)
|
||||
if settings.contains(u'bookname language'):
|
||||
settings.setValue(u'book name language', settings.value(
|
||||
u'bookname language', QtCore.QVariant(0)).toInt()[0])
|
||||
settings.remove(u'bookname language')
|
||||
settings.endGroup()
|
||||
|
||||
def addImportMenuItem(self, import_menu):
|
||||
self.importBibleItem = create_action(import_menu, u'importBibleItem',
|
||||
@ -126,7 +133,7 @@ class BiblePlugin(Plugin):
|
||||
Upgrade older bible databases.
|
||||
"""
|
||||
if not hasattr(self, u'upgrade_wizard'):
|
||||
self.upgrade_wizard = BibleUpgradeForm(self.formparent,
|
||||
self.upgrade_wizard = BibleUpgradeForm(self.formParent,
|
||||
self.manager, self)
|
||||
# If the import was not cancelled then reload.
|
||||
if self.upgrade_wizard.exec_():
|
||||
@ -145,11 +152,10 @@ class BiblePlugin(Plugin):
|
||||
def usesTheme(self, theme):
|
||||
"""
|
||||
Called to find out if the bible plugin is currently using a theme.
|
||||
Returns True if the theme is being used, otherwise returns False.
|
||||
Returns ``True`` if the theme is being used, otherwise returns
|
||||
``False``.
|
||||
"""
|
||||
if unicode(self.settings_tab.bible_theme) == theme:
|
||||
return True
|
||||
return False
|
||||
return unicode(self.settingsTab.bible_theme) == theme
|
||||
|
||||
def renameTheme(self, oldTheme, newTheme):
|
||||
"""
|
||||
@ -163,8 +169,8 @@ class BiblePlugin(Plugin):
|
||||
``newTheme``
|
||||
The new name the plugin should now use.
|
||||
"""
|
||||
self.settings_tab.bible_theme = newTheme
|
||||
self.settings_tab.save()
|
||||
self.settingsTab.bible_theme = newTheme
|
||||
self.settingsTab.save()
|
||||
|
||||
def setPluginTextStrings(self):
|
||||
"""
|
||||
|
@ -371,7 +371,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
"""
|
||||
Perform the actual upgrade.
|
||||
"""
|
||||
self.include_webbible = False
|
||||
self.includeWebBible = False
|
||||
proxy_server = None
|
||||
if not self.files:
|
||||
self.progressLabel.setText(
|
||||
@ -383,14 +383,14 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
for number, file in enumerate(self.files):
|
||||
if self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
max_bibles += 1
|
||||
oldBible = None
|
||||
old_bible = None
|
||||
for number, filename in enumerate(self.files):
|
||||
# Close the previous bible's connection.
|
||||
if oldBible is not None:
|
||||
oldBible.close_connection()
|
||||
if old_bible is not None:
|
||||
old_bible.close_connection()
|
||||
# Set to None to make obvious that we have already closed the
|
||||
# database.
|
||||
oldBible = None
|
||||
old_bible = None
|
||||
if self.stop_import_flag:
|
||||
self.success[number] = False
|
||||
break
|
||||
@ -398,7 +398,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.success[number] = False
|
||||
continue
|
||||
self.progressBar.reset()
|
||||
oldBible = OldBibleDB(self.mediaItem, path=self.temp_dir,
|
||||
old_bible = OldBibleDB(self.mediaItem, path=self.temp_dir,
|
||||
file=filename[0])
|
||||
name = filename[1]
|
||||
self.progressLabel.setText(unicode(translate(
|
||||
@ -408,33 +408,38 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.newbibles[number] = BibleDB(self.mediaItem, path=self.path,
|
||||
name=name, file=filename[0])
|
||||
self.newbibles[number].register(self.plugin.upgrade_wizard)
|
||||
metadata = oldBible.get_metadata()
|
||||
webbible = False
|
||||
metadata = old_bible.get_metadata()
|
||||
web_bible = False
|
||||
meta_data = {}
|
||||
for meta in metadata:
|
||||
# Upgrade the names of the metadata keys
|
||||
if meta[u'key'] == u'Version':
|
||||
meta[u'key'] = u'name'
|
||||
if meta[u'key'] == u'Bookname language':
|
||||
meta[u'key'] = 'book_name_language'
|
||||
meta[u'key'] = meta[u'key'].lower().replace(' ', '_')
|
||||
# Copy the metadata
|
||||
meta_data[meta[u'key']] = meta[u'value']
|
||||
if not meta[u'key'] == u'Version' and not meta[u'key'] == \
|
||||
u'dbversion':
|
||||
if meta[u'key'] != u'name' and meta[u'key'] != u'dbversion':
|
||||
self.newbibles[number].save_meta(meta[u'key'],
|
||||
meta[u'value'])
|
||||
if meta[u'key'] == u'download source':
|
||||
webbible = True
|
||||
self.include_webbible = True
|
||||
if meta.has_key(u'proxy server'):
|
||||
proxy_server = meta[u'proxy server']
|
||||
if webbible:
|
||||
if meta_data[u'download source'].lower() == u'crosswalk':
|
||||
if meta[u'key'] == u'download_source':
|
||||
web_bible = True
|
||||
self.includeWebBible = True
|
||||
proxy_server = meta.get(u'proxy_server')
|
||||
if web_bible:
|
||||
if meta_data[u'download_source'].lower() == u'crosswalk':
|
||||
handler = CWExtract(proxy_server)
|
||||
elif meta_data[u'download source'].lower() == u'biblegateway':
|
||||
elif meta_data[u'download_source'].lower() == u'biblegateway':
|
||||
handler = BGExtract(proxy_server)
|
||||
elif meta_data[u'download source'].lower() == u'bibleserver':
|
||||
elif meta_data[u'download_source'].lower() == u'bibleserver':
|
||||
handler = BSExtract(proxy_server)
|
||||
books = handler.get_books_from_http(meta_data[u'download name'])
|
||||
books = handler.get_books_from_http(meta_data[u'download_name'])
|
||||
if not books:
|
||||
log.error(u'Upgrading books from %s - download '\
|
||||
u'name: "%s" failed' % (
|
||||
meta_data[u'download source'],
|
||||
meta_data[u'download name']))
|
||||
meta_data[u'download_source'],
|
||||
meta_data[u'download_name']))
|
||||
self.newbibles[number].session.close()
|
||||
del self.newbibles[number]
|
||||
critical_error_message_box(
|
||||
@ -451,8 +456,8 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.success[number] = False
|
||||
continue
|
||||
bible = BiblesResourcesDB.get_webbible(
|
||||
meta_data[u'download name'],
|
||||
meta_data[u'download source'].lower())
|
||||
meta_data[u'download_name'],
|
||||
meta_data[u'download_source'].lower())
|
||||
if bible and bible[u'language_id']:
|
||||
language_id = bible[u'language_id']
|
||||
self.newbibles[number].save_meta(u'language_id',
|
||||
@ -485,8 +490,8 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
if not book_ref_id:
|
||||
log.warn(u'Upgrading books from %s - download '\
|
||||
u'name: "%s" aborted by user' % (
|
||||
meta_data[u'download source'],
|
||||
meta_data[u'download name']))
|
||||
meta_data[u'download_source'],
|
||||
meta_data[u'download_name']))
|
||||
self.newbibles[number].session.close()
|
||||
del self.newbibles[number]
|
||||
self.success[number] = False
|
||||
@ -495,9 +500,9 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
db_book = self.newbibles[number].create_book(book,
|
||||
book_ref_id, book_details[u'testament_id'])
|
||||
# Try to import already downloaded verses.
|
||||
oldbook = oldBible.get_book(book)
|
||||
oldbook = old_bible.get_book(book)
|
||||
if oldbook:
|
||||
verses = oldBible.get_verses(oldbook[u'id'])
|
||||
verses = old_bible.get_verses(oldbook[u'id'])
|
||||
if not verses:
|
||||
log.warn(u'No verses found to import for book '
|
||||
u'"%s"', book)
|
||||
@ -527,7 +532,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
self.success[number] = False
|
||||
continue
|
||||
books = oldBible.get_books()
|
||||
books = old_bible.get_books()
|
||||
self.progressBar.setMaximum(len(books))
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
@ -551,7 +556,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.newbibles[number].create_book(book[u'name'],
|
||||
book_ref_id, book_details[u'testament_id'])
|
||||
verses = oldBible.get_verses(book[u'id'])
|
||||
verses = old_bible.get_verses(book[u'id'])
|
||||
if not verses:
|
||||
log.warn(u'No verses found to import for book '
|
||||
u'"%s"', book[u'name'])
|
||||
@ -566,7 +571,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
int(verse[u'verse']), unicode(verse[u'text']))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.newbibles[number].session.commit()
|
||||
if self.success.has_key(number) and not self.success[number]:
|
||||
if not self.success.get(number, True):
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
@ -574,17 +579,17 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
else:
|
||||
self.success[number] = True
|
||||
self.newbibles[number].save_meta(u'Version', name)
|
||||
self.newbibles[number].save_meta(u'name', name)
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\n'
|
||||
'Complete')) %
|
||||
(number + 1, max_bibles, name))
|
||||
if self.newbibles.has_key(number):
|
||||
if number in self.newbibles:
|
||||
self.newbibles[number].session.close()
|
||||
# Close the last bible's connection if possible.
|
||||
if oldBible is not None:
|
||||
oldBible.close_connection()
|
||||
if old_bible is not None:
|
||||
old_bible.close_connection()
|
||||
|
||||
def postWizard(self):
|
||||
"""
|
||||
@ -593,7 +598,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
successful_import = 0
|
||||
failed_import = 0
|
||||
for number, filename in enumerate(self.files):
|
||||
if self.success.has_key(number) and self.success[number]:
|
||||
if self.success.get(number):
|
||||
successful_import += 1
|
||||
elif self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
failed_import += 1
|
||||
@ -608,7 +613,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
else:
|
||||
failed_import_text = u''
|
||||
if successful_import > 0:
|
||||
if self.include_webbible:
|
||||
if self.includeWebBible:
|
||||
self.progressLabel.setText(unicode(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading '
|
||||
'Bible(s): %s successful%s\nPlease note that verses from '
|
||||
|
@ -90,7 +90,7 @@ class Ui_BookNameDialog(object):
|
||||
'Select Book Name'))
|
||||
self.infoLabel.setText(translate('BiblesPlugin.BookNameDialog',
|
||||
'The following book name cannot be matched up internally. Please '
|
||||
'select the corresponding English name from the list.'))
|
||||
'select the corresponding name from the list.'))
|
||||
self.currentLabel.setText(translate('BiblesPlugin.BookNameDialog',
|
||||
'Current name:'))
|
||||
self.correspondingLabel.setText(translate(
|
||||
|
@ -28,6 +28,7 @@
|
||||
Module implementing BookNameForm.
|
||||
"""
|
||||
import logging
|
||||
import re
|
||||
|
||||
from PyQt4.QtGui import QDialog
|
||||
from PyQt4 import QtCore
|
||||
@ -36,6 +37,7 @@ from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.bibles.forms.booknamedialog import \
|
||||
Ui_BookNameDialog
|
||||
from openlp.plugins.bibles.lib import BibleStrings
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -54,6 +56,8 @@ class BookNameForm(QDialog, Ui_BookNameDialog):
|
||||
QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
self.customSignals()
|
||||
self.book_names = BibleStrings().BookNames
|
||||
self.book_id = False
|
||||
|
||||
def customSignals(self):
|
||||
"""
|
||||
@ -97,7 +101,8 @@ class BookNameForm(QDialog, Ui_BookNameDialog):
|
||||
and item[u'testament_id'] == 3:
|
||||
addBook = False
|
||||
if addBook:
|
||||
self.correspondingComboBox.addItem(item[u'name'])
|
||||
self.correspondingComboBox.addItem(
|
||||
self.book_names[item[u'abbreviation']])
|
||||
|
||||
def exec_(self, name, books, maxbooks):
|
||||
self.books = books
|
||||
@ -120,4 +125,13 @@ class BookNameForm(QDialog, Ui_BookNameDialog):
|
||||
self.correspondingComboBox.setFocus()
|
||||
return False
|
||||
else:
|
||||
cor_book = unicode(self.correspondingComboBox.currentText())
|
||||
for character in u'\\.^$*+?{}[]()':
|
||||
cor_book = cor_book.replace(character, u'\\' + character)
|
||||
books = filter(lambda key:
|
||||
re.match(cor_book, unicode(self.book_names[key]), re.UNICODE),
|
||||
self.book_names.keys())
|
||||
books = filter(None, map(BiblesResourcesDB.get_book, books))
|
||||
if books:
|
||||
self.book_id = books[0][u'id']
|
||||
return QDialog.accept(self)
|
||||
|
@ -141,7 +141,7 @@ class Ui_EditBibleDialog(object):
|
||||
QtCore.QMetaObject.connectSlotsByName(editBibleDialog)
|
||||
|
||||
def retranslateUi(self, editBibleDialog):
|
||||
self.booknames = BibleStrings().Booknames
|
||||
self.book_names = BibleStrings().BookNames
|
||||
editBibleDialog.setWindowTitle(
|
||||
translate('BiblesPlugin.EditBibleForm', 'Bible Editor'))
|
||||
# Meta tab
|
||||
@ -178,4 +178,4 @@ class Ui_EditBibleDialog(object):
|
||||
translate('SongsPlugin.EditBibleForm', 'Custom Book Names'))
|
||||
for book in BiblesResourcesDB.get_books():
|
||||
self.bookNameLabel[book[u'abbreviation']].setText(
|
||||
u'%s:' % unicode(self.booknames[book[u'abbreviation']]))
|
||||
u'%s:' % unicode(self.book_names[book[u'abbreviation']]))
|
||||
|
@ -50,7 +50,7 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.mediaitem = mediaitem
|
||||
self.booknames = BibleStrings().Booknames
|
||||
self.book_names = BibleStrings().BookNames
|
||||
self.setupUi(self)
|
||||
self.manager = manager
|
||||
|
||||
@ -64,19 +64,19 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
log.debug(u'Load Bible')
|
||||
self.bible = bible
|
||||
self.versionNameEdit.setText(
|
||||
self.manager.get_meta_data(self.bible, u'Version').value)
|
||||
self.manager.get_meta_data(self.bible, u'name').value)
|
||||
self.copyrightEdit.setText(
|
||||
self.manager.get_meta_data(self.bible, u'Copyright').value)
|
||||
self.manager.get_meta_data(self.bible, u'copyright').value)
|
||||
self.permissionsEdit.setText(
|
||||
self.manager.get_meta_data(self.bible, u'Permissions').value)
|
||||
bookname_language = self.manager.get_meta_data(self.bible,
|
||||
u'Bookname language')
|
||||
if bookname_language and bookname_language.value != u'None':
|
||||
self.manager.get_meta_data(self.bible, u'permissions').value)
|
||||
book_name_language = self.manager.get_meta_data(self.bible,
|
||||
u'book_name_language')
|
||||
if book_name_language and book_name_language.value != u'None':
|
||||
self.languageSelectionComboBox.setCurrentIndex(
|
||||
int(bookname_language.value) + 1)
|
||||
int(book_name_language.value) + 1)
|
||||
self.books = {}
|
||||
self.webbible = self.manager.get_meta_data(self.bible,
|
||||
u'download source')
|
||||
u'download_source')
|
||||
if self.webbible:
|
||||
self.bookNameNotice.setText(translate('BiblesPlugin.EditBibleForm',
|
||||
'This is a Web Download Bible.\nIt is not possible to '
|
||||
@ -119,9 +119,9 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
version = unicode(self.versionNameEdit.text())
|
||||
copyright = unicode(self.copyrightEdit.text())
|
||||
permissions = unicode(self.permissionsEdit.text())
|
||||
bookname_language = self.languageSelectionComboBox.currentIndex() - 1
|
||||
if bookname_language == -1:
|
||||
bookname_language = None
|
||||
book_name_language = self.languageSelectionComboBox.currentIndex() - 1
|
||||
if book_name_language == -1:
|
||||
book_name_language = None
|
||||
if not self.validateMeta(version, copyright):
|
||||
return
|
||||
if not self.webbible:
|
||||
@ -135,7 +135,7 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.manager.save_meta_data(self.bible, version, copyright, permissions,
|
||||
bookname_language)
|
||||
book_name_language)
|
||||
if not self.webbible:
|
||||
for abbr, book in self.books.iteritems():
|
||||
if book:
|
||||
@ -146,11 +146,11 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
QtGui.QDialog.accept(self)
|
||||
|
||||
def validateMeta(self, version, copyright):
|
||||
def validateMeta(self, name, copyright):
|
||||
"""
|
||||
Validate the Meta before saving.
|
||||
"""
|
||||
if not version:
|
||||
if not name:
|
||||
self.versionNameEdit.setFocus()
|
||||
critical_error_message_box(UiStrings().EmptyField,
|
||||
translate('BiblesPlugin.BibleEditForm',
|
||||
@ -163,9 +163,9 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
'You need to set a copyright for your Bible. '
|
||||
'Bibles in the Public Domain need to be marked as such.'))
|
||||
return False
|
||||
elif self.manager.exists(version) and \
|
||||
self.manager.get_meta_data(self.bible, u'Version').value != \
|
||||
version:
|
||||
elif self.manager.exists(name) and \
|
||||
self.manager.get_meta_data(self.bible, u'name').value != \
|
||||
name:
|
||||
self.versionNameEdit.setFocus()
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.BibleEditForm', 'Bible Exists'),
|
||||
@ -175,37 +175,37 @@ class EditBibleForm(QtGui.QDialog, Ui_EditBibleDialog):
|
||||
return False
|
||||
return True
|
||||
|
||||
def validateBook(self, new_bookname, abbreviation):
|
||||
def validateBook(self, new_book_name, abbreviation):
|
||||
"""
|
||||
Validate a book.
|
||||
"""
|
||||
book_regex = re.compile(u'[\d]*[^\d]+$')
|
||||
if not new_bookname:
|
||||
if not new_book_name:
|
||||
self.bookNameEdit[abbreviation].setFocus()
|
||||
critical_error_message_box(UiStrings().EmptyField,
|
||||
unicode(translate('BiblesPlugin.BibleEditForm',
|
||||
'You need to specify a book name for "%s".')) %
|
||||
self.booknames[abbreviation])
|
||||
self.book_names[abbreviation])
|
||||
return False
|
||||
elif not book_regex.match(new_bookname):
|
||||
elif not book_regex.match(new_book_name):
|
||||
self.bookNameEdit[abbreviation].setFocus()
|
||||
critical_error_message_box(UiStrings().EmptyField,
|
||||
unicode(translate('BiblesPlugin.BibleEditForm',
|
||||
'The book name "%s" is not correct.\nNumbers can only be used '
|
||||
'at the beginning and must\nbe followed by one or more '
|
||||
'non-numeric characters.')) % new_bookname)
|
||||
'non-numeric characters.')) % new_book_name)
|
||||
return False
|
||||
for abbr, book in self.books.iteritems():
|
||||
if book:
|
||||
if abbr == abbreviation:
|
||||
continue
|
||||
if unicode(self.bookNameEdit[abbr].text()) == new_bookname:
|
||||
if unicode(self.bookNameEdit[abbr].text()) == new_book_name:
|
||||
self.bookNameEdit[abbreviation].setFocus()
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.BibleEditForm',
|
||||
'Duplicate Book Name'),
|
||||
unicode(translate('BiblesPlugin.BibleEditForm',
|
||||
'The Book Name "%s" has been entered more than once.'))
|
||||
% new_bookname)
|
||||
% new_book_name)
|
||||
return False
|
||||
return True
|
||||
|
@ -88,7 +88,7 @@ class BibleStrings(object):
|
||||
"""
|
||||
These strings should need a good reason to be retranslated elsewhere.
|
||||
"""
|
||||
self.Booknames = {
|
||||
self.BookNames = {
|
||||
u'Gen': translate('BiblesPlugin', 'Genesis'),
|
||||
u'Exod': translate('BiblesPlugin', 'Exodus'),
|
||||
u'Lev': translate('BiblesPlugin', 'Leviticus'),
|
||||
@ -236,7 +236,7 @@ def get_reference_separator(separator_type):
|
||||
``separator_type``
|
||||
The role and format of the separator.
|
||||
"""
|
||||
if len(REFERENCE_SEPARATORS) == 0:
|
||||
if not REFERENCE_SEPARATORS:
|
||||
update_reference_separators()
|
||||
return REFERENCE_SEPARATORS[separator_type]
|
||||
|
||||
@ -247,7 +247,7 @@ def get_reference_match(match_type):
|
||||
``match_type``
|
||||
The type of match is ``range_separator``, ``range`` or ``full``.
|
||||
"""
|
||||
if len(REFERENCE_MATCHES) == 0:
|
||||
if not REFERENCE_MATCHES:
|
||||
update_reference_separators()
|
||||
return REFERENCE_MATCHES[match_type]
|
||||
|
||||
@ -355,7 +355,7 @@ 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:
|
||||
booknames = BibleStrings().Booknames
|
||||
book_names = BibleStrings().BookNames
|
||||
# escape reserved characters
|
||||
book_escaped = book
|
||||
for character in u'\\.^$*+?{}[]()':
|
||||
@ -369,7 +369,7 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False):
|
||||
book_ref_id = db_book.book_reference_id
|
||||
elif language_selection == LanguageSelection.Application:
|
||||
books = filter(lambda key:
|
||||
regex_book.match(unicode(booknames[key])), booknames.keys())
|
||||
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']):
|
||||
|
@ -483,7 +483,7 @@ class BiblesTab(SettingsTab):
|
||||
self.getGreyTextPalette(False))
|
||||
self.endSeparatorCheckBox.setChecked(True)
|
||||
self.language_selection = settings.value(
|
||||
u'bookname language', QtCore.QVariant(0)).toInt()[0]
|
||||
u'book name language', QtCore.QVariant(0)).toInt()[0]
|
||||
self.languageSelectionComboBox.setCurrentIndex(self.language_selection)
|
||||
settings.endGroup()
|
||||
|
||||
@ -496,7 +496,7 @@ class BiblesTab(SettingsTab):
|
||||
QtCore.QVariant(self.display_style))
|
||||
settings.setValue(u'verse layout style',
|
||||
QtCore.QVariant(self.layout_style))
|
||||
settings.setValue(u'bookname language',
|
||||
settings.setValue(u'book name language',
|
||||
QtCore.QVariant(self.language_selection))
|
||||
settings.setValue(u'second bibles', QtCore.QVariant(self.second_bibles))
|
||||
settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme))
|
||||
|
@ -39,6 +39,7 @@ from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.utils import AppLocation, clean_filename
|
||||
import upgrade
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -147,7 +148,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
self.file = clean_filename(self.name) + u'.sqlite'
|
||||
if u'file' in kwargs:
|
||||
self.file = kwargs[u'file']
|
||||
Manager.__init__(self, u'bibles', init_schema, self.file)
|
||||
Manager.__init__(self, u'bibles', init_schema, self.file, upgrade)
|
||||
if u'file' in kwargs:
|
||||
self.get_name()
|
||||
if u'path' in kwargs:
|
||||
@ -167,7 +168,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
"""
|
||||
Returns the version name of the Bible.
|
||||
"""
|
||||
version_name = self.get_object(BibleMeta, u'Version')
|
||||
version_name = self.get_object(BibleMeta, u'name')
|
||||
self.name = version_name.value if version_name else None
|
||||
return self.name
|
||||
|
||||
@ -182,7 +183,6 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
The actual Qt wizard form.
|
||||
"""
|
||||
self.wizard = wizard
|
||||
self.save_meta(u'dbversion', u'2')
|
||||
return self.name
|
||||
|
||||
def create_book(self, name, bk_ref_id, testament=1):
|
||||
@ -332,6 +332,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
def get_book_ref_id_by_name(self, book, maxbooks, language_id=None):
|
||||
log.debug(u'BibleDB.get_book_ref_id_by_name:("%s", "%s")', book,
|
||||
language_id)
|
||||
book_id = None
|
||||
if BiblesResourcesDB.get_book(book, True):
|
||||
book_temp = BiblesResourcesDB.get_book(book, True)
|
||||
book_id = book_temp[u'id']
|
||||
@ -341,26 +342,13 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
book_id = AlternativeBookNamesDB.get_book_reference_id(book)
|
||||
else:
|
||||
from openlp.plugins.bibles.forms import BookNameForm
|
||||
book_ref = None
|
||||
book_name = BookNameForm(self.wizard)
|
||||
if book_name.exec_(book, self.get_books(), maxbooks):
|
||||
book_ref = unicode(
|
||||
book_name.correspondingComboBox.currentText())
|
||||
if not book_ref:
|
||||
return None
|
||||
else:
|
||||
book_temp = BiblesResourcesDB.get_book(book_ref)
|
||||
if book_temp:
|
||||
book_id = book_temp[u'id']
|
||||
else:
|
||||
return None
|
||||
book_id = book_name.book_id
|
||||
if book_id:
|
||||
AlternativeBookNamesDB.create_alternative_book_name(
|
||||
book, book_id, language_id)
|
||||
if book_id:
|
||||
return book_id
|
||||
else:
|
||||
return None
|
||||
return book_id
|
||||
|
||||
def get_verses(self, reference_list, show_error=True):
|
||||
"""
|
||||
@ -495,7 +483,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
prior to 1.9.6.
|
||||
"""
|
||||
try:
|
||||
columns = self.session.query(Book).all()
|
||||
self.session.query(Book).all()
|
||||
except:
|
||||
return True
|
||||
return False
|
||||
@ -562,16 +550,13 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||
log.debug(u'BiblesResourcesDB.get_books()')
|
||||
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
|
||||
u'abbreviation, chapters FROM book_reference ORDER BY id')
|
||||
return [
|
||||
{
|
||||
u'id': book[0],
|
||||
u'testament_id': book[1],
|
||||
u'name': unicode(book[2]),
|
||||
u'abbreviation': unicode(book[3]),
|
||||
u'chapters': book[4]
|
||||
}
|
||||
for book in books
|
||||
]
|
||||
return [{
|
||||
u'id': book[0],
|
||||
u'testament_id': book[1],
|
||||
u'name': unicode(book[2]),
|
||||
u'abbreviation': unicode(book[3]),
|
||||
u'chapters': book[4]
|
||||
} for book in books]
|
||||
|
||||
@staticmethod
|
||||
def get_book(name, lower=False):
|
||||
@ -613,7 +598,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||
Return the books which include string.
|
||||
|
||||
``string``
|
||||
The string to search for in the booknames or abbreviations.
|
||||
The string to search for in the book names or abbreviations.
|
||||
"""
|
||||
log.debug(u'BiblesResourcesDB.get_book_like("%s")', string)
|
||||
if not isinstance(string, unicode):
|
||||
@ -623,16 +608,13 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||
u'LOWER(name) LIKE ? OR LOWER(abbreviation) LIKE ?',
|
||||
(u'%' + string.lower() + u'%', u'%' + string.lower() + u'%'))
|
||||
if books:
|
||||
return [
|
||||
{
|
||||
return [{
|
||||
u'id': book[0],
|
||||
u'testament_id': book[1],
|
||||
u'name': unicode(book[2]),
|
||||
u'abbreviation': unicode(book[3]),
|
||||
u'chapters': book[4]
|
||||
}
|
||||
for book in books
|
||||
]
|
||||
} for book in books]
|
||||
else:
|
||||
return None
|
||||
|
||||
@ -759,16 +741,13 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||
u'language_id, download_source_id FROM webbibles WHERE '
|
||||
u'download_source_id = ?', (source[u'id'],))
|
||||
if bibles:
|
||||
return [
|
||||
{
|
||||
return [{
|
||||
u'id': bible[0],
|
||||
u'name': bible[1],
|
||||
u'abbreviation': bible[2],
|
||||
u'language_id': bible[3],
|
||||
u'download_source_id': bible[4]
|
||||
}
|
||||
for bible in bibles
|
||||
]
|
||||
} for bible in bibles]
|
||||
else:
|
||||
return None
|
||||
|
||||
@ -801,7 +780,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||
u'abbreviation': bible[0][2],
|
||||
u'language_id': bible[0][3],
|
||||
u'download_source_id': bible[0][4]
|
||||
}
|
||||
}
|
||||
except (IndexError, TypeError):
|
||||
return None
|
||||
|
||||
@ -862,14 +841,11 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
|
||||
languages = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
|
||||
u'language ORDER by name')
|
||||
if languages:
|
||||
return [
|
||||
{
|
||||
return [{
|
||||
u'id': language[0],
|
||||
u'name': unicode(language[1]),
|
||||
u'code': unicode(language[2])
|
||||
}
|
||||
for language in languages
|
||||
]
|
||||
} for language in languages]
|
||||
else:
|
||||
return None
|
||||
|
||||
@ -1048,7 +1024,7 @@ class OldBibleDB(QtCore.QObject, Manager):
|
||||
Returns the version name of the Bible.
|
||||
"""
|
||||
version_name = self.run_sql(u'SELECT value FROM '
|
||||
u'metadata WHERE key = "Version"')
|
||||
u'metadata WHERE key = "name"')
|
||||
if version_name:
|
||||
self.name = version_name[0][0]
|
||||
else:
|
||||
@ -1062,13 +1038,10 @@ class OldBibleDB(QtCore.QObject, Manager):
|
||||
metadata = self.run_sql(u'SELECT key, value FROM metadata '
|
||||
u'ORDER BY rowid')
|
||||
if metadata:
|
||||
return [
|
||||
{
|
||||
return [{
|
||||
u'key': unicode(meta[0]),
|
||||
u'value': unicode(meta[1])
|
||||
}
|
||||
for meta in metadata
|
||||
]
|
||||
} for meta in metadata]
|
||||
else:
|
||||
return None
|
||||
|
||||
@ -1100,13 +1073,10 @@ class OldBibleDB(QtCore.QObject, Manager):
|
||||
"""
|
||||
books = self.run_sql(u'SELECT name, id FROM book ORDER BY id')
|
||||
if books:
|
||||
return [
|
||||
{
|
||||
return [{
|
||||
u'name': unicode(book[0]),
|
||||
u'id':int(book[1])
|
||||
}
|
||||
for book in books
|
||||
]
|
||||
} for book in books]
|
||||
else:
|
||||
return None
|
||||
|
||||
@ -1117,15 +1087,12 @@ class OldBibleDB(QtCore.QObject, Manager):
|
||||
verses = self.run_sql(u'SELECT book_id, chapter, verse, text FROM '
|
||||
u'verse WHERE book_id = ? ORDER BY id', (book_id, ))
|
||||
if verses:
|
||||
return [
|
||||
{
|
||||
return [{
|
||||
u'book_id': int(verse[0]),
|
||||
u'chapter': int(verse[1]),
|
||||
u'verse': int(verse[2]),
|
||||
u'text': unicode(verse[3])
|
||||
}
|
||||
for verse in verses
|
||||
]
|
||||
} for verse in verses]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
@ -49,28 +49,28 @@ class BGExtract(object):
|
||||
"""
|
||||
Extract verses from BibleGateway
|
||||
"""
|
||||
def __init__(self, proxyurl=None):
|
||||
log.debug(u'BGExtract.init("%s")', proxyurl)
|
||||
self.proxyurl = proxyurl
|
||||
def __init__(self, proxy_url=None):
|
||||
log.debug(u'BGExtract.init("%s")', proxy_url)
|
||||
self.proxy_url = proxy_url
|
||||
socket.setdefaulttimeout(30)
|
||||
|
||||
def get_bible_chapter(self, version, bookname, chapter):
|
||||
def get_bible_chapter(self, version, book_name, chapter):
|
||||
"""
|
||||
Access and decode Bibles via the BibleGateway website.
|
||||
|
||||
``version``
|
||||
The version of the Bible like 31 for New International version.
|
||||
|
||||
``bookname``
|
||||
``book_name``
|
||||
Name of the Book.
|
||||
|
||||
``chapter``
|
||||
Chapter number.
|
||||
"""
|
||||
log.debug(u'BGExtract.get_bible_chapter("%s", "%s", "%s")', version,
|
||||
bookname, chapter)
|
||||
urlbookname = urllib.quote(bookname.encode("utf-8"))
|
||||
url_params = u'search=%s+%s&version=%s' % (urlbookname, chapter,
|
||||
book_name, chapter)
|
||||
url_book_name = urllib.quote(book_name.encode("utf-8"))
|
||||
url_params = u'search=%s+%s&version=%s' % (url_book_name, chapter,
|
||||
version)
|
||||
cleaner = [(re.compile(' |<br />|\'\+\''), lambda match: '')]
|
||||
soup = get_soup_for_bible_ref(
|
||||
@ -106,7 +106,7 @@ class BGExtract(object):
|
||||
verse_list = {}
|
||||
# Cater for inconsistent mark up in the first verse of a chapter.
|
||||
first_verse = verses.find(u'versenum')
|
||||
if first_verse and len(first_verse.contents):
|
||||
if first_verse and first_verse.contents:
|
||||
verse_list[1] = unicode(first_verse.contents[0])
|
||||
for verse in verses(u'sup', u'versenum'):
|
||||
raw_verse_num = verse.next
|
||||
@ -120,7 +120,7 @@ class BGExtract(object):
|
||||
clean_verse_num = int(str(raw_verse_num))
|
||||
except ValueError:
|
||||
log.warn(u'Illegal verse number in %s %s %s:%s',
|
||||
version, bookname, chapter, unicode(raw_verse_num))
|
||||
version, book_name, chapter, unicode(raw_verse_num))
|
||||
if clean_verse_num:
|
||||
verse_text = raw_verse_num.next
|
||||
part = raw_verse_num.next.next
|
||||
@ -138,7 +138,7 @@ class BGExtract(object):
|
||||
log.debug(u'No content found in the BibleGateway response.')
|
||||
send_error_message(u'parse')
|
||||
return None
|
||||
return SearchResults(bookname, chapter, verse_list)
|
||||
return SearchResults(book_name, chapter, verse_list)
|
||||
|
||||
def get_books_from_http(self, version):
|
||||
"""
|
||||
@ -195,30 +195,30 @@ class BSExtract(object):
|
||||
"""
|
||||
Extract verses from Bibleserver.com
|
||||
"""
|
||||
def __init__(self, proxyurl=None):
|
||||
log.debug(u'BSExtract.init("%s")', proxyurl)
|
||||
self.proxyurl = proxyurl
|
||||
def __init__(self, proxy_url=None):
|
||||
log.debug(u'BSExtract.init("%s")', proxy_url)
|
||||
self.proxy_url = proxy_url
|
||||
socket.setdefaulttimeout(30)
|
||||
|
||||
def get_bible_chapter(self, version, bookname, chapter):
|
||||
def get_bible_chapter(self, version, book_name, chapter):
|
||||
"""
|
||||
Access and decode bibles via Bibleserver mobile website
|
||||
|
||||
``version``
|
||||
The version of the bible like NIV for New International Version
|
||||
|
||||
``bookname``
|
||||
``book_name``
|
||||
Text name of bible book e.g. Genesis, 1. John, 1John or Offenbarung
|
||||
|
||||
``chapter``
|
||||
Chapter number
|
||||
"""
|
||||
log.debug(u'BSExtract.get_bible_chapter("%s", "%s", "%s")', version,
|
||||
bookname, chapter)
|
||||
urlversion = urllib.quote(version.encode("utf-8"))
|
||||
urlbookname = urllib.quote(bookname.encode("utf-8"))
|
||||
book_name, chapter)
|
||||
url_version = urllib.quote(version.encode("utf-8"))
|
||||
url_book_name = urllib.quote(book_name.encode("utf-8"))
|
||||
chapter_url = u'http://m.bibleserver.com/text/%s/%s%d' % \
|
||||
(urlversion, urlbookname, chapter)
|
||||
(url_version, url_book_name, chapter)
|
||||
header = (u'Accept-Language', u'en')
|
||||
soup = get_soup_for_bible_ref(chapter_url, header)
|
||||
if not soup:
|
||||
@ -236,7 +236,7 @@ class BSExtract(object):
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
versenumber = int(verse_number.sub(r'\3', verse[u'class']))
|
||||
verses[versenumber] = verse.contents[1].rstrip(u'\n')
|
||||
return SearchResults(bookname, chapter, verses)
|
||||
return SearchResults(book_name, chapter, verses)
|
||||
|
||||
def get_books_from_http(self, version):
|
||||
"""
|
||||
@ -268,72 +268,72 @@ class CWExtract(object):
|
||||
"""
|
||||
Extract verses from CrossWalk/BibleStudyTools
|
||||
"""
|
||||
def __init__(self, proxyurl=None):
|
||||
log.debug(u'CWExtract.init("%s")', proxyurl)
|
||||
self.proxyurl = proxyurl
|
||||
def __init__(self, proxy_url=None):
|
||||
log.debug(u'CWExtract.init("%s")', proxy_url)
|
||||
self.proxy_url = proxy_url
|
||||
socket.setdefaulttimeout(30)
|
||||
|
||||
def get_bible_chapter(self, version, bookname, chapter):
|
||||
def get_bible_chapter(self, version, book_name, chapter):
|
||||
"""
|
||||
Access and decode bibles via the Crosswalk website
|
||||
|
||||
``version``
|
||||
The version of the Bible like niv for New International Version
|
||||
|
||||
``bookname``
|
||||
``book_name``
|
||||
Text name of in english e.g. 'gen' for Genesis
|
||||
|
||||
``chapter``
|
||||
Chapter number
|
||||
"""
|
||||
log.debug(u'CWExtract.get_bible_chapter("%s", "%s", "%s")', version,
|
||||
bookname, chapter)
|
||||
urlbookname = bookname.replace(u' ', u'-')
|
||||
urlbookname = urlbookname.lower()
|
||||
urlbookname = urllib.quote(urlbookname.encode("utf-8"))
|
||||
book_name, chapter)
|
||||
url_book_name = book_name.replace(u' ', u'-')
|
||||
url_book_name = url_book_name.lower()
|
||||
url_book_name = urllib.quote(url_book_name.encode("utf-8"))
|
||||
chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % \
|
||||
(version, urlbookname, chapter)
|
||||
(version, url_book_name, chapter)
|
||||
soup = get_soup_for_bible_ref(chapter_url)
|
||||
if not soup:
|
||||
return None
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
htmlverses = soup.findAll(u'span', u'versetext')
|
||||
if not htmlverses:
|
||||
html_verses = soup.findAll(u'span', u'versetext')
|
||||
if not html_verses:
|
||||
log.error(u'No verses found in the CrossWalk response.')
|
||||
send_error_message(u'parse')
|
||||
return None
|
||||
verses = {}
|
||||
reduce_spaces = re.compile(r'[ ]{2,}')
|
||||
fix_punctuation = re.compile(r'[ ]+([.,;])')
|
||||
for verse in htmlverses:
|
||||
for verse in html_verses:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
versenumber = int(verse.contents[0].contents[0])
|
||||
versetext = u''
|
||||
verse_number = int(verse.contents[0].contents[0])
|
||||
verse_text = u''
|
||||
for part in verse.contents:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
if isinstance(part, NavigableString):
|
||||
versetext = versetext + part
|
||||
verse_text = verse_text + part
|
||||
elif part and part.attrMap and \
|
||||
(part.attrMap[u'class'] == u'WordsOfChrist' or \
|
||||
part.attrMap[u'class'] == u'strongs'):
|
||||
for subpart in part.contents:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
if isinstance(subpart, NavigableString):
|
||||
versetext = versetext + subpart
|
||||
verse_text = verse_text + subpart
|
||||
elif subpart and subpart.attrMap and \
|
||||
subpart.attrMap[u'class'] == u'strongs':
|
||||
for subsub in subpart.contents:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
if isinstance(subsub, NavigableString):
|
||||
versetext = versetext + subsub
|
||||
verse_text = verse_text + subsub
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
# Fix up leading and trailing spaces, multiple spaces, and spaces
|
||||
# between text and , and .
|
||||
versetext = versetext.strip(u'\n\r\t ')
|
||||
versetext = reduce_spaces.sub(u' ', versetext)
|
||||
versetext = fix_punctuation.sub(r'\1', versetext)
|
||||
verses[versenumber] = versetext
|
||||
return SearchResults(bookname, chapter, verses)
|
||||
verse_text = verse_text.strip(u'\n\r\t ')
|
||||
verse_text = reduce_spaces.sub(u' ', verse_text)
|
||||
verse_text = fix_punctuation.sub(r'\1', verse_text)
|
||||
verses[verse_number] = verse_text
|
||||
return SearchResults(book_name, chapter, verses)
|
||||
|
||||
def get_books_from_http(self, version):
|
||||
"""
|
||||
@ -401,16 +401,16 @@ class HTTPBible(BibleDB):
|
||||
self.wizard.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.HTTPBible',
|
||||
'Registering Bible and loading books...')))
|
||||
self.save_meta(u'download source', self.download_source)
|
||||
self.save_meta(u'download name', self.download_name)
|
||||
self.save_meta(u'download_source', self.download_source)
|
||||
self.save_meta(u'download_name', self.download_name)
|
||||
if self.proxy_server:
|
||||
self.save_meta(u'proxy server', self.proxy_server)
|
||||
self.save_meta(u'proxy_server', self.proxy_server)
|
||||
if self.proxy_username:
|
||||
# Store the proxy userid.
|
||||
self.save_meta(u'proxy username', self.proxy_username)
|
||||
self.save_meta(u'proxy_username', self.proxy_username)
|
||||
if self.proxy_password:
|
||||
# Store the proxy password.
|
||||
self.save_meta(u'proxy password', self.proxy_password)
|
||||
self.save_meta(u'proxy_password', self.proxy_password)
|
||||
if self.download_source.lower() == u'crosswalk':
|
||||
handler = CWExtract(self.proxy_server)
|
||||
elif self.download_source.lower() == u'biblegateway':
|
||||
@ -499,10 +499,10 @@ class HTTPBible(BibleDB):
|
||||
## if it was there. By reusing the returned book name
|
||||
## we get a correct book. For example it is possible
|
||||
## to request ac and get Acts back.
|
||||
bookname = search_results.book
|
||||
book_name = search_results.book
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
# Check to see if book/chapter exists.
|
||||
db_book = self.get_book(bookname)
|
||||
db_book = self.get_book(book_name)
|
||||
self.create_chapter(db_book.id, search_results.chapter,
|
||||
search_results.verselist)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
@ -164,12 +164,12 @@ class BibleManager(object):
|
||||
self.db_cache[name] = bible
|
||||
# Look to see if lazy load bible exists and get create getter.
|
||||
source = self.db_cache[name].get_object(BibleMeta,
|
||||
u'download source')
|
||||
u'download_source')
|
||||
if source:
|
||||
download_name = self.db_cache[name].get_object(BibleMeta,
|
||||
u'download name').value
|
||||
u'download_name').value
|
||||
meta_proxy = self.db_cache[name].get_object(BibleMeta,
|
||||
u'proxy url')
|
||||
u'proxy_server')
|
||||
web_bible = HTTPBible(self.parent, path=self.path,
|
||||
file=filename, download_source=source.value,
|
||||
download_name=download_name)
|
||||
@ -330,7 +330,7 @@ class BibleManager(object):
|
||||
'Import Wizard to install one or more Bibles.')
|
||||
})
|
||||
return None
|
||||
language_selection = self.get_meta_data(bible, u'Bookname language')
|
||||
language_selection = self.get_meta_data(bible, u'book_name_language')
|
||||
if language_selection:
|
||||
language_selection = int(language_selection.value)
|
||||
if language_selection is None or language_selection == -1:
|
||||
@ -377,7 +377,7 @@ class BibleManager(object):
|
||||
Unicode. The Bible to get the language selection from.
|
||||
"""
|
||||
log.debug(u'BibleManager.get_language_selection("%s")', bible)
|
||||
language_selection = self.get_meta_data(bible, u'Bookname language')
|
||||
language_selection = self.get_meta_data(bible, u'book_name_language')
|
||||
if language_selection and language_selection.value != u'None':
|
||||
return int(language_selection.value)
|
||||
if language_selection is None or language_selection.value == u'None':
|
||||
@ -410,17 +410,17 @@ class BibleManager(object):
|
||||
return None
|
||||
# Check if the bible or second_bible is a web bible.
|
||||
webbible = self.db_cache[bible].get_object(BibleMeta,
|
||||
u'download source')
|
||||
u'download_source')
|
||||
second_webbible = u''
|
||||
if second_bible:
|
||||
second_webbible = self.db_cache[second_bible].get_object(BibleMeta,
|
||||
u'download source')
|
||||
u'download_source')
|
||||
if webbible or second_webbible:
|
||||
Receiver.send_message(u'openlp_information_message', {
|
||||
u'title': translate('BiblesPlugin.BibleManager',
|
||||
'Web Bible cannot be used'),
|
||||
'Web Bible cannot be used'),
|
||||
u'message': translate('BiblesPlugin.BibleManager',
|
||||
'Text Search is not available with Web Bibles.')
|
||||
'Text Search is not available with Web Bibles.')
|
||||
})
|
||||
return None
|
||||
if text:
|
||||
@ -428,27 +428,27 @@ class BibleManager(object):
|
||||
else:
|
||||
Receiver.send_message(u'openlp_information_message', {
|
||||
u'title': translate('BiblesPlugin.BibleManager',
|
||||
'Scripture Reference Error'),
|
||||
'Scripture Reference Error'),
|
||||
u'message': translate('BiblesPlugin.BibleManager',
|
||||
'You did not enter a search keyword.\n'
|
||||
'You can separate different keywords by a space to search for '
|
||||
'all of your keywords and you can separate them by a comma to '
|
||||
'search for one of them.')
|
||||
'You did not enter a search keyword.\n'
|
||||
'You can separate different keywords by a space to '
|
||||
'search for all of your keywords and you can separate '
|
||||
'them by a comma to search for one of them.')
|
||||
})
|
||||
return None
|
||||
|
||||
def save_meta_data(self, bible, version, copyright, permissions,
|
||||
bookname_language=None):
|
||||
book_name_language=None):
|
||||
"""
|
||||
Saves the bibles meta data.
|
||||
"""
|
||||
log.debug(u'save_meta data %s, %s, %s, %s',
|
||||
bible, version, copyright, permissions)
|
||||
self.db_cache[bible].save_meta(u'Version', version)
|
||||
self.db_cache[bible].save_meta(u'Copyright', copyright)
|
||||
self.db_cache[bible].save_meta(u'Permissions', permissions)
|
||||
self.db_cache[bible].save_meta(u'Bookname language',
|
||||
bookname_language)
|
||||
self.db_cache[bible].save_meta(u'name', version)
|
||||
self.db_cache[bible].save_meta(u'copyright', copyright)
|
||||
self.db_cache[bible].save_meta(u'permissions', permissions)
|
||||
self.db_cache[bible].save_meta(u'book_name_language',
|
||||
book_name_language)
|
||||
|
||||
def get_meta_data(self, bible, key):
|
||||
"""
|
||||
|
@ -64,7 +64,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.unlockIcon = build_icon(u':/bibles/bibles_search_unlock.png')
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
# Place to store the search results for both bibles.
|
||||
self.settings = self.plugin.settings_tab
|
||||
self.settings = self.plugin.settingsTab
|
||||
self.quickPreviewAllowed = True
|
||||
self.hasSearch = True
|
||||
self.search_results = {}
|
||||
@ -392,7 +392,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
if bible in bibles:
|
||||
find_and_set_in_combo_box(self.advancedVersionComboBox, bible)
|
||||
self.initialiseAdvancedBible(unicode(bible))
|
||||
elif len(bibles):
|
||||
elif bibles:
|
||||
self.initialiseAdvancedBible(bibles[0])
|
||||
bible = QtCore.QSettings().value(
|
||||
self.settingsSection + u'/quick bible', QtCore.QVariant(
|
||||
@ -408,7 +408,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.plugin.appStartup()
|
||||
self.updateAutoCompleter()
|
||||
|
||||
def initialiseAdvancedBible(self, bible):
|
||||
def initialiseAdvancedBible(self, bible, last_book_id=None):
|
||||
"""
|
||||
This initialises the given bible, which means that its book names and
|
||||
their chapter numbers is added to the combo boxes on the
|
||||
@ -417,8 +417,12 @@ class BibleMediaItem(MediaManagerItem):
|
||||
|
||||
``bible``
|
||||
The bible to initialise (unicode).
|
||||
|
||||
``last_book_id``
|
||||
The "book reference id" of the book which is choosen at the moment.
|
||||
(int)
|
||||
"""
|
||||
log.debug(u'initialiseAdvancedBible %s', bible)
|
||||
log.debug(u'initialiseAdvancedBible %s, %s', bible, last_book_id)
|
||||
book_data = self.plugin.manager.get_books(bible)
|
||||
secondbible = unicode(self.advancedSecondComboBox.currentText())
|
||||
if secondbible != u'':
|
||||
@ -432,8 +436,9 @@ class BibleMediaItem(MediaManagerItem):
|
||||
book_data = book_data_temp
|
||||
self.advancedBookComboBox.clear()
|
||||
first = True
|
||||
initialise_chapter_verse = False
|
||||
language_selection = self.plugin.manager.get_language_selection(bible)
|
||||
booknames = BibleStrings().Booknames
|
||||
book_names = BibleStrings().BookNames
|
||||
for book in book_data:
|
||||
row = self.advancedBookComboBox.count()
|
||||
if language_selection == LanguageSelection.Bible:
|
||||
@ -442,7 +447,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
data = BiblesResourcesDB.get_book_by_id(
|
||||
book[u'book_reference_id'])
|
||||
self.advancedBookComboBox.addItem(
|
||||
booknames[data[u'abbreviation']])
|
||||
book_names[data[u'abbreviation']])
|
||||
elif language_selection == LanguageSelection.English:
|
||||
data = BiblesResourcesDB.get_book_by_id(
|
||||
book[u'book_reference_id'])
|
||||
@ -451,8 +456,19 @@ class BibleMediaItem(MediaManagerItem):
|
||||
row, QtCore.QVariant(book[u'book_reference_id']))
|
||||
if first:
|
||||
first = False
|
||||
self.initialiseChapterVerse(bible, book[u'name'],
|
||||
book[u'book_reference_id'])
|
||||
first_book = book
|
||||
initialise_chapter_verse = True
|
||||
if last_book_id and last_book_id == int(book[u'book_reference_id']):
|
||||
index = self.advancedBookComboBox.findData(
|
||||
QtCore.QVariant(book[u'book_reference_id']))
|
||||
if index == -1:
|
||||
# Not Found.
|
||||
index = 0
|
||||
self.advancedBookComboBox.setCurrentIndex(index)
|
||||
initialise_chapter_verse = False
|
||||
if initialise_chapter_verse:
|
||||
self.initialiseChapterVerse(bible, first_book[u'name'],
|
||||
first_book[u'book_reference_id'])
|
||||
|
||||
def initialiseChapterVerse(self, bible, book, book_ref_id):
|
||||
log.debug(u'initialiseChapterVerse %s, %s, %s', bible, book,
|
||||
@ -509,12 +525,12 @@ class BibleMediaItem(MediaManagerItem):
|
||||
if language_selection == LanguageSelection.Bible:
|
||||
books = [book.name + u' ' for book in book_data]
|
||||
elif language_selection == LanguageSelection.Application:
|
||||
booknames = BibleStrings().Booknames
|
||||
book_names = BibleStrings().BookNames
|
||||
for book in book_data:
|
||||
data = BiblesResourcesDB.get_book_by_id(
|
||||
book.book_reference_id)
|
||||
books.append(unicode(
|
||||
booknames[data[u'abbreviation']]) + u' ')
|
||||
book_names[data[u'abbreviation']]) + u' ')
|
||||
elif language_selection == LanguageSelection.English:
|
||||
for book in book_data:
|
||||
data = BiblesResourcesDB.get_book_by_id(
|
||||
@ -537,7 +553,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
elif self.advancedTab.isVisible():
|
||||
bible = unicode(self.advancedVersionComboBox.currentText())
|
||||
if bible:
|
||||
self.editBibleForm = EditBibleForm(self, self.plugin.formparent,
|
||||
self.editBibleForm = EditBibleForm(self, self.plugin.formParent,
|
||||
self.plugin.manager)
|
||||
self.editBibleForm.loadBible(bible)
|
||||
if self.editBibleForm.exec_():
|
||||
@ -597,11 +613,15 @@ class BibleMediaItem(MediaManagerItem):
|
||||
QtCore.QSettings().setValue(self.settingsSection + u'/advanced bible',
|
||||
QtCore.QVariant(self.advancedVersionComboBox.currentText()))
|
||||
self.initialiseAdvancedBible(
|
||||
unicode(self.advancedVersionComboBox.currentText()))
|
||||
unicode(self.advancedVersionComboBox.currentText()),
|
||||
self.advancedBookComboBox.itemData(
|
||||
int(self.advancedBookComboBox.currentIndex())))
|
||||
|
||||
def onAdvancedSecondComboBox(self):
|
||||
self.initialiseAdvancedBible(
|
||||
unicode(self.advancedVersionComboBox.currentText()))
|
||||
unicode(self.advancedVersionComboBox.currentText()),
|
||||
self.advancedBookComboBox.itemData(
|
||||
int(self.advancedBookComboBox.currentIndex())))
|
||||
|
||||
def onAdvancedBookComboBox(self):
|
||||
item = int(self.advancedBookComboBox.currentIndex())
|
||||
@ -806,30 +826,30 @@ class BibleMediaItem(MediaManagerItem):
|
||||
further action is saved for/in each row.
|
||||
"""
|
||||
verse_separator = get_reference_separator(u'sep_v_display')
|
||||
version = self.plugin.manager.get_meta_data(bible, u'Version').value
|
||||
copyright = self.plugin.manager.get_meta_data(bible, u'Copyright').value
|
||||
version = self.plugin.manager.get_meta_data(bible, u'name').value
|
||||
copyright = self.plugin.manager.get_meta_data(bible, u'copyright').value
|
||||
permissions = \
|
||||
self.plugin.manager.get_meta_data(bible, u'Permissions').value
|
||||
self.plugin.manager.get_meta_data(bible, u'permissions').value
|
||||
second_version = u''
|
||||
second_copyright = u''
|
||||
second_permissions = u''
|
||||
if second_bible:
|
||||
second_version = self.plugin.manager.get_meta_data(
|
||||
second_bible, u'Version').value
|
||||
second_bible, u'name').value
|
||||
second_copyright = self.plugin.manager.get_meta_data(
|
||||
second_bible, u'Copyright').value
|
||||
second_bible, u'copyright').value
|
||||
second_permissions = self.plugin.manager.get_meta_data(
|
||||
second_bible, u'Permissions').value
|
||||
second_bible, u'permissions').value
|
||||
items = []
|
||||
language_selection = self.plugin.manager.get_language_selection(bible)
|
||||
for count, verse in enumerate(search_results):
|
||||
if language_selection == LanguageSelection.Bible:
|
||||
book = verse.book.name
|
||||
elif language_selection == LanguageSelection.Application:
|
||||
booknames = BibleStrings().Booknames
|
||||
book_names = BibleStrings().Booknames
|
||||
data = BiblesResourcesDB.get_book_by_id(
|
||||
verse.book.book_reference_id)
|
||||
book = unicode(booknames[data[u'abbreviation']])
|
||||
book = unicode(book_names[data[u'abbreviation']])
|
||||
elif language_selection == LanguageSelection.English:
|
||||
data = BiblesResourcesDB.get_book_by_id(
|
||||
verse.book.book_reference_id)
|
||||
@ -878,7 +898,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
items = item
|
||||
else:
|
||||
items = self.listView.selectedItems()
|
||||
if len(items) == 0:
|
||||
if not items:
|
||||
return False
|
||||
bible_text = u''
|
||||
old_item = None
|
||||
@ -949,7 +969,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
# Service Item: Title
|
||||
service_item.title = create_separated_list(raw_title)
|
||||
# Service Item: Theme
|
||||
if len(self.settings.bible_theme) == 0:
|
||||
if not self.settings.bible_theme:
|
||||
service_item.theme = None
|
||||
else:
|
||||
service_item.theme = self.settings.bible_theme
|
||||
|
@ -50,8 +50,6 @@ class OSISBible(BibleDB):
|
||||
log.debug(self.__class__.__name__)
|
||||
BibleDB.__init__(self, parent, **kwargs)
|
||||
self.filename = kwargs[u'filename']
|
||||
fbibles = None
|
||||
self.books = {}
|
||||
self.language_regex = re.compile(r'<language.*>(.*?)</language>')
|
||||
self.verse_regex = re.compile(
|
||||
r'<verse osisID="([a-zA-Z0-9 ]*).([0-9]*).([0-9]*)">(.*?)</verse>')
|
||||
@ -74,16 +72,6 @@ class OSISBible(BibleDB):
|
||||
filepath = os.path.join(
|
||||
AppLocation.get_directory(AppLocation.PluginsDir), u'bibles',
|
||||
u'resources', u'osisbooks.csv')
|
||||
try:
|
||||
fbibles = open(filepath, u'r')
|
||||
for line in fbibles:
|
||||
book = line.split(u',')
|
||||
self.books[book[0]] = (book[1].strip(), book[2].strip())
|
||||
except IOError:
|
||||
log.exception(u'OSIS bible import failed')
|
||||
finally:
|
||||
if fbibles:
|
||||
fbibles.close()
|
||||
|
||||
def do_import(self, bible_name=None):
|
||||
"""
|
||||
@ -101,6 +89,8 @@ class OSISBible(BibleDB):
|
||||
try:
|
||||
detect_file = open(self.filename, u'r')
|
||||
details = chardet.detect(detect_file.read(1048576))
|
||||
detect_file.seek(0)
|
||||
lines_in_file = int(len(detect_file.readlines()))
|
||||
except IOError:
|
||||
log.exception(u'Failed to detect OSIS file encoding')
|
||||
return
|
||||
@ -111,6 +101,17 @@ class OSISBible(BibleDB):
|
||||
osis = codecs.open(self.filename, u'r', details['encoding'])
|
||||
repl = replacement
|
||||
language_id = False
|
||||
# Decide if the bible propably contains only NT or AT and NT or
|
||||
# AT, NT and Apocrypha
|
||||
if lines_in_file < 11500:
|
||||
book_count = 27
|
||||
chapter_count = 260
|
||||
elif lines_in_file < 34200:
|
||||
book_count = 66
|
||||
chapter_count = 1188
|
||||
else:
|
||||
book_count = 67
|
||||
chapter_count = 1336
|
||||
for file_record in osis:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
@ -134,36 +135,32 @@ class OSISBible(BibleDB):
|
||||
% self.filename)
|
||||
return False
|
||||
match_count += 1
|
||||
book = match.group(1)
|
||||
book = unicode(match.group(1))
|
||||
chapter = int(match.group(2))
|
||||
verse = int(match.group(3))
|
||||
verse_text = match.group(4)
|
||||
if not db_book or db_book.name != self.books[book][0]:
|
||||
log.debug(u'New book: "%s"' % self.books[book][0])
|
||||
book_ref_id = self.get_book_ref_id_by_name(unicode(
|
||||
self.books[book][0]), 67, language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Importing books from "%s" '\
|
||||
'failed' % self.filename)
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(
|
||||
book_ref_id)
|
||||
book_ref_id = self.get_book_ref_id_by_name(book, book_count,
|
||||
language_id)
|
||||
if not book_ref_id:
|
||||
log.exception(u'Importing books from "%s" failed' %
|
||||
self.filename)
|
||||
return False
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
if not db_book or db_book.name != book_details[u'name']:
|
||||
log.debug(u'New book: "%s"' % book_details[u'name'])
|
||||
db_book = self.create_book(
|
||||
unicode(self.books[book][0]),
|
||||
book_details[u'name'],
|
||||
book_ref_id,
|
||||
book_details[u'testament_id'])
|
||||
if last_chapter == 0:
|
||||
if book == u'Gen':
|
||||
self.wizard.progressBar.setMaximum(1188)
|
||||
else:
|
||||
self.wizard.progressBar.setMaximum(260)
|
||||
self.wizard.progressBar.setMaximum(chapter_count)
|
||||
if last_chapter != chapter:
|
||||
if last_chapter != 0:
|
||||
self.session.commit()
|
||||
self.wizard.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.OsisImport', 'Importing %s %s...',
|
||||
'Importing <book name> <chapter>...')) %
|
||||
(self.books[match.group(1)][0], chapter))
|
||||
(book_details[u'name'], chapter))
|
||||
last_chapter = chapter
|
||||
# All of this rigmarol below is because the mod2osis
|
||||
# tool from the Sword library embeds XML in the OSIS
|
||||
|
191
openlp/plugins/bibles/lib/upgrade.py
Normal file
191
openlp/plugins/bibles/lib/upgrade.py
Normal file
@ -0,0 +1,191 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
|
||||
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
|
||||
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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:`upgrade` module provides a way for the database and schema that is the
|
||||
backend for the Bibles plugin
|
||||
"""
|
||||
import logging
|
||||
|
||||
from sqlalchemy import Table, func, select, insert
|
||||
|
||||
__version__ = 1
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def upgrade_setup(metadata):
|
||||
"""
|
||||
Set up the latest revision all tables, with reflection, needed for the
|
||||
upgrade process. If you want to drop a table, you need to remove it from
|
||||
here, and add it to your upgrade function.
|
||||
"""
|
||||
# Don't define the "metadata" table, as the upgrade mechanism already
|
||||
# defines it.
|
||||
tables = {
|
||||
u'book': Table(u'book', metadata, autoload=True),
|
||||
u'verse': Table(u'verse', metadata, autoload=True)
|
||||
}
|
||||
return tables
|
||||
|
||||
|
||||
def upgrade_1(session, metadata, tables):
|
||||
"""
|
||||
Version 1 upgrade.
|
||||
|
||||
This upgrade renames a number of keys to a single naming convention..
|
||||
"""
|
||||
metadata_table = metadata.tables[u'metadata']
|
||||
# Copy "Version" to "name" ("version" used by upgrade system)
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
session.execute(insert(metadata_table).values(
|
||||
key=u'name',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == u'Version'
|
||||
).as_scalar()
|
||||
))
|
||||
# Copy "Copyright" to "copyright"
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
session.execute(insert(metadata_table).values(
|
||||
key=u'copyright',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == u'Copyright'
|
||||
).as_scalar()
|
||||
))
|
||||
# Copy "Permissions" to "permissions"
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
session.execute(insert(metadata_table).values(
|
||||
key=u'permissions',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == u'Permissions'
|
||||
).as_scalar()
|
||||
))
|
||||
# Copy "Bookname language" to "book_name_language"
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == u'Bookname language'
|
||||
)
|
||||
).scalar()
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key=u'book_name_language',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == u'Bookname language'
|
||||
).as_scalar()
|
||||
))
|
||||
# Copy "download source" to "download_source"
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == u'download source'
|
||||
)
|
||||
).scalar()
|
||||
log.debug(u'download source: %s', value_count)
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key=u'download_source',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == u'download source'
|
||||
).as_scalar()
|
||||
))
|
||||
# Copy "download name" to "download_name"
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == u'download name'
|
||||
)
|
||||
).scalar()
|
||||
log.debug(u'download name: %s', value_count)
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key=u'download_name',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == u'download name'
|
||||
).as_scalar()
|
||||
))
|
||||
# Copy "proxy server" to "proxy_server"
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == u'proxy server'
|
||||
)
|
||||
).scalar()
|
||||
log.debug(u'proxy server: %s', value_count)
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key=u'proxy_server',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == u'proxy server'
|
||||
).as_scalar()
|
||||
))
|
||||
# Copy "proxy username" to "proxy_username"
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == u'proxy username'
|
||||
)
|
||||
).scalar()
|
||||
log.debug(u'proxy username: %s', value_count)
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key=u'proxy_username',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == u'proxy username'
|
||||
).as_scalar()
|
||||
))
|
||||
# Copy "proxy password" to "proxy_password"
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
value_count = session.execute(
|
||||
select(
|
||||
[func.count(metadata_table.c.value)],
|
||||
metadata_table.c.key == u'proxy password'
|
||||
)
|
||||
).scalar()
|
||||
log.debug(u'proxy password: %s', value_count)
|
||||
if value_count > 0:
|
||||
session.execute(insert(metadata_table).values(
|
||||
key=u'proxy_password',
|
||||
value=select(
|
||||
[metadata_table.c.value],
|
||||
metadata_table.c.key == u'proxy password'
|
||||
).as_scalar()
|
||||
))
|
||||
# TODO: Clean up in a subsequent release of OpenLP (like 2.0 final)
|
||||
#session.execute(delete(metadata_table)\
|
||||
# .where(metadata_table.c.key == u'dbversion'))
|
||||
session.commit()
|
@ -1,76 +0,0 @@
|
||||
Gen,Genesis,Gen
|
||||
Exod,Exodus,Exod
|
||||
Lev,Leviticus,Lev
|
||||
Num,Numbers,Num
|
||||
Deut,Deuteronomy,Deut
|
||||
Josh,Joshua,Josh
|
||||
Judg,Judges,Judg
|
||||
Ruth,Ruth,Ruth
|
||||
1Sam,1 Samuel,1Sam
|
||||
2Sam,2 Samuel,2Sam
|
||||
1Kgs,1 Kings,1Kgs
|
||||
2Kgs,2 Kings,2Kgs
|
||||
1Chr,1 Chronicles,1Chr
|
||||
2Chr,2 Chronicles,2Chr
|
||||
Ezra,Ezra,Ezra
|
||||
Neh,Nehemiah,Neh
|
||||
Esth,Esther,Esth
|
||||
Job,Job,Job
|
||||
Ps,Psalms,Ps
|
||||
Prov,Proverbs,Prov
|
||||
Eccl,Ecclesiastes,Eccl
|
||||
Song,Song of Songs,Song
|
||||
Isa,Isaiah,Isa
|
||||
Jer,Jeremiah,Jer
|
||||
Lam,Lamentations,Lam
|
||||
Ezek,Ezekiel,Ezek
|
||||
Dan,Daniel,Dan
|
||||
Hos,Hosea,Hos
|
||||
Joel,Joel,Joel
|
||||
Amos,Amos,Amos
|
||||
Obad,Obad,Obad
|
||||
Jonah,Jonah,Jonah
|
||||
Mic,Micah,Mic
|
||||
Nah,Naham,Nah
|
||||
Hab,Habakkuk,Hab
|
||||
Zeph,Zephaniah,Zeph
|
||||
Hag,Haggai,Hag
|
||||
Zech,Zechariah,Zech
|
||||
Mal,Malachi,Mal
|
||||
Matt,Matthew,Matt
|
||||
Mark,Mark,Mark
|
||||
Luke,Luke,Luke
|
||||
John,John,John
|
||||
Acts,Acts,Acts
|
||||
Rom,Romans,Rom
|
||||
1Cor,1 Corinthians,1Cor
|
||||
2Cor,2 Corinthians,2Cor
|
||||
Gal,Galatians,Gal
|
||||
Eph,Ephesians,Eph
|
||||
Phil,Philippians,Phil
|
||||
Col,Colossians,Col
|
||||
1Thess,1 Thessalonians,1Thess
|
||||
2Thess,2 Thessalonians,2Thess
|
||||
1Tim,1 Timothy,1Tim
|
||||
2Tim,2 Timothy,2Tim
|
||||
Titus,Titus,Titus
|
||||
Phlm,Philemon,Phlm
|
||||
Heb,Hebrews,Heb
|
||||
Jas,James,Jas
|
||||
1Pet,1 Peter,1Pet
|
||||
2Pet,2 Peter,2Pet
|
||||
1John,1 John,1John
|
||||
2John,2 John,2John
|
||||
3John,3 John,3John
|
||||
Jude,Jude,Jude
|
||||
Rev,Revelation,Rev
|
||||
Jdt,Judith,Jdt
|
||||
Wis,Wisdom,Wis
|
||||
Tob,Tobit,Tob
|
||||
Sir,Sirach,Sir
|
||||
Bar,Baruch,Bar
|
||||
1Macc,1 Maccabees,1Macc
|
||||
2Macc,2 Maccabees,2Macc
|
||||
AddDan,Rest of Daniel,AddDan
|
||||
AddEsth,Rest of Esther,AddEsth
|
||||
PrMan,Prayer of Manasses,PrMan
|
|
@ -50,8 +50,8 @@ class CustomPlugin(Plugin):
|
||||
CustomMediaItem, CustomTab)
|
||||
self.weight = -5
|
||||
self.manager = Manager(u'custom', init_schema)
|
||||
self.icon_path = u':/plugins/plugin_custom.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.iconPath = u':/plugins/plugin_custom.png'
|
||||
self.icon = build_icon(self.iconPath)
|
||||
|
||||
def about(self):
|
||||
about_text = translate('CustomPlugin', '<strong>Custom Slide Plugin'
|
||||
|
@ -127,7 +127,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
sxml.new_document()
|
||||
sxml.add_lyrics_to_song()
|
||||
count = 1
|
||||
for i in range(0, self.slideListView.count()):
|
||||
for i in range(self.slideListView.count()):
|
||||
sxml.add_verse_to_lyrics(u'custom', unicode(count),
|
||||
unicode(self.slideListView.item(i).text()))
|
||||
count += 1
|
||||
@ -170,7 +170,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
Edits all slides.
|
||||
"""
|
||||
slide_list = u''
|
||||
for row in range(0, self.slideListView.count()):
|
||||
for row in range(self.slideListView.count()):
|
||||
item = self.slideListView.item(row)
|
||||
slide_list += item.text()
|
||||
if row != self.slideListView.count() - 1:
|
||||
@ -206,7 +206,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
old_row = self.slideListView.currentRow()
|
||||
# Create a list with all (old/unedited) slides.
|
||||
old_slides = [self.slideListView.item(row).text() for row in \
|
||||
range(0, self.slideListView.count())]
|
||||
range(self.slideListView.count())]
|
||||
self.slideListView.clear()
|
||||
old_slides.pop(old_row)
|
||||
# Insert all slides to make the old_slides list complete.
|
||||
@ -254,7 +254,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
Checks whether a custom is valid or not.
|
||||
"""
|
||||
# We must have a title.
|
||||
if len(self.titleEdit.displayText()) == 0:
|
||||
if not self.titleEdit.displayText():
|
||||
self.titleEdit.setFocus()
|
||||
critical_error_message_box(
|
||||
message=translate('CustomPlugin.EditCustomForm',
|
||||
|
@ -57,7 +57,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'custom/custom'
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
self.edit_custom_form = EditCustomForm(self, self.plugin.formparent,
|
||||
self.edit_custom_form = EditCustomForm(self, self.plugin.formParent,
|
||||
self.plugin.manager)
|
||||
self.singleServiceItem = False
|
||||
self.quickPreviewAllowed = True
|
||||
@ -258,7 +258,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
search_length = 2
|
||||
if len(text) > search_length:
|
||||
self.onSearchTextButtonClicked()
|
||||
elif len(text) == 0:
|
||||
elif not text:
|
||||
self.onClearTextButtonClick()
|
||||
|
||||
def onClearTextButtonClick(self):
|
||||
|
@ -42,8 +42,8 @@ class ImagePlugin(Plugin):
|
||||
Plugin.__init__(self, u'images', plugin_helpers, ImageMediaItem,
|
||||
ImageTab)
|
||||
self.weight = -7
|
||||
self.icon_path = u':/plugins/plugin_images.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.iconPath = u':/plugins/plugin_images.png'
|
||||
self.icon = build_icon(self.iconPath)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'image_updated'), self.image_updated)
|
||||
|
||||
|
@ -106,24 +106,24 @@ class ImageMediaItem(MediaManagerItem):
|
||||
row_list = [item.row() for item in self.listView.selectedIndexes()]
|
||||
row_list.sort(reverse=True)
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.plugin.formparent.displayProgressBar(len(row_list))
|
||||
self.plugin.formParent.displayProgressBar(len(row_list))
|
||||
for row in row_list:
|
||||
text = self.listView.item(row)
|
||||
if text:
|
||||
delete_file(os.path.join(self.servicePath,
|
||||
unicode(text.text())))
|
||||
self.listView.takeItem(row)
|
||||
self.plugin.formparent.incrementProgressBar()
|
||||
self.plugin.formParent.incrementProgressBar()
|
||||
SettingsManager.set_list(self.settingsSection,
|
||||
u'images', self.getFileList())
|
||||
self.plugin.formparent.finishedProgressBar()
|
||||
self.plugin.formParent.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.listView.blockSignals(False)
|
||||
|
||||
def loadList(self, images, initialLoad=False):
|
||||
if not initialLoad:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.plugin.formparent.displayProgressBar(len(images))
|
||||
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,
|
||||
@ -144,9 +144,9 @@ class ImageMediaItem(MediaManagerItem):
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
|
||||
self.listView.addItem(item_name)
|
||||
if not initialLoad:
|
||||
self.plugin.formparent.incrementProgressBar()
|
||||
self.plugin.formParent.incrementProgressBar()
|
||||
if not initialLoad:
|
||||
self.plugin.formparent.finishedProgressBar()
|
||||
self.plugin.formParent.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
|
||||
def generateSlideData(self, service_item, item=None, xmlVersion=False,
|
||||
|
@ -41,8 +41,8 @@ class MediaPlugin(Plugin):
|
||||
Plugin.__init__(self, u'media', plugin_helpers,
|
||||
MediaMediaItem)
|
||||
self.weight = -6
|
||||
self.icon_path = u':/plugins/plugin_media.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.iconPath = u':/plugins/plugin_media.png'
|
||||
self.icon = build_icon(self.iconPath)
|
||||
# passed with drag and drop messages
|
||||
self.dnd_id = u'Media'
|
||||
self.audio_extensions_list = \
|
||||
@ -59,8 +59,8 @@ class MediaPlugin(Plugin):
|
||||
Create the settings Tab
|
||||
"""
|
||||
visible_name = self.getString(StringContent.VisibleName)
|
||||
self.settings_tab = MediaTab(parent, self.name, visible_name[u'title'],
|
||||
self.mediaController.mediaPlayers, self.icon_path)
|
||||
self.settingsTab = MediaTab(parent, self.name, visible_name[u'title'],
|
||||
self.mediaController.mediaPlayers, self.iconPath)
|
||||
|
||||
def about(self):
|
||||
about_text = translate('MediaPlugin', '<strong>Media Plugin</strong>'
|
||||
@ -142,6 +142,6 @@ class MediaPlugin(Plugin):
|
||||
self.mediaController.mediaPlayers[u'phonon'].isActive = True
|
||||
settings.setValue(u'players', \
|
||||
QtCore.QVariant(u','.join(new_players)))
|
||||
self.settings_tab.load()
|
||||
self.settingsTab.load()
|
||||
settings.remove(u'use phonon')
|
||||
settings.endGroup()
|
||||
|
@ -42,6 +42,9 @@ import time
|
||||
if os.name == u'nt':
|
||||
from win32com.client import Dispatch
|
||||
import pywintypes
|
||||
# Declare an empty exception to match the exception imported from UNO
|
||||
class ErrorCodeIOException(Exception):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
import uno
|
||||
@ -339,7 +342,6 @@ class ImpressDocument(PresentationDocument):
|
||||
Returns true if a presentation is loaded
|
||||
"""
|
||||
log.debug(u'is loaded OpenOffice')
|
||||
#print "is_loaded "
|
||||
if self.presentation is None or self.document is None:
|
||||
log.debug("is_loaded: no presentation or document")
|
||||
return False
|
||||
@ -357,14 +359,9 @@ class ImpressDocument(PresentationDocument):
|
||||
Returns true if a presentation is active and running
|
||||
"""
|
||||
log.debug(u'is active OpenOffice')
|
||||
#print "is_active "
|
||||
if not self.is_loaded():
|
||||
#print "False "
|
||||
return False
|
||||
#print "self.con ", self.control
|
||||
if self.control is None:
|
||||
return False
|
||||
return True
|
||||
return self.control is not None
|
||||
|
||||
def unblank_screen(self):
|
||||
"""
|
||||
|
@ -166,14 +166,14 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
if not initialLoad:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.plugin.formparent.displayProgressBar(len(files))
|
||||
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())
|
||||
for file in files:
|
||||
if not initialLoad:
|
||||
self.plugin.formparent.incrementProgressBar()
|
||||
self.plugin.formParent.incrementProgressBar()
|
||||
if currlist.count(file) > 0:
|
||||
continue
|
||||
filename = os.path.split(unicode(file))[1]
|
||||
@ -217,7 +217,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
self.listView.addItem(item_name)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
if not initialLoad:
|
||||
self.plugin.formparent.finishedProgressBar()
|
||||
self.plugin.formParent.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
|
||||
def onDeleteClick(self):
|
||||
@ -229,7 +229,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
row_list = [item.row() for item in items]
|
||||
row_list.sort(reverse=True)
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.plugin.formparent.displayProgressBar(len(row_list))
|
||||
self.plugin.formParent.displayProgressBar(len(row_list))
|
||||
for item in items:
|
||||
filepath = unicode(item.data(
|
||||
QtCore.Qt.UserRole).toString())
|
||||
@ -237,8 +237,8 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
doc = self.controllers[cidx].add_document(filepath)
|
||||
doc.presentation_deleted()
|
||||
doc.close_presentation()
|
||||
self.plugin.formparent.incrementProgressBar()
|
||||
self.plugin.formparent.finishedProgressBar()
|
||||
self.plugin.formParent.incrementProgressBar()
|
||||
self.plugin.formParent.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
for row in row_list:
|
||||
self.listView.takeItem(row)
|
||||
@ -263,50 +263,49 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
|
||||
service_item.add_capability(ItemCapabilities.HasDetailedTitleDisplay)
|
||||
shortname = service_item.shortname
|
||||
if shortname:
|
||||
for bitem in items:
|
||||
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
||||
if os.path.exists(filename):
|
||||
if shortname == self.Automatic:
|
||||
service_item.shortname = \
|
||||
self.findControllerByType(filename)
|
||||
if not service_item.shortname:
|
||||
return False
|
||||
controller = self.controllers[service_item.shortname]
|
||||
(path, name) = os.path.split(filename)
|
||||
doc = controller.add_document(filename)
|
||||
if doc.get_thumbnail_path(1, True) is None:
|
||||
doc.load_presentation()
|
||||
i = 1
|
||||
img = doc.get_thumbnail_path(i, True)
|
||||
if img:
|
||||
while img:
|
||||
service_item.add_from_command(path, name, img)
|
||||
i = i + 1
|
||||
img = doc.get_thumbnail_path(i, True)
|
||||
doc.close_presentation()
|
||||
return True
|
||||
else:
|
||||
# File is no longer present
|
||||
if not remote:
|
||||
critical_error_message_box(
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
'Missing Presentation'),
|
||||
unicode(translate(
|
||||
'PresentationPlugin.MediaItem',
|
||||
'The Presentation %s is incomplete,'
|
||||
' please reload.')) % filename)
|
||||
if not shortname:
|
||||
return False
|
||||
for bitem in items:
|
||||
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
|
||||
if os.path.exists(filename):
|
||||
if shortname == self.Automatic:
|
||||
service_item.shortname = self.findControllerByType(filename)
|
||||
if not service_item.shortname:
|
||||
return False
|
||||
controller = self.controllers[service_item.shortname]
|
||||
(path, name) = os.path.split(filename)
|
||||
doc = controller.add_document(filename)
|
||||
if doc.get_thumbnail_path(1, True) is None:
|
||||
doc.load_presentation()
|
||||
i = 1
|
||||
img = doc.get_thumbnail_path(i, True)
|
||||
if img:
|
||||
while img:
|
||||
service_item.add_from_command(path, name, img)
|
||||
i = i + 1
|
||||
img = doc.get_thumbnail_path(i, True)
|
||||
doc.close_presentation()
|
||||
return True
|
||||
else:
|
||||
# File is no longer present
|
||||
if not remote:
|
||||
critical_error_message_box(
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
'Missing Presentation'),
|
||||
unicode(translate(
|
||||
'PresentationPlugin.MediaItem',
|
||||
'The presentation %s is incomplete,'
|
||||
' please reload.')) % filename)
|
||||
return False
|
||||
else:
|
||||
# File is no longer present
|
||||
if not remote:
|
||||
critical_error_message_box(
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
'Missing Presentation'),
|
||||
unicode(translate('PresentationPlugin.MediaItem',
|
||||
'The Presentation %s no longer exists.')) % filename)
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
'The presentation %s no longer exists.')) % filename)
|
||||
return False
|
||||
|
||||
def findControllerByType(self, filename):
|
||||
"""
|
||||
|
@ -152,7 +152,7 @@ class PowerpointDocument(PresentationDocument):
|
||||
log.debug(u'create_thumbnails')
|
||||
if self.check_thumbnails():
|
||||
return
|
||||
for num in range(0, self.presentation.Slides.Count):
|
||||
for num in range(self.presentation.Slides.Count):
|
||||
self.presentation.Slides(num + 1).Export(os.path.join(
|
||||
self.get_thumbnail_folder(), 'slide%d.png' % (num + 1)),
|
||||
'png', 320, 240)
|
||||
|
@ -54,16 +54,16 @@ class PresentationPlugin(Plugin):
|
||||
self.controllers = {}
|
||||
Plugin.__init__(self, u'presentations', plugin_helpers)
|
||||
self.weight = -8
|
||||
self.icon_path = u':/plugins/plugin_presentations.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.iconPath = u':/plugins/plugin_presentations.png'
|
||||
self.icon = build_icon(self.iconPath)
|
||||
|
||||
def createSettingsTab(self, parent):
|
||||
"""
|
||||
Create the settings Tab
|
||||
"""
|
||||
visible_name = self.getString(StringContent.VisibleName)
|
||||
self.settings_tab = PresentationTab(parent, self.name,
|
||||
visible_name[u'title'], self.controllers, self.icon_path)
|
||||
self.settingsTab = PresentationTab(parent, self.name,
|
||||
visible_name[u'title'], self.controllers, self.iconPath)
|
||||
|
||||
def initialise(self):
|
||||
"""
|
||||
@ -99,7 +99,7 @@ class PresentationPlugin(Plugin):
|
||||
Create the Media Manager List
|
||||
"""
|
||||
self.mediaItem = PresentationMediaItem(
|
||||
self.mediadock.media_dock, self, self.icon, self.controllers)
|
||||
self.mediaDock.media_dock, self, self.icon, self.controllers)
|
||||
|
||||
def registerControllers(self, controller):
|
||||
"""
|
||||
@ -134,10 +134,7 @@ class PresentationPlugin(Plugin):
|
||||
for controller_class in controller_classes:
|
||||
controller = controller_class(self)
|
||||
self.registerControllers(controller)
|
||||
if self.controllers:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return bool(self.controllers)
|
||||
|
||||
def about(self):
|
||||
"""
|
||||
|
BIN
openlp/plugins/remotes/html/images/favicon.ico
Normal file
BIN
openlp/plugins/remotes/html/images/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
@ -31,6 +31,7 @@
|
||||
<title>${app_title}</title>
|
||||
<link rel="stylesheet" href="/files/jquery.mobile.css" />
|
||||
<link rel="stylesheet" href="/files/openlp.css" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/files/images/favicon.ico">
|
||||
<script type="text/javascript" src="/files/jquery.js"></script>
|
||||
<script type="text/javascript" src="/files/openlp.js"></script>
|
||||
<script type="text/javascript" src="/files/jquery.mobile.js"></script>
|
||||
|
9408
openlp/plugins/remotes/html/jquery.js
vendored
9408
openlp/plugins/remotes/html/jquery.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -29,6 +29,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<title>${stage_title}</title>
|
||||
<link rel="stylesheet" href="/files/stage.css" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/files/images/favicon.ico">
|
||||
<script type="text/javascript" src="/files/jquery.js"></script>
|
||||
<script type="text/javascript" src="/files/stage.js"></script>
|
||||
</head>
|
||||
|
@ -41,8 +41,8 @@ class RemotesPlugin(Plugin):
|
||||
"""
|
||||
Plugin.__init__(self, u'remotes', plugin_helpers,
|
||||
settings_tab_class=RemoteTab)
|
||||
self.icon_path = u':/plugins/plugin_remote.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.iconPath = u':/plugins/plugin_remote.png'
|
||||
self.icon = build_icon(self.iconPath)
|
||||
self.weight = -1
|
||||
self.server = None
|
||||
|
||||
|
@ -336,7 +336,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
Tag the Song List rows based on the verse list
|
||||
"""
|
||||
row_label = []
|
||||
for row in range(0, self.verseListWidget.rowCount()):
|
||||
for row in range(self.verseListWidget.rowCount()):
|
||||
item = self.verseListWidget.item(row, 0)
|
||||
verse_def = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
verse_tag = VerseType.translated_tag(verse_def[0])
|
||||
@ -494,7 +494,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
if len(tempText.split(u'\n')) != len(after_text.split(u'\n')):
|
||||
tempList = {}
|
||||
tempId = {}
|
||||
for row in range(0, self.verseListWidget.rowCount()):
|
||||
for row in range(self.verseListWidget.rowCount()):
|
||||
tempList[row] = self.verseListWidget.item(row, 0)\
|
||||
.text()
|
||||
tempId[row] = self.verseListWidget.item(row, 0)\
|
||||
@ -511,7 +511,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
def onVerseEditAllButtonClicked(self):
|
||||
verse_list = u''
|
||||
if self.verseListWidget.rowCount() > 0:
|
||||
for row in range(0, self.verseListWidget.rowCount()):
|
||||
for row in range(self.verseListWidget.rowCount()):
|
||||
item = self.verseListWidget.item(row, 0)
|
||||
field = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
verse_tag = VerseType.translated_name(field[0])
|
||||
@ -579,7 +579,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
verses = []
|
||||
verse_names = []
|
||||
order = self.__extractVerseOrder(text)
|
||||
for index in range(0, self.verseListWidget.rowCount()):
|
||||
for index in range(self.verseListWidget.rowCount()):
|
||||
verse = self.verseListWidget.item(index, 0)
|
||||
verse = unicode(verse.data(QtCore.Qt.UserRole).toString())
|
||||
if verse not in verse_names:
|
||||
@ -620,7 +620,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
verse_names = []
|
||||
order_names = unicode(verse_order).split()
|
||||
order = self.__extractVerseOrder(verse_order)
|
||||
for index in range(0, verse_count):
|
||||
for index in range(verse_count):
|
||||
verse = self.verseListWidget.item(index, 0)
|
||||
verse = unicode(verse.data(QtCore.Qt.UserRole).toString())
|
||||
if verse not in verse_names:
|
||||
@ -920,7 +920,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||
try:
|
||||
sxml = SongXML()
|
||||
multiple = []
|
||||
for i in range(0, self.verseListWidget.rowCount()):
|
||||
for i in range(self.verseListWidget.rowCount()):
|
||||
item = self.verseListWidget.item(i, 0)
|
||||
verseId = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
verse_tag = verseId[0]
|
||||
|
@ -191,13 +191,13 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
||||
else:
|
||||
log.debug(unicode(self.getVerse()[0]).split(u'\n'))
|
||||
value = unicode(self.getVerse()[0]).split(u'\n')[1]
|
||||
if len(value) == 0:
|
||||
if not value:
|
||||
lines = unicode(self.getVerse()[0]).split(u'\n')
|
||||
index = 2
|
||||
while index < len(lines) and len(value) == 0:
|
||||
while index < len(lines) and not value:
|
||||
value = lines[index]
|
||||
index += 1
|
||||
if len(value) == 0:
|
||||
if not value:
|
||||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.EditSongForm',
|
||||
'You need to type some text in to the verse.'))
|
||||
|
@ -57,7 +57,7 @@ class SongImportForm(OpenLPWizard):
|
||||
``plugin``
|
||||
The songs plugin.
|
||||
"""
|
||||
self.clipboard = plugin.formparent.clipboard
|
||||
self.clipboard = plugin.formParent.clipboard
|
||||
OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard',
|
||||
u':/wizards/wizard_importsong.bmp')
|
||||
|
||||
@ -129,6 +129,12 @@ class SongImportForm(OpenLPWizard):
|
||||
QtCore.QObject.connect(self.ccliRemoveButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onCCLIRemoveButtonClicked)
|
||||
QtCore.QObject.connect(self.dreamBeamAddButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onDreamBeamAddButtonClicked)
|
||||
QtCore.QObject.connect(self.dreamBeamRemoveButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onDreamBeamRemoveButtonClicked)
|
||||
QtCore.QObject.connect(self.songsOfFellowshipAddButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onSongsOfFellowshipAddButtonClicked)
|
||||
@ -165,6 +171,12 @@ class SongImportForm(OpenLPWizard):
|
||||
QtCore.QObject.connect(self.foilPresenterRemoveButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onFoilPresenterRemoveButtonClicked)
|
||||
QtCore.QObject.connect(self.powerSongAddButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onPowerSongAddButtonClicked)
|
||||
QtCore.QObject.connect(self.powerSongRemoveButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onPowerSongRemoveButtonClicked)
|
||||
|
||||
def addCustomPages(self):
|
||||
"""
|
||||
@ -201,6 +213,8 @@ class SongImportForm(OpenLPWizard):
|
||||
self.addFileSelectItem(u'generic', None, True)
|
||||
# CCLI File import
|
||||
self.addFileSelectItem(u'ccli')
|
||||
# DreamBeam
|
||||
self.addFileSelectItem(u'dreamBeam')
|
||||
# EasySlides
|
||||
self.addFileSelectItem(u'easySlides', single_select=True)
|
||||
# EasyWorship
|
||||
@ -209,6 +223,8 @@ class SongImportForm(OpenLPWizard):
|
||||
self.addFileSelectItem(u'foilPresenter')
|
||||
# Open Song
|
||||
self.addFileSelectItem(u'openSong', u'OpenSong')
|
||||
# PowerSong
|
||||
self.addFileSelectItem(u'powerSong')
|
||||
# SongBeamer
|
||||
self.addFileSelectItem(u'songBeamer')
|
||||
# Song Show Plus
|
||||
@ -247,6 +263,8 @@ class SongImportForm(OpenLPWizard):
|
||||
translate('SongsPlugin.ImportWizardForm',
|
||||
'Generic Document/Presentation'))
|
||||
self.formatComboBox.setItemText(SongFormat.CCLI, WizardStrings.CCLI)
|
||||
self.formatComboBox.setItemText(
|
||||
SongFormat.DreamBeam, WizardStrings.DB)
|
||||
self.formatComboBox.setItemText(
|
||||
SongFormat.EasySlides, WizardStrings.ES)
|
||||
self.formatComboBox.setItemText(
|
||||
@ -254,6 +272,8 @@ class SongImportForm(OpenLPWizard):
|
||||
self.formatComboBox.setItemText(
|
||||
SongFormat.FoilPresenter, WizardStrings.FP)
|
||||
self.formatComboBox.setItemText(SongFormat.OpenSong, WizardStrings.OS)
|
||||
self.formatComboBox.setItemText(
|
||||
SongFormat.PowerSong, WizardStrings.PS)
|
||||
self.formatComboBox.setItemText(
|
||||
SongFormat.SongBeamer, WizardStrings.SB)
|
||||
self.formatComboBox.setItemText(
|
||||
@ -291,6 +311,14 @@ class SongImportForm(OpenLPWizard):
|
||||
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||
self.ccliRemoveButton.setText(
|
||||
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
||||
self.dreamBeamAddButton.setText(
|
||||
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||
self.dreamBeamRemoveButton.setText(
|
||||
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
||||
self.powerSongAddButton.setText(
|
||||
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||
self.powerSongRemoveButton.setText(
|
||||
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
||||
self.songsOfFellowshipAddButton.setText(
|
||||
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||
self.songsOfFellowshipRemoveButton.setText(
|
||||
@ -397,6 +425,18 @@ class SongImportForm(OpenLPWizard):
|
||||
WizardStrings.YouSpecifyFile % WizardStrings.CCLI)
|
||||
self.ccliAddButton.setFocus()
|
||||
return False
|
||||
elif source_format == SongFormat.DreamBeam:
|
||||
if self.dreamBeamFileListWidget.count() == 0:
|
||||
critical_error_message_box(UiStrings().NFSp,
|
||||
WizardStrings.YouSpecifyFile % WizardStrings.DB)
|
||||
self.dreamBeamAddButton.setFocus()
|
||||
return False
|
||||
elif source_format == SongFormat.PowerSong:
|
||||
if self.powerSongFileListWidget.count() == 0:
|
||||
critical_error_message_box(UiStrings().NFSp,
|
||||
WizardStrings.YouSpecifyFile % WizardStrings.PS)
|
||||
self.powerSongAddButton.setFocus()
|
||||
return False
|
||||
elif source_format == SongFormat.SongsOfFellowship:
|
||||
if self.songsOfFellowshipFileListWidget.count() == 0:
|
||||
critical_error_message_box(UiStrings().NFSp,
|
||||
@ -433,7 +473,7 @@ class SongImportForm(OpenLPWizard):
|
||||
if self.songShowPlusFileListWidget.count() == 0:
|
||||
critical_error_message_box(UiStrings().NFSp,
|
||||
WizardStrings.YouSpecifyFile % WizardStrings.SSP)
|
||||
self.wordsOfWorshipAddButton.setFocus()
|
||||
self.songShowPlusAddButton.setFocus()
|
||||
return False
|
||||
elif source_format == SongFormat.FoilPresenter:
|
||||
if self.foilPresenterFileListWidget.count() == 0:
|
||||
@ -564,6 +604,38 @@ class SongImportForm(OpenLPWizard):
|
||||
"""
|
||||
self.removeSelectedItems(self.ccliFileListWidget)
|
||||
|
||||
def onDreamBeamAddButtonClicked(self):
|
||||
"""
|
||||
Get DreamBeam song database files
|
||||
"""
|
||||
self.getFiles(WizardStrings.OpenTypeFile % WizardStrings.DB,
|
||||
self.dreamBeamFileListWidget, u'%s (*.xml)'
|
||||
% translate('SongsPlugin.ImportWizardForm',
|
||||
'DreamBeam Song Files')
|
||||
)
|
||||
|
||||
def onDreamBeamRemoveButtonClicked(self):
|
||||
"""
|
||||
Remove selected DreamBeam files from the import list
|
||||
"""
|
||||
self.removeSelectedItems(self.dreamBeamFileListWidget)
|
||||
|
||||
def onPowerSongAddButtonClicked(self):
|
||||
"""
|
||||
Get PowerSong song database files
|
||||
"""
|
||||
self.getFiles(WizardStrings.OpenTypeFile % WizardStrings.PS,
|
||||
self.powerSongFileListWidget, u'%s (*.song)'
|
||||
% translate('SongsPlugin.ImportWizardForm',
|
||||
'PowerSong 1.0 Song Files')
|
||||
)
|
||||
|
||||
def onPowerSongRemoveButtonClicked(self):
|
||||
"""
|
||||
Remove selected PowerSong files from the import list
|
||||
"""
|
||||
self.removeSelectedItems(self.powerSongFileListWidget)
|
||||
|
||||
def onSongsOfFellowshipAddButtonClicked(self):
|
||||
"""
|
||||
Get Songs of Fellowship song database files
|
||||
@ -680,6 +752,8 @@ class SongImportForm(OpenLPWizard):
|
||||
self.openSongFileListWidget.clear()
|
||||
self.wordsOfWorshipFileListWidget.clear()
|
||||
self.ccliFileListWidget.clear()
|
||||
self.dreamBeamFileListWidget.clear()
|
||||
self.powerSongFileListWidget.clear()
|
||||
self.songsOfFellowshipFileListWidget.clear()
|
||||
self.genericFileListWidget.clear()
|
||||
self.easySlidesFilenameEdit.setText(u'')
|
||||
@ -741,6 +815,18 @@ class SongImportForm(OpenLPWizard):
|
||||
importer = self.plugin.importSongs(SongFormat.CCLI,
|
||||
filenames=self.getListOfFiles(self.ccliFileListWidget)
|
||||
)
|
||||
elif source_format == SongFormat.DreamBeam:
|
||||
# Import DreamBeam songs
|
||||
importer = self.plugin.importSongs(SongFormat.DreamBeam,
|
||||
filenames=self.getListOfFiles(
|
||||
self.dreamBeamFileListWidget)
|
||||
)
|
||||
elif source_format == SongFormat.PowerSong:
|
||||
# Import PowerSong songs
|
||||
importer = self.plugin.importSongs(SongFormat.PowerSong,
|
||||
filenames=self.getListOfFiles(
|
||||
self.powerSongFileListWidget)
|
||||
)
|
||||
elif source_format == SongFormat.SongsOfFellowship:
|
||||
# Import a Songs of Fellowship RTF file
|
||||
importer = self.plugin.importSongs(SongFormat.SongsOfFellowship,
|
||||
|
@ -108,7 +108,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
item_id = self._getCurrentItemId(list_widget)
|
||||
if item_id != -1:
|
||||
item = self.manager.get_object(item_class, item_id)
|
||||
if item and len(item.songs) == 0:
|
||||
if item and not item.songs:
|
||||
if critical_error_message_box(dlg_title, del_text, self,
|
||||
True) == QtGui.QMessageBox.Yes:
|
||||
self.manager.delete_object(item_class, item.id)
|
||||
@ -191,7 +191,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
||||
``edit``
|
||||
If we edit an item, this should be *True*.
|
||||
"""
|
||||
if len(objects) > 0:
|
||||
if objects:
|
||||
# If we edit an existing object, we need to make sure that we do
|
||||
# not return False when nothing has changed.
|
||||
if edit:
|
||||
|
@ -316,7 +316,7 @@ def clean_song(manager, song):
|
||||
verse_type,
|
||||
verse[0][u'label'],
|
||||
verse[1],
|
||||
verse[0][u'lang'] if verse[0].has_key(u'lang') else None
|
||||
verse[0].get(u'lang')
|
||||
)
|
||||
compare_order.append((u'%s%s' % (verse_type, verse[0][u'label'])
|
||||
).upper())
|
||||
|
@ -185,7 +185,7 @@ class CCLIFileImport(SongImport):
|
||||
check_first_verse_line = False
|
||||
field_list = song_fields.split(u'/t')
|
||||
words_list = song_words.split(u'/t')
|
||||
for counter in range(0, len(field_list)):
|
||||
for counter in range(len(field_list)):
|
||||
if field_list[counter].startswith(u'Ver'):
|
||||
verse_type = VerseType.Tags[VerseType.Verse]
|
||||
elif field_list[counter].startswith(u'Ch'):
|
||||
@ -211,7 +211,7 @@ class CCLIFileImport(SongImport):
|
||||
elif verse_lines[0].startswith(u'('):
|
||||
verse_type = VerseType.Tags[VerseType.Other]
|
||||
verse_text = verse_lines[1]
|
||||
if len(verse_text) > 0:
|
||||
if verse_text:
|
||||
self.addVerse(verse_text, verse_type)
|
||||
check_first_verse_line = False
|
||||
# Handle multiple authors
|
||||
|
157
openlp/plugins/songs/lib/dreambeamimport.py
Normal file
157
openlp/plugins/songs/lib/dreambeamimport.py
Normal file
@ -0,0 +1,157 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
|
||||
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
|
||||
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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:`dreambeamimport` module provides the functionality for importing
|
||||
DreamBeam songs into the OpenLP database.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from lxml import etree, objectify
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.plugins.songs.lib.songimport import SongImport
|
||||
from openlp.plugins.songs.lib.ui import SongStrings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class DreamBeamImport(SongImport):
|
||||
"""
|
||||
The :class:`DreamBeamImport` class provides the ability to import song files from
|
||||
DreamBeam.
|
||||
|
||||
An example of DreamBeam xml mark-up::
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<DreamSong xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<WordWrap>false</WordWrap>
|
||||
<Version>0.80</Version>
|
||||
<Title>Amazing Grace</Title>
|
||||
<Author>John Newton</Author>
|
||||
<Collection />
|
||||
<Number />
|
||||
<Notes />
|
||||
<KeyRangeLow>F</KeyRangeLow>
|
||||
<KeyRangeHigh>G</KeyRangeHigh>
|
||||
<MinorKey>false</MinorKey>
|
||||
<DualLanguage>false</DualLanguage>
|
||||
<SongLyrics>
|
||||
<LyricsItem Type="Verse" Number="1">Amazing Grace, how sweet the sound,
|
||||
That saved a wretch like me.
|
||||
I once was lost but now am found,
|
||||
Was blind, but now, I see.</LyricsItem>
|
||||
<LyricsItem Type="Verse" Number="2">T’was Grace that taught my heart to fear.
|
||||
And Grace, my fears relieved.
|
||||
How precious did that Grace appear…
|
||||
the hour I first believed.</LyricsItem>
|
||||
</SongLyrics>
|
||||
<Sequence>
|
||||
<LyricsSequenceItem Type="Verse" Number="1" />
|
||||
<LyricsSequenceItem Type="Verse" Number="2" />
|
||||
</Sequence>
|
||||
<ShowRectangles>false</ShowRectangles>
|
||||
</DreamSong>
|
||||
|
||||
Valid extensions for a DreamBeam song file are:
|
||||
|
||||
* \*.xml
|
||||
"""
|
||||
|
||||
def doImport(self):
|
||||
"""
|
||||
Receive a single file or a list of files to import.
|
||||
"""
|
||||
if isinstance(self.importSource, list):
|
||||
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||
for file in self.importSource:
|
||||
if self.stopImportFlag:
|
||||
return
|
||||
self.setDefaults()
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
try:
|
||||
parsed_file = etree.parse(open(file, u'r'), parser)
|
||||
except etree.XMLSyntaxError:
|
||||
log.exception(u'XML syntax error in file %s' % file)
|
||||
self.logError(file, SongStrings.XMLSyntaxError)
|
||||
continue
|
||||
xml = unicode(etree.tostring(parsed_file))
|
||||
song_xml = objectify.fromstring(xml)
|
||||
if song_xml.tag != u'DreamSong':
|
||||
self.logError(file, unicode(
|
||||
translate('SongsPlugin.DreamBeamImport',
|
||||
('Invalid DreamBeam song file. Missing '
|
||||
'DreamSong tag.'))))
|
||||
continue
|
||||
if hasattr(song_xml, u'Version'):
|
||||
self.version = float(song_xml.Version.text)
|
||||
else:
|
||||
self.version = 0
|
||||
# Version numbers found in DreamBeam Source /FileTypes/Song.cs
|
||||
if self.version >= 0.5:
|
||||
if hasattr(song_xml, u'Title'):
|
||||
self.title = unicode(song_xml.Title.text)
|
||||
if hasattr(song_xml, u'Author'):
|
||||
author_copyright = song_xml.Author.text
|
||||
if hasattr(song_xml, u'SongLyrics'):
|
||||
for lyrics_item in song_xml.SongLyrics.iterchildren():
|
||||
verse_type = lyrics_item.get(u'Type')
|
||||
verse_number = lyrics_item.get(u'Number')
|
||||
verse_text = unicode(lyrics_item.text)
|
||||
self.addVerse(verse_text,
|
||||
(u'%s%s' % (verse_type[:1], verse_number)))
|
||||
if hasattr(song_xml, u'Collection'):
|
||||
self.songBookName = unicode(song_xml.Collection.text)
|
||||
if hasattr(song_xml, u'Number'):
|
||||
self.songNumber = unicode(song_xml.Number.text)
|
||||
if hasattr(song_xml, u'Sequence'):
|
||||
for LyricsSequenceItem in (
|
||||
song_xml.Sequence.iterchildren()):
|
||||
self.verseOrderList.append(
|
||||
"%s%s" % (LyricsSequenceItem.get(u'Type')[:1],
|
||||
LyricsSequenceItem.get(u'Number')))
|
||||
if hasattr(song_xml, u'Notes'):
|
||||
self.comments = unicode(song_xml.Notes.text)
|
||||
else:
|
||||
if hasattr(song_xml.Text0, u'Text'):
|
||||
self.title = unicode(song_xml.Text0.Text.text)
|
||||
if hasattr(song_xml.Text1, u'Text'):
|
||||
self.lyrics = unicode(song_xml.Text1.Text.text)
|
||||
for verse in self.lyrics.split(u'\n\n\n'):
|
||||
self.addVerse(verse)
|
||||
if hasattr(song_xml.Text2, u'Text'):
|
||||
author_copyright = song_xml.Text2.Text.text
|
||||
if author_copyright:
|
||||
author_copyright = unicode(author_copyright)
|
||||
if author_copyright.find(
|
||||
unicode(SongStrings.CopyrightSymbol)) >= 0:
|
||||
self.addCopyright(author_copyright)
|
||||
else:
|
||||
self.parseAuthor(author_copyright)
|
||||
if not self.finish():
|
||||
self.logError(file)
|
@ -162,15 +162,12 @@ class EasySlidesImport(SongImport):
|
||||
separatorlines = 0
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if len(line) == 0:
|
||||
if not line:
|
||||
continue
|
||||
elif line[1:7] == u'region':
|
||||
# this is region separator, probably [region 2]
|
||||
region = self._extractRegion(line)
|
||||
if regionlines.has_key(region):
|
||||
regionlines[region] = regionlines[region] + 1
|
||||
else:
|
||||
regionlines[region] = 1
|
||||
regionlines[region] = 1 + regionlines.get(region, 0)
|
||||
elif line[0] == u'[':
|
||||
separatorlines = separatorlines + 1
|
||||
# if the song has separators
|
||||
@ -206,7 +203,7 @@ class EasySlidesImport(SongImport):
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if len(line) == 0:
|
||||
if not line:
|
||||
if separators:
|
||||
# separators are used, so empty line means slide break
|
||||
# inside verse
|
||||
@ -215,15 +212,11 @@ class EasySlidesImport(SongImport):
|
||||
else:
|
||||
# separators are not used, so empty line starts a new verse
|
||||
vt = u'V'
|
||||
if verses[reg].has_key(vt):
|
||||
vn = len(verses[reg][vt].keys())+1
|
||||
else:
|
||||
vn = u'1'
|
||||
vn = len(verses[reg].get(vt, {})) + 1
|
||||
inst = 1
|
||||
elif line[0:7] == u'[region':
|
||||
reg = self._extractRegion(line)
|
||||
if not verses.has_key(reg):
|
||||
verses[reg] = {}
|
||||
verses.setdefault(reg, {})
|
||||
if not regionsInVerses:
|
||||
vt = u'V'
|
||||
vn = u'1'
|
||||
@ -238,28 +231,19 @@ class EasySlidesImport(SongImport):
|
||||
if match:
|
||||
marker = match.group(1).strip()
|
||||
vn = match.group(2)
|
||||
if len(marker) == 0:
|
||||
vt = u'V'
|
||||
elif MarkTypes.has_key(marker):
|
||||
vt = MarkTypes[marker]
|
||||
else:
|
||||
vt = u'O'
|
||||
vt = MarkTypes.get(marker, u'O') if marker else u'V'
|
||||
if regionsInVerses:
|
||||
region = defaultregion
|
||||
inst = 1
|
||||
if self._listHas(verses, [reg, vt, vn, inst]):
|
||||
inst = len(verses[reg][vt][vn])+1
|
||||
inst = len(verses[reg][vt][vn]) + 1
|
||||
else:
|
||||
if not [reg, vt, vn, inst] in our_verse_order:
|
||||
our_verse_order.append([reg, vt, vn, inst])
|
||||
if not verses[reg].has_key(vt):
|
||||
verses[reg][vt] = {}
|
||||
if not verses[reg][vt].has_key(vn):
|
||||
verses[reg][vt][vn] = {}
|
||||
if not verses[reg][vt][vn].has_key(inst):
|
||||
verses[reg][vt][vn][inst] = []
|
||||
words = self.tidyText(line)
|
||||
verses[reg][vt][vn][inst].append(words)
|
||||
verses[reg].setdefault(vt, {})
|
||||
verses[reg][vt].setdefault(vn, {})
|
||||
verses[reg][vt][vn].setdefault(inst, [])
|
||||
verses[reg][vt][vn][inst].append(self.tidyText(line))
|
||||
# done parsing
|
||||
|
||||
versetags = []
|
||||
@ -286,11 +270,11 @@ class EasySlidesImport(SongImport):
|
||||
try:
|
||||
order = unicode(song.Sequence).strip().split(u',')
|
||||
for tag in order:
|
||||
if len(tag) == 0:
|
||||
if not tag:
|
||||
continue
|
||||
elif tag[0].isdigit():
|
||||
tag = u'V' + tag
|
||||
elif SeqTypes.has_key(tag.lower()):
|
||||
elif tag.lower() in SeqTypes:
|
||||
tag = SeqTypes[tag.lower()]
|
||||
else:
|
||||
continue
|
||||
@ -307,9 +291,7 @@ class EasySlidesImport(SongImport):
|
||||
|
||||
def _listHas(self, lst, subitems):
|
||||
for subitem in subitems:
|
||||
if isinstance(lst, dict) and lst.has_key(subitem):
|
||||
lst = lst[subitem]
|
||||
elif isinstance(lst, list) and subitem in lst:
|
||||
if subitem in lst:
|
||||
lst = lst[subitem]
|
||||
else:
|
||||
return False
|
||||
|
@ -62,15 +62,15 @@ def strip_rtf(blob, encoding):
|
||||
if control:
|
||||
# for delimiters, set control to False
|
||||
if c == '{':
|
||||
if len(control_word) > 0:
|
||||
if control_word:
|
||||
depth += 1
|
||||
control = False
|
||||
elif c == '}':
|
||||
if len(control_word) > 0:
|
||||
if control_word:
|
||||
depth -= 1
|
||||
control = False
|
||||
elif c == '\\':
|
||||
new_control = (len(control_word) > 0)
|
||||
new_control = bool(control_word)
|
||||
control = False
|
||||
elif c.isspace():
|
||||
control = False
|
||||
@ -79,7 +79,7 @@ def strip_rtf(blob, encoding):
|
||||
if len(control_word) == 3 and control_word[0] == '\'':
|
||||
control = False
|
||||
if not control:
|
||||
if len(control_word) == 0:
|
||||
if not control_word:
|
||||
if c == '{' or c == '}' or c == '\\':
|
||||
clear_text.append(c)
|
||||
else:
|
||||
@ -360,7 +360,7 @@ class EasyWorshipSongImport(SongImport):
|
||||
field_desc = self.fieldDescs[field_desc_index]
|
||||
# Return None in case of 'blank' entries
|
||||
if isinstance(field, str):
|
||||
if len(field.rstrip('\0')) == 0:
|
||||
if not field.rstrip('\0'):
|
||||
return None
|
||||
elif field == 0:
|
||||
return None
|
||||
|
@ -413,7 +413,7 @@ class FoilPresenter(object):
|
||||
temp_verse_order_backup = []
|
||||
temp_sortnr_backup = 1
|
||||
temp_sortnr_liste = []
|
||||
versenumber = {
|
||||
verse_count = {
|
||||
VerseType.Tags[VerseType.Verse]: 1,
|
||||
VerseType.Tags[VerseType.Chorus]: 1,
|
||||
VerseType.Tags[VerseType.Bridge]: 1,
|
||||
@ -463,8 +463,8 @@ class FoilPresenter(object):
|
||||
verse_number = re.compile(u'[a-zA-Z.+-_ ]*').sub(u'', verse_name)
|
||||
# Foilpresenter allows e. g. "C", but we need "C1".
|
||||
if not verse_number:
|
||||
verse_number = unicode(versenumber[verse_type])
|
||||
versenumber[verse_type] += 1
|
||||
verse_number = unicode(verse_count[verse_type])
|
||||
verse_count[verse_type] += 1
|
||||
else:
|
||||
# test if foilpresenter have the same versenumber two times with
|
||||
# different parts raise the verse number
|
||||
@ -508,13 +508,13 @@ class FoilPresenter(object):
|
||||
song.song_number = u''
|
||||
try:
|
||||
for bucheintrag in foilpresenterfolie.buch.bucheintrag:
|
||||
bookname = self._child(bucheintrag.name)
|
||||
if bookname:
|
||||
book_name = self._child(bucheintrag.name)
|
||||
if book_name:
|
||||
book = self.manager.get_object_filtered(Book,
|
||||
Book.name == bookname)
|
||||
Book.name == book_name)
|
||||
if book is None:
|
||||
# We need to create a book, because it does not exist.
|
||||
book = Book.populate(name=bookname, publisher=u'')
|
||||
book = Book.populate(name=book_name, publisher=u'')
|
||||
self.manager.save_object(book)
|
||||
song.song_book_id = book.id
|
||||
try:
|
||||
@ -537,12 +537,12 @@ class FoilPresenter(object):
|
||||
``song``
|
||||
The song object.
|
||||
"""
|
||||
for titelstring in foilpresenterfolie.titel.titelstring:
|
||||
for title_string in foilpresenterfolie.titel.titelstring:
|
||||
if not song.title:
|
||||
song.title = self._child(titelstring)
|
||||
song.title = self._child(title_string)
|
||||
song.alternate_title = u''
|
||||
else:
|
||||
song.alternate_title = self._child(titelstring)
|
||||
song.alternate_title = self._child(title_string)
|
||||
|
||||
def _process_topics(self, foilpresenterfolie, song):
|
||||
"""
|
||||
@ -556,13 +556,13 @@ class FoilPresenter(object):
|
||||
"""
|
||||
try:
|
||||
for name in foilpresenterfolie.kategorien.name:
|
||||
topictext = self._child(name)
|
||||
if topictext:
|
||||
topic_text = self._child(name)
|
||||
if topic_text:
|
||||
topic = self.manager.get_object_filtered(Topic,
|
||||
Topic.name == topictext)
|
||||
Topic.name == topic_text)
|
||||
if topic is None:
|
||||
# We need to create a topic, because it does not exist.
|
||||
topic = Topic.populate(name=topictext)
|
||||
topic = Topic.populate(name=topic_text)
|
||||
self.manager.save_object(topic)
|
||||
song.topics.append(topic)
|
||||
except AttributeError:
|
||||
|
@ -35,6 +35,8 @@ from olpimport import OpenLPSongImport
|
||||
from openlyricsimport import OpenLyricsImport
|
||||
from wowimport import WowImport
|
||||
from cclifileimport import CCLIFileImport
|
||||
from dreambeamimport import DreamBeamImport
|
||||
from powersongimport import PowerSongImport
|
||||
from ewimport import EasyWorshipSongImport
|
||||
from songbeamerimport import SongBeamerImport
|
||||
from songshowplusimport import SongShowPlusImport
|
||||
@ -73,20 +75,22 @@ class SongFormat(object):
|
||||
OpenLP1 = 2
|
||||
Generic = 3
|
||||
CCLI = 4
|
||||
EasySlides = 5
|
||||
EasyWorship = 6
|
||||
FoilPresenter = 7
|
||||
OpenSong = 8
|
||||
SongBeamer = 9
|
||||
SongShowPlus = 10
|
||||
SongsOfFellowship = 11
|
||||
WordsOfWorship = 12
|
||||
#CSV = 13
|
||||
DreamBeam = 5
|
||||
EasySlides = 6
|
||||
EasyWorship = 7
|
||||
FoilPresenter = 8
|
||||
OpenSong = 9
|
||||
PowerSong = 10
|
||||
SongBeamer = 11
|
||||
SongShowPlus = 12
|
||||
SongsOfFellowship = 13
|
||||
WordsOfWorship = 14
|
||||
#CSV = 15
|
||||
|
||||
@staticmethod
|
||||
def get_class(format):
|
||||
"""
|
||||
Return the appropriate imeplementation class.
|
||||
Return the appropriate implementation class.
|
||||
|
||||
``format``
|
||||
The song format.
|
||||
@ -107,6 +111,10 @@ class SongFormat(object):
|
||||
return OooImport
|
||||
elif format == SongFormat.CCLI:
|
||||
return CCLIFileImport
|
||||
elif format == SongFormat.DreamBeam:
|
||||
return DreamBeamImport
|
||||
elif format == SongFormat.PowerSong:
|
||||
return PowerSongImport
|
||||
elif format == SongFormat.EasySlides:
|
||||
return EasySlidesImport
|
||||
elif format == SongFormat.EasyWorship:
|
||||
@ -130,10 +138,12 @@ class SongFormat(object):
|
||||
SongFormat.OpenLP1,
|
||||
SongFormat.Generic,
|
||||
SongFormat.CCLI,
|
||||
SongFormat.DreamBeam,
|
||||
SongFormat.EasySlides,
|
||||
SongFormat.EasyWorship,
|
||||
SongFormat.FoilPresenter,
|
||||
SongFormat.OpenSong,
|
||||
SongFormat.PowerSong,
|
||||
SongFormat.SongBeamer,
|
||||
SongFormat.SongShowPlus,
|
||||
SongFormat.SongsOfFellowship,
|
||||
|
@ -68,7 +68,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'songs/song'
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
self.editSongForm = EditSongForm(self, self.plugin.formparent,
|
||||
self.editSongForm = EditSongForm(self, self.plugin.formParent,
|
||||
self.plugin.manager)
|
||||
self.openLyrics = OpenLyrics(self.plugin.manager)
|
||||
self.singleServiceItem = False
|
||||
@ -295,9 +295,8 @@ class SongMediaItem(MediaManagerItem):
|
||||
log.debug(u'display results Book')
|
||||
self.listView.clear()
|
||||
for book in searchresults:
|
||||
songs = sorted(book.songs, key=lambda song: int(
|
||||
re.sub(r'[^0-9]', u' ', song.song_number).partition(' ')[0])
|
||||
if len(re.sub(r'[^\w]', ' ', song.song_number)) else 0)
|
||||
songs = sorted(book.songs, key=lambda song:
|
||||
int(re.match(r'[0-9]+', u'0' + song.song_number).group()))
|
||||
for song in songs:
|
||||
# Do not display temporary songs
|
||||
if song.temporary:
|
||||
@ -331,7 +330,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
search_length = 3
|
||||
if len(text) > search_length:
|
||||
self.onSearchTextButtonClicked()
|
||||
elif len(text) == 0:
|
||||
elif not text:
|
||||
self.onClearTextButtonClick()
|
||||
|
||||
def onImportClick(self):
|
||||
@ -409,7 +408,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
|
||||
return
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.plugin.formparent.displayProgressBar(len(items))
|
||||
self.plugin.formParent.displayProgressBar(len(items))
|
||||
for item in items:
|
||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
media_files = self.plugin.manager.get_all_objects(MediaFile,
|
||||
@ -428,8 +427,8 @@ class SongMediaItem(MediaManagerItem):
|
||||
except OSError:
|
||||
log.exception(u'Could not remove directory: %s', save_path)
|
||||
self.plugin.manager.delete_object(Song, item_id)
|
||||
self.plugin.formparent.incrementProgressBar()
|
||||
self.plugin.formparent.finishedProgressBar()
|
||||
self.plugin.formParent.incrementProgressBar()
|
||||
self.plugin.formParent.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.onSearchTextButtonClicked()
|
||||
|
||||
@ -491,7 +490,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
else:
|
||||
# Loop through the verse list and expand the song accordingly.
|
||||
for order in song.verse_order.lower().split():
|
||||
if len(order) == 0:
|
||||
if not order:
|
||||
break
|
||||
for verse in verseList:
|
||||
if verse[0][u'type'][0].lower() == order[0] and \
|
||||
@ -530,7 +529,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
u'authors': u', '.join(author_list)}
|
||||
service_item.xml_version = self.openLyrics.song_to_xml(song)
|
||||
# Add the audio file to the service item.
|
||||
if len(song.media_files) > 0:
|
||||
if song.media_files:
|
||||
service_item.add_capability(ItemCapabilities.HasBackgroundAudio)
|
||||
service_item.background_audio = \
|
||||
[m.file_name for m in song.media_files]
|
||||
@ -575,12 +574,12 @@ class SongMediaItem(MediaManagerItem):
|
||||
editId = song.id
|
||||
break
|
||||
# If there's any backing tracks, copy them over.
|
||||
if len(item.background_audio) > 0:
|
||||
if item.background_audio:
|
||||
self._updateBackgroundAudio(song, item)
|
||||
if add_song and self.addSongFromService:
|
||||
song = self.openLyrics.xml_to_song(item.xml_version)
|
||||
# If there's any backing tracks, copy them over.
|
||||
if len(item.background_audio) > 0:
|
||||
if item.background_audio:
|
||||
self._updateBackgroundAudio(song, item)
|
||||
editId = song.id
|
||||
self.onSearchTextButtonClicked()
|
||||
@ -588,7 +587,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
# Make sure we temporary import formatting tags.
|
||||
song = self.openLyrics.xml_to_song(item.xml_version, True)
|
||||
# If there's any backing tracks, copy them over.
|
||||
if len(item.background_audio) > 0:
|
||||
if item.background_audio:
|
||||
self._updateBackgroundAudio(song, item)
|
||||
editId = song.id
|
||||
temporary = True
|
||||
|
@ -60,7 +60,7 @@ class OpenLP1SongImport(SongImport):
|
||||
"""
|
||||
SongImport.__init__(self, manager, **kwargs)
|
||||
self.availableThemes = \
|
||||
kwargs[u'plugin'].formparent.themeManagerContents.getThemes()
|
||||
kwargs[u'plugin'].formParent.themeManagerContents.getThemes()
|
||||
|
||||
def doImport(self):
|
||||
"""
|
||||
@ -122,8 +122,7 @@ class OpenLP1SongImport(SongImport):
|
||||
cursor.execute(
|
||||
u'SELECT settingsid FROM songs WHERE songid = %s' % song_id)
|
||||
theme_id = cursor.fetchone()[0]
|
||||
if themes.has_key(theme_id):
|
||||
self.themeName = themes[theme_id]
|
||||
self.themeName = themes.get(theme_id, u'')
|
||||
verses = lyrics.split(u'\n\n')
|
||||
for verse in verses:
|
||||
if verse.strip():
|
||||
@ -191,7 +190,7 @@ class OpenLP1SongImport(SongImport):
|
||||
# Detect charset by songs.
|
||||
cursor.execute(u'SELECT name FROM sqlite_master '
|
||||
u'WHERE type = \'table\' AND name = \'tracks\'')
|
||||
if len(cursor.fetchall()) > 0:
|
||||
if cursor.fetchall():
|
||||
cursor.execute(u'SELECT fulltrackname FROM tracks')
|
||||
tracks = cursor.fetchall()
|
||||
for track in tracks:
|
||||
|
@ -174,7 +174,7 @@ class OpenSongImport(SongImport):
|
||||
if semicolon >= 0:
|
||||
this_line = this_line[:semicolon]
|
||||
this_line = this_line.strip()
|
||||
if not len(this_line):
|
||||
if not this_line:
|
||||
continue
|
||||
# skip guitar chords and page and column breaks
|
||||
if this_line.startswith(u'.') or this_line.startswith(u'---') \
|
||||
@ -197,15 +197,12 @@ class OpenSongImport(SongImport):
|
||||
# the verse tag
|
||||
verse_tag = content
|
||||
verse_num = u'1'
|
||||
if len(verse_tag) == 0:
|
||||
verse_index = 0
|
||||
else:
|
||||
verse_index = VerseType.from_loose_input(verse_tag)
|
||||
verse_index = VerseType.from_loose_input(verse_tag) \
|
||||
if verse_tag else 0
|
||||
verse_tag = VerseType.Tags[verse_index]
|
||||
inst = 1
|
||||
if [verse_tag, verse_num, inst] in our_verse_order \
|
||||
and verses.has_key(verse_tag) \
|
||||
and verses[verse_tag].has_key(verse_num):
|
||||
and verse_num in verses.get(verse_tag, {}):
|
||||
inst = len(verses[verse_tag][verse_num]) + 1
|
||||
continue
|
||||
# number at start of line.. it's verse number
|
||||
@ -213,11 +210,9 @@ class OpenSongImport(SongImport):
|
||||
verse_num = this_line[0]
|
||||
this_line = this_line[1:].strip()
|
||||
our_verse_order.append([verse_tag, verse_num, inst])
|
||||
if not verses.has_key(verse_tag):
|
||||
verses[verse_tag] = {}
|
||||
if not verses[verse_tag].has_key(verse_num):
|
||||
verses[verse_tag][verse_num] = {}
|
||||
if not verses[verse_tag][verse_num].has_key(inst):
|
||||
verses.setdefault(verse_tag, {})
|
||||
verses[verse_tag].setdefault(verse_num, {})
|
||||
if inst not in verses[verse_tag][verse_num]:
|
||||
verses[verse_tag][verse_num][inst] = []
|
||||
our_verse_order.append([verse_tag, verse_num, inst])
|
||||
# Tidy text and remove the ____s from extended words
|
||||
@ -252,15 +247,14 @@ class OpenSongImport(SongImport):
|
||||
if match is not None:
|
||||
verse_tag = match.group(1)
|
||||
verse_num = match.group(2)
|
||||
if not len(verse_tag):
|
||||
if not verse_tag:
|
||||
verse_tag = VerseType.Tags[VerseType.Verse]
|
||||
else:
|
||||
# Assume it's no.1 if there are no digits
|
||||
verse_tag = verse_def
|
||||
verse_num = u'1'
|
||||
verse_def = u'%s%s' % (verse_tag, verse_num)
|
||||
if verses.has_key(verse_tag) and \
|
||||
verses[verse_tag].has_key(verse_num):
|
||||
if verse_num in verses.get(verse_tag, {}):
|
||||
self.verseOrderList.append(verse_def)
|
||||
else:
|
||||
log.info(u'Got order %s but not in verse tags, dropping'
|
||||
|
195
openlp/plugins/songs/lib/powersongimport.py
Normal file
195
openlp/plugins/songs/lib/powersongimport.py
Normal file
@ -0,0 +1,195 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2012 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
|
||||
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
|
||||
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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:`powersongimport` module provides the functionality for importing
|
||||
PowerSong songs into the OpenLP database.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.plugins.songs.lib.songimport import SongImport
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class PowerSongImport(SongImport):
|
||||
"""
|
||||
The :class:`PowerSongImport` class provides the ability to import song files
|
||||
from PowerSong.
|
||||
|
||||
**PowerSong 1.0 Song File Format:**
|
||||
|
||||
The file has a number of label-field (think key-value) pairs.
|
||||
|
||||
Label and Field strings:
|
||||
|
||||
* Every label and field is a variable length string preceded by an
|
||||
integer specifying it's byte length.
|
||||
* Integer is 32-bit but is encoded in 7-bit format to save space. Thus
|
||||
if length will fit in 7 bits (ie <= 127) it takes up only one byte.
|
||||
|
||||
Metadata fields:
|
||||
|
||||
* Every PowerSong file has a TITLE field.
|
||||
* There is zero or more AUTHOR fields.
|
||||
* There is always a COPYRIGHTLINE label, but its field may be empty.
|
||||
This field may also contain a CCLI number: e.g. "CCLI 176263".
|
||||
|
||||
Lyrics fields:
|
||||
|
||||
* Each verse is contained in a PART field.
|
||||
* Lines have Windows line endings ``CRLF`` (0x0d, 0x0a).
|
||||
* There is no concept of verse types.
|
||||
|
||||
Valid extensions for a PowerSong song file are:
|
||||
|
||||
* .song
|
||||
"""
|
||||
|
||||
def doImport(self):
|
||||
"""
|
||||
Receive a list of files to import.
|
||||
"""
|
||||
if not isinstance(self.importSource, list):
|
||||
self.logError(unicode(translate('SongsPlugin.PowerSongImport',
|
||||
'No files to import.')))
|
||||
return
|
||||
self.importWizard.progressBar.setMaximum(len(self.importSource))
|
||||
for file in self.importSource:
|
||||
if self.stopImportFlag:
|
||||
return
|
||||
self.setDefaults()
|
||||
parse_error = False
|
||||
with open(file, 'rb') as song_data:
|
||||
while True:
|
||||
try:
|
||||
label = self._readString(song_data)
|
||||
if not label:
|
||||
break
|
||||
field = self._readString(song_data)
|
||||
except ValueError:
|
||||
parse_error = True
|
||||
self.logError(file, unicode(
|
||||
translate('SongsPlugin.PowerSongImport',
|
||||
'Invalid PowerSong file. Unexpected byte value.')))
|
||||
break
|
||||
else:
|
||||
if label == u'TITLE':
|
||||
self.title = field.replace(u'\n', u' ')
|
||||
elif label == u'AUTHOR':
|
||||
self.parseAuthor(field)
|
||||
elif label == u'COPYRIGHTLINE':
|
||||
found_copyright = True
|
||||
self._parseCopyrightCCLI(field)
|
||||
elif label == u'PART':
|
||||
self.addVerse(field)
|
||||
if parse_error:
|
||||
continue
|
||||
# Check that file had TITLE field
|
||||
if not self.title:
|
||||
self.logError(file, unicode(
|
||||
translate('SongsPlugin.PowerSongImport',
|
||||
'Invalid PowerSong file. Missing "TITLE" header.')))
|
||||
continue
|
||||
# Check that file had COPYRIGHTLINE label
|
||||
if not found_copyright:
|
||||
self.logError(file, unicode(
|
||||
translate('SongsPlugin.PowerSongImport',
|
||||
'"%s" Invalid PowerSong file. Missing "COPYRIGHTLINE" '
|
||||
'header.' % self.title)))
|
||||
continue
|
||||
# Check that file had at least one verse
|
||||
if not self.verses:
|
||||
self.logError(file, unicode(
|
||||
translate('SongsPlugin.PowerSongImport',
|
||||
'"%s" Verses not found. Missing "PART" header.'
|
||||
% self.title)))
|
||||
continue
|
||||
if not self.finish():
|
||||
self.logError(file)
|
||||
|
||||
def _readString(self, file_object):
|
||||
"""
|
||||
Reads in next variable-length string.
|
||||
"""
|
||||
string_len = self._read7BitEncodedInteger(file_object)
|
||||
return unicode(file_object.read(string_len), u'utf-8', u'ignore')
|
||||
|
||||
def _read7BitEncodedInteger(self, file_object):
|
||||
"""
|
||||
Reads in a 32-bit integer in compressed 7-bit format.
|
||||
|
||||
Accomplished by reading the integer 7 bits at a time. The high bit
|
||||
of the byte when set means to continue reading more bytes.
|
||||
If the integer will fit in 7 bits (ie <= 127), it only takes up one
|
||||
byte. Otherwise, it may take up to 5 bytes.
|
||||
|
||||
Reference: .NET method System.IO.BinaryReader.Read7BitEncodedInt
|
||||
"""
|
||||
val = 0
|
||||
shift = 0
|
||||
i = 0
|
||||
while True:
|
||||
# Check for corrupted stream (since max 5 bytes per 32-bit integer)
|
||||
if i == 5:
|
||||
raise ValueError
|
||||
byte = self._readByte(file_object)
|
||||
# Strip high bit and shift left
|
||||
val += (byte & 0x7f) << shift
|
||||
shift += 7
|
||||
high_bit_set = byte & 0x80
|
||||
if not high_bit_set:
|
||||
break
|
||||
i += 1
|
||||
return val
|
||||
|
||||
def _readByte(self, file_object):
|
||||
"""
|
||||
Reads in next byte as an unsigned integer
|
||||
|
||||
Note: returns 0 at end of file.
|
||||
"""
|
||||
byte_str = file_object.read(1)
|
||||
# If read result is empty, then reached end of file
|
||||
if not byte_str:
|
||||
return 0
|
||||
else:
|
||||
return ord(byte_str)
|
||||
|
||||
def _parseCopyrightCCLI(self, field):
|
||||
"""
|
||||
Look for CCLI song number, and get copyright
|
||||
"""
|
||||
copyright, sep, ccli_no = field.rpartition(u'CCLI')
|
||||
if not sep:
|
||||
copyright = ccli_no
|
||||
ccli_no = u''
|
||||
if copyright:
|
||||
self.addCopyright(copyright.rstrip(u'\n').replace(u'\n', u' '))
|
||||
if ccli_no:
|
||||
ccli_no = ccli_no.strip(u' :')
|
||||
if ccli_no.isdigit():
|
||||
self.ccliNumber = ccli_no
|
@ -61,9 +61,9 @@ class SongImport(QtCore.QObject):
|
||||
"""
|
||||
self.manager = manager
|
||||
QtCore.QObject.__init__(self)
|
||||
if kwargs.has_key(u'filename'):
|
||||
if u'filename' in kwargs:
|
||||
self.importSource = kwargs[u'filename']
|
||||
elif kwargs.has_key(u'filenames'):
|
||||
elif u'filenames' in kwargs:
|
||||
self.importSource = kwargs[u'filenames']
|
||||
else:
|
||||
raise KeyError(u'Keyword arguments "filename[s]" not supplied.')
|
||||
@ -107,11 +107,11 @@ class SongImport(QtCore.QObject):
|
||||
|
||||
``filepath``
|
||||
This should be the file path if ``self.importSource`` is a list
|
||||
with different files. If it is not a list, but a single file (for
|
||||
with different files. If it is not a list, but a single file (for
|
||||
instance a database), then this should be the song's title.
|
||||
|
||||
``reason``
|
||||
The reason, why the import failed. The string should be as
|
||||
The reason why the import failed. The string should be as
|
||||
informative as possible.
|
||||
"""
|
||||
self.setDefaults()
|
||||
@ -273,7 +273,7 @@ class SongImport(QtCore.QObject):
|
||||
Author not checked here, if no author then "Author unknown" is
|
||||
automatically added
|
||||
"""
|
||||
if not self.title or not len(self.verses):
|
||||
if not self.title or not self.verses:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
@ -314,13 +314,10 @@ class SongImport(QtCore.QObject):
|
||||
verse_def = new_verse_def
|
||||
sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang)
|
||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||
if not len(self.verseOrderList) and \
|
||||
self.verseOrderListGeneratedUseful:
|
||||
if not self.verseOrderList and self.verseOrderListGeneratedUseful:
|
||||
self.verseOrderList = self.verseOrderListGenerated
|
||||
for i, current_verse_def in enumerate(self.verseOrderList):
|
||||
if verses_changed_to_other.has_key(current_verse_def):
|
||||
self.verseOrderList[i] = \
|
||||
verses_changed_to_other[current_verse_def]
|
||||
self.verseOrderList = map(lambda v: verses_changed_to_other.get(v, v),
|
||||
self.verseOrderList)
|
||||
song.verse_order = u' '.join(self.verseOrderList)
|
||||
song.copyright = self.copyright
|
||||
song.comments = self.comments
|
||||
|
@ -25,8 +25,8 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`wowimport` module provides the functionality for importing Words of
|
||||
Worship songs into the OpenLP database.
|
||||
The :mod:`songshowplusimport` module provides the functionality for importing
|
||||
SongShow Plus songs into the OpenLP database.
|
||||
"""
|
||||
import os
|
||||
import logging
|
||||
@ -204,7 +204,7 @@ class SongShowPlusImport(SongImport):
|
||||
elif verse_type == "pre-chorus":
|
||||
verse_tag = VerseType.Tags[VerseType.PreChorus]
|
||||
else:
|
||||
if not self.otherList.has_key(verse_name):
|
||||
if verse_name not in self.otherList:
|
||||
if ignore_unique:
|
||||
return None
|
||||
self.otherCount = self.otherCount + 1
|
||||
|
@ -75,6 +75,7 @@ def upgrade_1(session, metadata, tables):
|
||||
ForeignKeyConstraint([u'song_id'], [u'songs.id'],
|
||||
table=tables[u'media_files']).create()
|
||||
|
||||
|
||||
def upgrade_2(session, metadata, tables):
|
||||
"""
|
||||
Version 2 upgrade.
|
||||
@ -86,6 +87,7 @@ def upgrade_2(session, metadata, tables):
|
||||
Column(u'last_modified', types.DateTime(), default=func.now())\
|
||||
.create(table=tables[u'songs'])
|
||||
|
||||
|
||||
def upgrade_3(session, metadata, tables):
|
||||
"""
|
||||
Version 3 upgrade.
|
||||
|
@ -71,7 +71,7 @@ class WowImport(SongImport):
|
||||
* ``SOH`` (0x01) - Chorus
|
||||
* ``STX`` (0x02) - Bridge
|
||||
|
||||
Blocks are seperated by two bytes. The first byte is 0x01, and the
|
||||
Blocks are separated by two bytes. The first byte is 0x01, and the
|
||||
second byte is 0x80.
|
||||
|
||||
Lines:
|
||||
@ -126,7 +126,7 @@ class WowImport(SongImport):
|
||||
('Invalid Words of Worship song file. Missing '
|
||||
'"CSongDoc::CBlock" string.'))))
|
||||
continue
|
||||
# Seek to the beging of the first block
|
||||
# Seek to the beginning of the first block
|
||||
song_data.seek(82)
|
||||
for block in range(no_of_blocks):
|
||||
self.linesToRead = ord(song_data.read(4)[:1])
|
||||
@ -140,7 +140,7 @@ class WowImport(SongImport):
|
||||
block_text += self.lineText
|
||||
self.linesToRead -= 1
|
||||
block_type = BLOCK_TYPES[ord(song_data.read(4)[:1])]
|
||||
# Blocks are seperated by 2 bytes, skip them, but not if
|
||||
# Blocks are separated by 2 bytes, skip them, but not if
|
||||
# this is the last block!
|
||||
if block + 1 < no_of_blocks:
|
||||
song_data.seek(2, os.SEEK_CUR)
|
||||
|
@ -33,7 +33,7 @@ The basic XML for storing the lyrics in the song database looks like this::
|
||||
<song version="1.0">
|
||||
<lyrics>
|
||||
<verse type="c" label="1" lang="en">
|
||||
<![CDATA[Chorus virtual slide 1[---]Chorus virtual slide 2]]>
|
||||
<![CDATA[Chorus optional split 1[---]Chorus optional split 2]]>
|
||||
</verse>
|
||||
</lyrics>
|
||||
</song>
|
||||
@ -135,7 +135,7 @@ class SongXML(object):
|
||||
The returned list has the following format::
|
||||
|
||||
[[{'type': 'v', 'label': '1'},
|
||||
u"virtual slide 1[---]virtual slide 2"],
|
||||
u"optional slide split 1[---]optional slide split 2"],
|
||||
[{'lang': 'en', 'type': 'c', 'label': '1'}, u"English chorus"]]
|
||||
"""
|
||||
self.song_xml = None
|
||||
@ -317,9 +317,7 @@ class OpenLyrics(object):
|
||||
tags_element = None
|
||||
match = re.search(u'\{/?\w+\}', song.lyrics, re.UNICODE)
|
||||
if match:
|
||||
# Reset available tags.
|
||||
FormattingTags.reset_html_tags()
|
||||
# Named 'formatting' - 'format' is built-in fuction in Python.
|
||||
# Named 'format_' - 'format' is built-in fuction in Python.
|
||||
format_ = etree.SubElement(song_xml, u'format')
|
||||
tags_element = etree.SubElement(format_, u'tags')
|
||||
tags_element.set(u'application', u'OpenLP')
|
||||
@ -334,18 +332,59 @@ class OpenLyrics(object):
|
||||
self._add_text_to_element(u'verse', lyrics, None, verse_def)
|
||||
if u'lang' in verse[0]:
|
||||
verse_element.set(u'lang', verse[0][u'lang'])
|
||||
# Create a list with all "virtual" verses.
|
||||
virtual_verses = cgi.escape(verse[1])
|
||||
virtual_verses = virtual_verses.split(u'[---]')
|
||||
for index, virtual_verse in enumerate(virtual_verses):
|
||||
# Create a list with all "optional" verses.
|
||||
optional_verses = cgi.escape(verse[1])
|
||||
optional_verses = optional_verses.split(u'\n[---]\n')
|
||||
start_tags = u''
|
||||
end_tags = u''
|
||||
for index, optional_verse in enumerate(optional_verses):
|
||||
# Fix up missing end and start tags such as {r} or {/r}.
|
||||
optional_verse = start_tags + optional_verse
|
||||
start_tags, end_tags = self._get_missing_tags(optional_verse)
|
||||
optional_verse += end_tags
|
||||
# Add formatting tags to text
|
||||
lines_element = self._add_text_with_tags_to_lines(verse_element,
|
||||
virtual_verse, tags_element)
|
||||
optional_verse, tags_element)
|
||||
# Do not add the break attribute to the last lines element.
|
||||
if index < len(virtual_verses) - 1:
|
||||
if index < len(optional_verses) - 1:
|
||||
lines_element.set(u'break', u'optional')
|
||||
return self._extract_xml(song_xml)
|
||||
|
||||
def _get_missing_tags(self, text):
|
||||
"""
|
||||
Tests the given text for not closed formatting tags and returns a tuple
|
||||
consisting of two unicode strings::
|
||||
|
||||
(u'{st}{r}', u'{/r}{/st}')
|
||||
|
||||
The first unicode string are the start tags (for the next slide). The
|
||||
second unicode string are the end tags.
|
||||
|
||||
``text``
|
||||
The text to test. The text must **not** contain html tags, only
|
||||
OpenLP formatting tags are allowed::
|
||||
|
||||
{st}{r}Text text text
|
||||
"""
|
||||
tags = []
|
||||
for tag in FormattingTags.get_html_tags():
|
||||
if tag[u'start tag'] == u'{br}':
|
||||
continue
|
||||
if text.count(tag[u'start tag']) != text.count(tag[u'end tag']):
|
||||
tags.append((text.find(tag[u'start tag']),
|
||||
tag[u'start tag'], tag[u'end tag']))
|
||||
# Sort the lists, so that the tags which were opened first on the first
|
||||
# slide (the text we are checking) will be opened first on the next
|
||||
# slide as well.
|
||||
tags.sort(key=lambda tag: tag[0])
|
||||
end_tags = []
|
||||
start_tags = []
|
||||
for tag in tags:
|
||||
start_tags.append(tag[1])
|
||||
end_tags.append(tag[2])
|
||||
end_tags.reverse()
|
||||
return u''.join(start_tags), u''.join(end_tags)
|
||||
|
||||
def xml_to_song(self, xml, parse_and_temporary_save=False):
|
||||
"""
|
||||
Create and save a song from OpenLyrics format xml to the database. Since
|
||||
@ -521,9 +560,9 @@ class OpenLyrics(object):
|
||||
if hasattr(properties, u'comments'):
|
||||
comments_list = []
|
||||
for comment in properties.comments.comment:
|
||||
commenttext = self._text(comment)
|
||||
if commenttext:
|
||||
comments_list.append(commenttext)
|
||||
comment_text = self._text(comment)
|
||||
if comment_text:
|
||||
comments_list.append(comment_text)
|
||||
song.comments = u'\n'.join(comments_list)
|
||||
|
||||
def _process_copyright(self, properties, song):
|
||||
@ -572,7 +611,8 @@ class OpenLyrics(object):
|
||||
for tag in FormattingTags.get_html_tags()]
|
||||
new_tags = [tag for tag in found_tags
|
||||
if tag[u'start tag'] not in existing_tag_ids]
|
||||
FormattingTags.add_html_tags(new_tags, True)
|
||||
FormattingTags.add_html_tags(new_tags)
|
||||
FormattingTags.save_html_tags()
|
||||
|
||||
def _process_lines_mixed_content(self, element, newlines=True):
|
||||
"""
|
||||
@ -611,7 +651,7 @@ class OpenLyrics(object):
|
||||
text += u'{%s}' % element.get(u'name')
|
||||
# Some formattings may have only start tag.
|
||||
# Handle this case if element has no children and contains no text.
|
||||
if len(element) == 0 and not element.text:
|
||||
if not element and not element.text:
|
||||
use_endtag = False
|
||||
# Append text from element.
|
||||
if element.text:
|
||||
@ -746,13 +786,13 @@ class OpenLyrics(object):
|
||||
song.song_number = u''
|
||||
if hasattr(properties, u'songbooks'):
|
||||
for songbook in properties.songbooks.songbook:
|
||||
bookname = songbook.get(u'name', u'')
|
||||
if bookname:
|
||||
book_name = songbook.get(u'name', u'')
|
||||
if book_name:
|
||||
book = self.manager.get_object_filtered(Book,
|
||||
Book.name == bookname)
|
||||
Book.name == book_name)
|
||||
if book is None:
|
||||
# We need to create a book, because it does not exist.
|
||||
book = Book.populate(name=bookname, publisher=u'')
|
||||
book = Book.populate(name=book_name, publisher=u'')
|
||||
self.manager.save_object(book)
|
||||
song.song_book_id = book.id
|
||||
song.song_number = songbook.get(u'entry', u'')
|
||||
@ -787,14 +827,14 @@ class OpenLyrics(object):
|
||||
The song object.
|
||||
"""
|
||||
if hasattr(properties, u'themes'):
|
||||
for topictext in properties.themes.theme:
|
||||
topictext = self._text(topictext)
|
||||
if topictext:
|
||||
for topic_text in properties.themes.theme:
|
||||
topic_text = self._text(topic_text)
|
||||
if topic_text:
|
||||
topic = self.manager.get_object_filtered(Topic,
|
||||
Topic.name == topictext)
|
||||
Topic.name == topic_text)
|
||||
if topic is None:
|
||||
# We need to create a topic, because it does not exist.
|
||||
topic = Topic.populate(name=topictext)
|
||||
topic = Topic.populate(name=topic_text)
|
||||
self.manager.save_object(topic)
|
||||
song.topics.append(topic)
|
||||
|
||||
@ -813,6 +853,7 @@ class OpenLyricsError(Exception):
|
||||
VerseError = 2
|
||||
|
||||
def __init__(self, type, log_message, display_message):
|
||||
Exception.__init__(self)
|
||||
self.type = type
|
||||
self.log_message = log_message
|
||||
self.display_message = display_message
|
||||
|
@ -61,8 +61,8 @@ class SongsPlugin(Plugin):
|
||||
Plugin.__init__(self, u'songs', plugin_helpers, SongMediaItem, SongsTab)
|
||||
self.manager = Manager(u'songs', init_schema, upgrade_mod=upgrade)
|
||||
self.weight = -10
|
||||
self.icon_path = u':/plugins/plugin_songs.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.iconPath = u':/plugins/plugin_songs.png'
|
||||
self.icon = build_icon(self.iconPath)
|
||||
|
||||
def checkPreConditions(self):
|
||||
return self.manager.session is not None
|
||||
@ -144,7 +144,7 @@ class SongsPlugin(Plugin):
|
||||
return
|
||||
progressDialog = QtGui.QProgressDialog(
|
||||
translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel,
|
||||
0, maxSongs, self.formparent)
|
||||
0, maxSongs, self.formParent)
|
||||
progressDialog.setWindowModality(QtCore.Qt.WindowModal)
|
||||
songs = self.manager.get_all_objects(Song)
|
||||
for number, song in enumerate(songs):
|
||||
@ -239,9 +239,9 @@ class SongsPlugin(Plugin):
|
||||
for sfile in os.listdir(db_dir):
|
||||
if sfile.startswith(u'songs_') and sfile.endswith(u'.sqlite'):
|
||||
song_dbs.append(os.path.join(db_dir, sfile))
|
||||
if len(song_dbs) == 0:
|
||||
if not song_dbs:
|
||||
return
|
||||
progress = QtGui.QProgressDialog(self.formparent)
|
||||
progress = QtGui.QProgressDialog(self.formParent)
|
||||
progress.setWindowModality(QtCore.Qt.WindowModal)
|
||||
progress.setLabelText(translate('OpenLP.Ui', 'Starting import...'))
|
||||
progress.setCancelButton(None)
|
||||
|
@ -98,13 +98,13 @@ class SongUsagePlugin(Plugin):
|
||||
self.songUsageMenu.addAction(self.songUsageReport)
|
||||
self.songUsageMenu.addAction(self.songUsageDelete)
|
||||
self.songUsageActiveButton = QtGui.QToolButton(
|
||||
self.formparent.statusBar)
|
||||
self.formParent.statusBar)
|
||||
self.songUsageActiveButton.setCheckable(True)
|
||||
self.songUsageActiveButton.setAutoRaise(True)
|
||||
self.songUsageActiveButton.setStatusTip(translate('SongUsagePlugin',
|
||||
'Toggle the tracking of song usage.'))
|
||||
self.songUsageActiveButton.setObjectName(u'songUsageActiveButton')
|
||||
self.formparent.statusBar.insertPermanentWidget(1,
|
||||
self.formParent.statusBar.insertPermanentWidget(1,
|
||||
self.songUsageActiveButton)
|
||||
self.songUsageActiveButton.hide()
|
||||
# Signals and slots
|
||||
@ -138,8 +138,8 @@ class SongUsagePlugin(Plugin):
|
||||
action_list.add_action(self.songUsageReport,
|
||||
unicode(translate('SongUsagePlugin', 'Song Usage')))
|
||||
self.songUsageDeleteForm = SongUsageDeleteForm(self.manager,
|
||||
self.formparent)
|
||||
self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent)
|
||||
self.formParent)
|
||||
self.songUsageDetailForm = SongUsageDetailForm(self, self.formParent)
|
||||
self.songUsageMenu.menuAction().setVisible(True)
|
||||
self.songUsageActiveButton.show()
|
||||
|
||||
|
1310
resources/i18n/af.ts
1310
resources/i18n/af.ts
File diff suppressed because it is too large
Load Diff
1310
resources/i18n/cs.ts
1310
resources/i18n/cs.ts
File diff suppressed because it is too large
Load Diff
1294
resources/i18n/da.ts
1294
resources/i18n/da.ts
File diff suppressed because it is too large
Load Diff
1322
resources/i18n/de.ts
1322
resources/i18n/de.ts
File diff suppressed because it is too large
Load Diff
1310
resources/i18n/el.ts
1310
resources/i18n/el.ts
File diff suppressed because it is too large
Load Diff
1310
resources/i18n/en.ts
1310
resources/i18n/en.ts
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1394
resources/i18n/es.ts
1394
resources/i18n/es.ts
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user