forked from openlp/openlp
r1695
This commit is contained in:
commit
f8a705af78
|
@ -34,6 +34,7 @@ from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, \
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# FIXME: Add html5 doctype. However, do not break theme gradients.
|
||||||
HTMLSRC = u"""
|
HTMLSRC = u"""
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
@ -56,44 +57,44 @@ body {
|
||||||
height: %spx;
|
height: %spx;
|
||||||
}
|
}
|
||||||
#black {
|
#black {
|
||||||
z-index:8;
|
z-index: 8;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#bgimage {
|
#bgimage {
|
||||||
z-index:1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
#image {
|
#image {
|
||||||
z-index:2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
#video1 {
|
#video1 {
|
||||||
z-index:3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
#video2 {
|
#video2 {
|
||||||
z-index:3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
#alert {
|
#alert {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
z-index:10;
|
z-index: 10;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
#footer {
|
#footer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index:6;
|
z-index: 6;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
/* lyric css */
|
/* lyric css */
|
||||||
%s
|
%s
|
||||||
sup {
|
sup {
|
||||||
font-size:0.6em;
|
font-size: 0.6em;
|
||||||
vertical-align:top;
|
vertical-align: top;
|
||||||
position:relative;
|
position: relative;
|
||||||
top:-0.3em;
|
top: -0.3em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script language="javascript">
|
<script>
|
||||||
var timer = null;
|
var timer = null;
|
||||||
var video_timer = null;
|
var video_timer = null;
|
||||||
var current_video = '1';
|
var current_video = '1';
|
||||||
|
@ -317,10 +318,10 @@ sup {
|
||||||
%s
|
%s
|
||||||
<div id="footer" class="footer"></div>
|
<div id="footer" class="footer"></div>
|
||||||
<div id="black" class="size"></div>
|
<div id="black" class="size"></div>
|
||||||
<div id="alert" style="visibility:hidden;"></div>
|
<div id="alert" style="visibility:hidden"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def build_html(item, screen, alert, islive, background, image=None):
|
def build_html(item, screen, alert, islive, background, image=None):
|
||||||
"""
|
"""
|
||||||
|
@ -446,15 +447,15 @@ def build_lyrics_css(item, webkitvers):
|
||||||
The version of qtwebkit we're using
|
The version of qtwebkit we're using
|
||||||
|
|
||||||
"""
|
"""
|
||||||
style = """
|
style = u"""
|
||||||
.lyricstable {
|
.lyricstable {
|
||||||
z-index:5;
|
z-index: 5;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: table;
|
display: table;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
.lyricscell {
|
.lyricscell {
|
||||||
display:table-cell;
|
display: table-cell;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
|
@ -558,8 +559,8 @@ def build_lyrics_format_css(theme, width, height):
|
||||||
left_margin = 0
|
left_margin = 0
|
||||||
lyrics = u'white-space:pre-wrap; word-wrap: break-word; ' \
|
lyrics = u'white-space:pre-wrap; word-wrap: break-word; ' \
|
||||||
'text-align: %s; vertical-align: %s; font-family: %s; ' \
|
'text-align: %s; vertical-align: %s; font-family: %s; ' \
|
||||||
'font-size: %spt; color: %s; line-height: %d%%; margin:0;' \
|
'font-size: %spt; color: %s; line-height: %d%%; margin: 0;' \
|
||||||
'padding:0; padding-left:%spx; width: %spx; height: %spx; ' % \
|
'padding: 0; padding-left: %spx; width: %spx; height: %spx; ' % \
|
||||||
(align, valign, theme.font_main_name, theme.font_main_size,
|
(align, valign, theme.font_main_name, theme.font_main_size,
|
||||||
theme.font_main_color, 100 + int(theme.font_main_line_adjustment),
|
theme.font_main_color, 100 + int(theme.font_main_line_adjustment),
|
||||||
left_margin, width, height)
|
left_margin, width, height)
|
||||||
|
@ -608,7 +609,7 @@ def build_footer_css(item, height):
|
||||||
``item``
|
``item``
|
||||||
Service Item to be processed.
|
Service Item to be processed.
|
||||||
"""
|
"""
|
||||||
style = """
|
style = u"""
|
||||||
left: %spx;
|
left: %spx;
|
||||||
bottom: %spx;
|
bottom: %spx;
|
||||||
width: %spx;
|
width: %spx;
|
||||||
|
@ -616,7 +617,7 @@ def build_footer_css(item, height):
|
||||||
font-size: %spt;
|
font-size: %spt;
|
||||||
color: %s;
|
color: %s;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
white-space:nowrap;
|
white-space: nowrap;
|
||||||
"""
|
"""
|
||||||
theme = item.themedata
|
theme = item.themedata
|
||||||
if not theme or not item.footer:
|
if not theme or not item.footer:
|
||||||
|
@ -634,7 +635,7 @@ def build_alert_css(alertTab, width):
|
||||||
``alertTab``
|
``alertTab``
|
||||||
Details from the Alert tab for fonts etc
|
Details from the Alert tab for fonts etc
|
||||||
"""
|
"""
|
||||||
style = """
|
style = u"""
|
||||||
width: %spx;
|
width: %spx;
|
||||||
vertical-align: %s;
|
vertical-align: %s;
|
||||||
font-family: %s;
|
font-family: %s;
|
||||||
|
|
|
@ -96,7 +96,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||||
self.plugin = plugin
|
self.plugin = plugin
|
||||||
visible_title = self.plugin.getString(StringContent.VisibleName)
|
visible_title = self.plugin.getString(StringContent.VisibleName)
|
||||||
self.title = unicode(visible_title[u'title'])
|
self.title = unicode(visible_title[u'title'])
|
||||||
self.settingsSection = self.plugin.name.lower()
|
self.settingsSection = self.plugin.name
|
||||||
self.icon = None
|
self.icon = None
|
||||||
if icon:
|
if icon:
|
||||||
self.icon = build_icon(icon)
|
self.icon = build_icon(icon)
|
||||||
|
@ -113,7 +113,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||||
self.retranslateUi()
|
self.retranslateUi()
|
||||||
self.auto_select_id = -1
|
self.auto_select_id = -1
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'%s_service_load' % self.plugin.name.lower()),
|
QtCore.SIGNAL(u'%s_service_load' % self.plugin.name),
|
||||||
self.serviceLoad)
|
self.serviceLoad)
|
||||||
|
|
||||||
def requiredIcons(self):
|
def requiredIcons(self):
|
||||||
|
@ -558,7 +558,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||||
QtGui.QMessageBox.information(self, UiStrings().NISs,
|
QtGui.QMessageBox.information(self, UiStrings().NISs,
|
||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'You must select an existing service item to add to.'))
|
'You must select an existing service item to add to.'))
|
||||||
elif self.plugin.name.lower() == serviceItem.name.lower():
|
elif self.plugin.name == serviceItem.name:
|
||||||
self.generateSlideData(serviceItem)
|
self.generateSlideData(serviceItem)
|
||||||
self.plugin.serviceManager.addServiceItem(serviceItem,
|
self.plugin.serviceManager.addServiceItem(serviceItem,
|
||||||
replace=True)
|
replace=True)
|
||||||
|
|
|
@ -152,7 +152,7 @@ class Plugin(QtCore.QObject):
|
||||||
self.version = version
|
self.version = version
|
||||||
else:
|
else:
|
||||||
self.version = get_application_version()[u'version']
|
self.version = get_application_version()[u'version']
|
||||||
self.settingsSection = self.name.lower()
|
self.settingsSection = self.name
|
||||||
self.icon = None
|
self.icon = None
|
||||||
self.media_item_class = media_item_class
|
self.media_item_class = media_item_class
|
||||||
self.settings_tab_class = settings_tab_class
|
self.settings_tab_class = settings_tab_class
|
||||||
|
|
|
@ -31,7 +31,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, PluginStatus
|
from openlp.core.lib import Plugin, PluginStatus
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -56,20 +56,20 @@ class Renderer(object):
|
||||||
"""
|
"""
|
||||||
log.info(u'Renderer Loaded')
|
log.info(u'Renderer Loaded')
|
||||||
|
|
||||||
def __init__(self, image_manager, theme_manager):
|
def __init__(self, imageManager, themeManager):
|
||||||
"""
|
"""
|
||||||
Initialise the render manager.
|
Initialise the render manager.
|
||||||
|
|
||||||
``image_manager``
|
``imageManager``
|
||||||
A ImageManager instance which takes care of e. g. caching and resizing
|
A ImageManager instance which takes care of e. g. caching and resizing
|
||||||
images.
|
images.
|
||||||
|
|
||||||
``theme_manager``
|
``themeManager``
|
||||||
The ThemeManager instance, used to get the current theme details.
|
The ThemeManager instance, used to get the current theme details.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Initialisation started')
|
log.debug(u'Initialisation started')
|
||||||
self.theme_manager = theme_manager
|
self.themeManager = themeManager
|
||||||
self.image_manager = image_manager
|
self.imageManager = imageManager
|
||||||
self.screens = ScreenList.get_instance()
|
self.screens = ScreenList.get_instance()
|
||||||
self.service_theme = u''
|
self.service_theme = u''
|
||||||
self.theme_level = u''
|
self.theme_level = u''
|
||||||
|
@ -77,7 +77,7 @@ class Renderer(object):
|
||||||
self.theme_data = None
|
self.theme_data = None
|
||||||
self.bg_frame = None
|
self.bg_frame = None
|
||||||
self.force_page = False
|
self.force_page = False
|
||||||
self.display = MainDisplay(None, self.image_manager, False)
|
self.display = MainDisplay(None, self.imageManager, False)
|
||||||
self.display.setup()
|
self.display.setup()
|
||||||
|
|
||||||
def update_display(self):
|
def update_display(self):
|
||||||
|
@ -88,7 +88,7 @@ class Renderer(object):
|
||||||
self._calculate_default(self.screens.current[u'size'])
|
self._calculate_default(self.screens.current[u'size'])
|
||||||
if self.display:
|
if self.display:
|
||||||
self.display.close()
|
self.display.close()
|
||||||
self.display = MainDisplay(None, self.image_manager, False)
|
self.display = MainDisplay(None, self.imageManager, False)
|
||||||
self.display.setup()
|
self.display.setup()
|
||||||
self.bg_frame = None
|
self.bg_frame = None
|
||||||
self.theme_data = None
|
self.theme_data = None
|
||||||
|
@ -101,14 +101,14 @@ class Renderer(object):
|
||||||
The global-level theme to be set.
|
The global-level theme to be set.
|
||||||
|
|
||||||
``theme_level``
|
``theme_level``
|
||||||
Defaults to *``ThemeLevel.Global``*. The theme level, can be
|
Defaults to ``ThemeLevel.Global``. The theme level, can be
|
||||||
``ThemeLevel.Global``, ``ThemeLevel.Service`` or
|
``ThemeLevel.Global``, ``ThemeLevel.Service`` or
|
||||||
``ThemeLevel.Song``.
|
``ThemeLevel.Song``.
|
||||||
"""
|
"""
|
||||||
self.global_theme = global_theme
|
self.global_theme = global_theme
|
||||||
self.theme_level = theme_level
|
self.theme_level = theme_level
|
||||||
self.global_theme_data = \
|
self.global_theme_data = \
|
||||||
self.theme_manager.getThemeData(self.global_theme)
|
self.themeManager.getThemeData(self.global_theme)
|
||||||
self.theme_data = None
|
self.theme_data = None
|
||||||
|
|
||||||
def set_service_theme(self, service_theme):
|
def set_service_theme(self, service_theme):
|
||||||
|
@ -162,12 +162,12 @@ class Renderer(object):
|
||||||
if override_levels:
|
if override_levels:
|
||||||
self.theme_data = override_theme
|
self.theme_data = override_theme
|
||||||
else:
|
else:
|
||||||
self.theme_data = self.theme_manager.getThemeData(theme)
|
self.theme_data = self.themeManager.getThemeData(theme)
|
||||||
self._calculate_default(self.screens.current[u'size'])
|
self._calculate_default(self.screens.current[u'size'])
|
||||||
self._build_text_rectangle(self.theme_data)
|
self._build_text_rectangle(self.theme_data)
|
||||||
# if No file do not update cache
|
# if No file do not update cache
|
||||||
if self.theme_data.background_filename:
|
if self.theme_data.background_filename:
|
||||||
self.image_manager.add_image(self.theme_data.theme_name,
|
self.imageManager.add_image(self.theme_data.theme_name,
|
||||||
self.theme_data.background_filename)
|
self.theme_data.background_filename)
|
||||||
return self._rect, self._rect_footer
|
return self._rect, self._rect_footer
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ class Renderer(object):
|
||||||
# make big page for theme edit dialog to get line count
|
# make big page for theme edit dialog to get line count
|
||||||
serviceItem.add_from_text(u'', VERSE + VERSE + VERSE)
|
serviceItem.add_from_text(u'', VERSE + VERSE + VERSE)
|
||||||
else:
|
else:
|
||||||
self.image_manager.del_image(theme_data.theme_name)
|
self.imageManager.del_image(theme_data.theme_name)
|
||||||
serviceItem.add_from_text(u'', VERSE)
|
serviceItem.add_from_text(u'', VERSE)
|
||||||
serviceItem.renderer = self
|
serviceItem.renderer = self
|
||||||
serviceItem.raw_footer = FOOTER
|
serviceItem.raw_footer = FOOTER
|
||||||
|
@ -205,43 +205,52 @@ class Renderer(object):
|
||||||
# Reset the real screen size for subsequent render requests
|
# Reset the real screen size for subsequent render requests
|
||||||
self._calculate_default(self.screens.current[u'size'])
|
self._calculate_default(self.screens.current[u'size'])
|
||||||
return preview
|
return preview
|
||||||
|
self.force_page = False
|
||||||
|
|
||||||
def format_slide(self, text, line_break, item):
|
def format_slide(self, text, item):
|
||||||
"""
|
"""
|
||||||
Calculate how much text can fit on a slide.
|
Calculate how much text can fit on a slide.
|
||||||
|
|
||||||
``text``
|
``text``
|
||||||
The words to go on the slides.
|
The words to go on the slides.
|
||||||
|
|
||||||
``line_break``
|
``item``
|
||||||
Add line endings after each line of text used for bibles.
|
The :class:`~openlp.core.lib.serviceitem.ServiceItem` item object.
|
||||||
"""
|
"""
|
||||||
log.debug(u'format slide')
|
log.debug(u'format slide')
|
||||||
# clean up line endings
|
# Add line endings after each line of text used for bibles.
|
||||||
|
line_end = u'<br>'
|
||||||
|
if item.is_capable(ItemCapabilities.NoLineBreaks):
|
||||||
|
line_end = u' '
|
||||||
|
# Bibles
|
||||||
|
if item.is_capable(ItemCapabilities.AllowsWordSplit):
|
||||||
|
pages = self._paginate_slide_words(text, line_end)
|
||||||
|
else:
|
||||||
|
# Clean up line endings.
|
||||||
lines = self._lines_split(text)
|
lines = self._lines_split(text)
|
||||||
pages = self._paginate_slide(lines, line_break, self.force_page)
|
pages = self._paginate_slide(lines, line_end)
|
||||||
if len(pages) > 1:
|
if len(pages) > 1:
|
||||||
# Songs and Custom
|
# Songs and Custom
|
||||||
if item.is_capable(ItemCapabilities.AllowsVirtualSplit):
|
if item.is_capable(ItemCapabilities.AllowsVirtualSplit):
|
||||||
# Do not forget the line breaks !
|
# Do not forget the line breaks!
|
||||||
slides = text.split(u'[---]')
|
slides = text.split(u'[---]')
|
||||||
pages = []
|
pages = []
|
||||||
for slide in slides:
|
for slide in slides:
|
||||||
lines = slide.strip(u'\n').split(u'\n')
|
lines = slide.strip(u'\n').split(u'\n')
|
||||||
new_pages = self._paginate_slide(lines, line_break,
|
pages.extend(self._paginate_slide(lines, line_end))
|
||||||
self.force_page)
|
new_pages = []
|
||||||
pages.extend(new_pages)
|
for page in pages:
|
||||||
# Bibles
|
while page.endswith(u'<br>'):
|
||||||
elif item.is_capable(ItemCapabilities.AllowsWordSplit):
|
page = page[:-4]
|
||||||
pages = self._paginate_slide_words(text, line_break)
|
new_pages.append(page)
|
||||||
return pages
|
return new_pages
|
||||||
|
|
||||||
def _calculate_default(self, screen):
|
def _calculate_default(self, screen):
|
||||||
"""
|
"""
|
||||||
Calculate the default dimentions of the screen.
|
Calculate the default dimentions of the screen.
|
||||||
|
|
||||||
``screen``
|
``screen``
|
||||||
The QSize of the screen.
|
The screen to calculate the default of.
|
||||||
"""
|
"""
|
||||||
log.debug(u'_calculate default %s', screen)
|
log.debug(u'_calculate default %s', screen)
|
||||||
self.width = screen.width()
|
self.width = screen.width()
|
||||||
|
@ -301,61 +310,44 @@ class Renderer(object):
|
||||||
self.web.resize(self.page_width, self.page_height)
|
self.web.resize(self.page_width, self.page_height)
|
||||||
self.web_frame = self.web.page().mainFrame()
|
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
|
||||||
self.page_shell = u'<html><head><style>' \
|
self.page_shell = u'<!DOCTYPE html><html><head><style>' \
|
||||||
u'*{margin: 0; padding: 0; border: 0;} '\
|
u'*{margin:0; padding:0; border:0;} '\
|
||||||
u'#main {position:absolute; top:0px; %s %s}</style></head><body>' \
|
u'#main {position:absolute; top:0px; %s %s}</style></head><body>' \
|
||||||
u'<div id="main">' % \
|
u'<div id="main">' % \
|
||||||
(build_lyrics_format_css(self.theme_data, self.page_width,
|
(build_lyrics_format_css(self.theme_data, self.page_width,
|
||||||
self.page_height), build_lyrics_outline_css(self.theme_data))
|
self.page_height), build_lyrics_outline_css(self.theme_data))
|
||||||
|
|
||||||
def _paginate_slide(self, lines, line_break, force_page=False):
|
def _paginate_slide(self, lines, line_end):
|
||||||
"""
|
"""
|
||||||
Figure out how much text can appear on a slide, using the current
|
Figure out how much text can appear on a slide, using the current
|
||||||
theme settings.
|
theme settings.
|
||||||
|
|
||||||
``lines``
|
``lines``
|
||||||
The words to be fitted on the slide split into lines.
|
The text to be fitted on the slide split into lines.
|
||||||
|
|
||||||
``line_break``
|
|
||||||
Add line endings after each line of text (used for bibles).
|
|
||||||
|
|
||||||
``force_page``
|
|
||||||
Flag to tell message lines in page.
|
|
||||||
|
|
||||||
|
``line_end``
|
||||||
|
The text added after each line. Either ``u' '`` or ``u'<br>``.
|
||||||
"""
|
"""
|
||||||
log.debug(u'_paginate_slide - Start')
|
log.debug(u'_paginate_slide - Start')
|
||||||
line_end = u''
|
|
||||||
if line_break:
|
|
||||||
line_end = u'<br>'
|
|
||||||
formatted = []
|
formatted = []
|
||||||
html_text = u''
|
previous_html = u''
|
||||||
styled_text = u''
|
previous_raw = u''
|
||||||
line_count = 0
|
separator = u'<br>'
|
||||||
for line in lines:
|
html_lines = map(expand_tags, lines)
|
||||||
if line_count != -1:
|
html = self.page_shell + separator.join(html_lines) + HTML_END
|
||||||
line_count += 1
|
|
||||||
styled_line = expand_tags(line) + line_end
|
|
||||||
styled_text += styled_line
|
|
||||||
html = self.page_shell + styled_text + HTML_END
|
|
||||||
self.web.setHtml(html)
|
self.web.setHtml(html)
|
||||||
# Text too long so go to next page.
|
# Text too long so go to next page.
|
||||||
if self.web_frame.contentsSize().height() > self.page_height:
|
if self.web_frame.contentsSize().height() > self.page_height:
|
||||||
if force_page and line_count > 0:
|
html_text, previous_raw = self._binary_chop(formatted,
|
||||||
Receiver.send_message(u'theme_line_count', line_count - 1)
|
previous_html, previous_raw, html_lines, lines, separator, u'')
|
||||||
line_count = -1
|
else:
|
||||||
while html_text.endswith(u'<br>'):
|
previous_raw = separator.join(lines)
|
||||||
html_text = html_text[:-4]
|
if previous_raw:
|
||||||
formatted.append(html_text)
|
formatted.append(previous_raw)
|
||||||
html_text = u''
|
|
||||||
styled_text = styled_line
|
|
||||||
html_text += line + line_end
|
|
||||||
while html_text.endswith(u'<br>'):
|
|
||||||
html_text = html_text[:-4]
|
|
||||||
formatted.append(html_text)
|
|
||||||
log.debug(u'_paginate_slide - End')
|
log.debug(u'_paginate_slide - End')
|
||||||
return formatted
|
return formatted
|
||||||
|
|
||||||
def _paginate_slide_words(self, text, line_break):
|
def _paginate_slide_words(self, text, line_end):
|
||||||
"""
|
"""
|
||||||
Figure out how much text can appear on a slide, using the current
|
Figure out how much text can appear on a slide, using the current
|
||||||
theme settings. This version is to handle text which needs to be split
|
theme settings. This version is to handle text which needs to be split
|
||||||
|
@ -364,22 +356,19 @@ class Renderer(object):
|
||||||
``text``
|
``text``
|
||||||
The words to be fitted on the slide split into lines.
|
The words to be fitted on the slide split into lines.
|
||||||
|
|
||||||
``line_break``
|
``line_end``
|
||||||
Add line endings after each line of text used for bibles.
|
The text added after each line. Either ``u' '`` or ``u'<br>``.
|
||||||
|
This is needed for bibles.
|
||||||
"""
|
"""
|
||||||
log.debug(u'_paginate_slide_words - Start')
|
log.debug(u'_paginate_slide_words - Start')
|
||||||
line_end = u' '
|
|
||||||
if line_break:
|
|
||||||
line_end = u'<br>'
|
|
||||||
formatted = []
|
formatted = []
|
||||||
previous_html = u''
|
previous_html = u''
|
||||||
previous_raw = u''
|
previous_raw = u''
|
||||||
lines = text.split(u'\n')
|
lines = text.split(u'\n')
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
styled_line = expand_tags(line)
|
html_line = expand_tags(line)
|
||||||
html = self.page_shell + previous_html + styled_line + HTML_END
|
html = self.page_shell + previous_html + html_line + HTML_END
|
||||||
self.web.setHtml(html)
|
self.web.setHtml(html)
|
||||||
# Text too long so go to next page.
|
# Text too long so go to next page.
|
||||||
if self.web_frame.contentsSize().height() > self.page_height:
|
if self.web_frame.contentsSize().height() > self.page_height:
|
||||||
|
@ -390,34 +379,76 @@ class Renderer(object):
|
||||||
self.web.setHtml(html)
|
self.web.setHtml(html)
|
||||||
if self.web_frame.contentsSize().height() <= \
|
if self.web_frame.contentsSize().height() <= \
|
||||||
self.page_height:
|
self.page_height:
|
||||||
while previous_raw.endswith(u'<br>'):
|
|
||||||
previous_raw = previous_raw[:-4]
|
|
||||||
formatted.append(previous_raw)
|
formatted.append(previous_raw)
|
||||||
previous_html = u''
|
previous_html = u''
|
||||||
previous_raw = u''
|
previous_raw = u''
|
||||||
html = self.page_shell + styled_line + HTML_END
|
html = self.page_shell + html_line + HTML_END
|
||||||
self.web.setHtml(html)
|
self.web.setHtml(html)
|
||||||
# Now check if the current verse will fit, if it does
|
# Now check if the current verse will fit, if it does
|
||||||
# not we have to start to process the verse word by
|
# not we have to start to process the verse word by
|
||||||
# word.
|
# word.
|
||||||
if self.web_frame.contentsSize().height() <= \
|
if self.web_frame.contentsSize().height() <= \
|
||||||
self.page_height:
|
self.page_height:
|
||||||
previous_html = styled_line + line_end
|
previous_html = html_line + line_end
|
||||||
previous_raw = line + line_end
|
previous_raw = line + line_end
|
||||||
continue
|
continue
|
||||||
# Figure out how many words of the line will fit on screen by
|
# Figure out how many words of the line will fit on screen as
|
||||||
# using the algorithm known as "binary chop".
|
# the line will not fit as a whole.
|
||||||
raw_words = self._words_split(line)
|
raw_words = self._words_split(line)
|
||||||
html_words = [expand_tags(word) for word in raw_words]
|
html_words = map(expand_tags, raw_words)
|
||||||
|
previous_html, previous_raw = self._binary_chop(
|
||||||
|
formatted, previous_html, previous_raw, html_words,
|
||||||
|
raw_words, u' ', line_end)
|
||||||
|
else:
|
||||||
|
previous_html += html_line + line_end
|
||||||
|
previous_raw += line + line_end
|
||||||
|
formatted.append(previous_raw)
|
||||||
|
log.debug(u'_paginate_slide_words - End')
|
||||||
|
return formatted
|
||||||
|
|
||||||
|
def _binary_chop(self, formatted, previous_html, previous_raw, html_list,
|
||||||
|
raw_list, separator, line_end):
|
||||||
|
"""
|
||||||
|
This implements the binary chop algorithm for faster rendering. This
|
||||||
|
algorithm works line based (line by line) and word based (word by word).
|
||||||
|
It is assumed that this method is **only** called, when the lines/words
|
||||||
|
to be rendered do **not** fit as a whole.
|
||||||
|
|
||||||
|
``formatted``
|
||||||
|
The list to append any slides.
|
||||||
|
|
||||||
|
``previous_html``
|
||||||
|
The html text which is know to fit on a slide, but is not yet added
|
||||||
|
to the list of slides. (unicode string)
|
||||||
|
|
||||||
|
``previous_raw``
|
||||||
|
The raw text (with display tags) which is know to fit on a slide,
|
||||||
|
but is not yet added to the list of slides. (unicode string)
|
||||||
|
|
||||||
|
``html_list``
|
||||||
|
The elements which do not fit on a slide and needs to be processed
|
||||||
|
using the binary chop. The text contains html.
|
||||||
|
|
||||||
|
``raw_list``
|
||||||
|
The elements which do not fit on a slide and needs to be processed
|
||||||
|
using the binary chop. The elements can contain display tags.
|
||||||
|
|
||||||
|
``separator``
|
||||||
|
The separator for the elements. For lines this is ``u'<br>'`` and
|
||||||
|
for words this is ``u' '``.
|
||||||
|
|
||||||
|
``line_end``
|
||||||
|
The text added after each "element line". Either ``u' '`` or
|
||||||
|
``u'<br>``. This is needed for bibles.
|
||||||
|
"""
|
||||||
smallest_index = 0
|
smallest_index = 0
|
||||||
highest_index = len(html_words) - 1
|
highest_index = len(html_list) - 1
|
||||||
index = int(highest_index / 2)
|
index = int(highest_index / 2)
|
||||||
while True:
|
while True:
|
||||||
html = self.page_shell + previous_html + \
|
html = self.page_shell + previous_html + \
|
||||||
u''.join(html_words[:index + 1]).strip() + HTML_END
|
separator.join(html_list[:index + 1]).strip() + HTML_END
|
||||||
self.web.setHtml(html)
|
self.web.setHtml(html)
|
||||||
if self.web_frame.contentsSize().height() > \
|
if self.web_frame.contentsSize().height() > self.page_height:
|
||||||
self.page_height:
|
|
||||||
# We know that it does not fit, so change/calculate the
|
# We know that it does not fit, so change/calculate the
|
||||||
# new index and highest_index accordingly.
|
# new index and highest_index accordingly.
|
||||||
highest_index = index
|
highest_index = index
|
||||||
|
@ -429,40 +460,34 @@ class Renderer(object):
|
||||||
if smallest_index == index or highest_index == index:
|
if smallest_index == index or highest_index == index:
|
||||||
index = smallest_index
|
index = smallest_index
|
||||||
formatted.append(previous_raw.rstrip(u'<br>') +
|
formatted.append(previous_raw.rstrip(u'<br>') +
|
||||||
u''.join(raw_words[:index + 1]))
|
separator.join(raw_list[:index + 1]))
|
||||||
previous_html = u''
|
previous_html = u''
|
||||||
previous_raw = u''
|
previous_raw = u''
|
||||||
else:
|
# Stop here as the theme line count was requested.
|
||||||
continue
|
if self.force_page:
|
||||||
# Check if the rest of the line fits on the slide. If it
|
Receiver.send_message(u'theme_line_count', index + 1)
|
||||||
# does we do not have to do the much more intensive "word by
|
|
||||||
# word" checking.
|
|
||||||
html = self.page_shell + \
|
|
||||||
u''.join(html_words[index + 1:]).strip() + HTML_END
|
|
||||||
self.web.setHtml(html)
|
|
||||||
if self.web_frame.contentsSize().height() <= \
|
|
||||||
self.page_height:
|
|
||||||
previous_html = \
|
|
||||||
u''.join(html_words[index + 1:]).strip() + line_end
|
|
||||||
previous_raw = \
|
|
||||||
u''.join(raw_words[index + 1:]).strip() + line_end
|
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# The other words do not fit, thus reset the indexes,
|
continue
|
||||||
# create a new list and continue with "word by word".
|
# Check if the remaining elements fit on the slide.
|
||||||
raw_words = raw_words[index + 1:]
|
html = self.page_shell + \
|
||||||
html_words = html_words[index + 1:]
|
separator.join(html_list[index + 1:]).strip() + HTML_END
|
||||||
smallest_index = 0
|
self.web.setHtml(html)
|
||||||
highest_index = len(html_words) - 1
|
if self.web_frame.contentsSize().height() <= self.page_height:
|
||||||
index = int(highest_index / 2)
|
previous_html = separator.join(
|
||||||
|
html_list[index + 1:]).strip() + line_end
|
||||||
|
previous_raw = separator.join(
|
||||||
|
raw_list[index + 1:]).strip() + line_end
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
previous_html += styled_line + line_end
|
# The remaining elements do not fit, thus reset the indexes,
|
||||||
previous_raw += line + line_end
|
# create a new list and continue.
|
||||||
while previous_raw.endswith(u'<br>'):
|
raw_list = raw_list[index + 1:]
|
||||||
previous_raw = previous_raw[:-4]
|
html_list = html_list[index + 1:]
|
||||||
formatted.append(previous_raw)
|
smallest_index = 0
|
||||||
log.debug(u'_paginate_slide_words - End')
|
highest_index = len(html_list) - 1
|
||||||
return formatted
|
index = int(highest_index / 2)
|
||||||
|
return previous_html, previous_raw
|
||||||
|
|
||||||
def _words_split(self, line):
|
def _words_split(self, line):
|
||||||
"""
|
"""
|
||||||
|
@ -470,8 +495,7 @@ class Renderer(object):
|
||||||
"""
|
"""
|
||||||
# this parse we are to be wordy
|
# this parse we are to be wordy
|
||||||
line = line.replace(u'\n', u' ')
|
line = line.replace(u'\n', u' ')
|
||||||
words = line.split(u' ')
|
return line.split(u' ')
|
||||||
return [word + u' ' for word in words]
|
|
||||||
|
|
||||||
def _lines_split(self, text):
|
def _lines_split(self, text):
|
||||||
"""
|
"""
|
||||||
|
@ -479,5 +503,5 @@ class Renderer(object):
|
||||||
"""
|
"""
|
||||||
# this parse we do not want to use this so remove it
|
# this parse we do not want to use this so remove it
|
||||||
text = text.replace(u'\n[---]', u'')
|
text = text.replace(u'\n[---]', u'')
|
||||||
lines = text.split(u'\n')
|
text = text.replace(u'[---]', u'')
|
||||||
return [line.replace(u'[---]', u'') for line in lines]
|
return text.split(u'\n')
|
||||||
|
|
|
@ -36,7 +36,6 @@ import os
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from openlp.core.lib import build_icon, clean_tags, expand_tags, translate
|
from openlp.core.lib import build_icon, clean_tags, expand_tags, translate
|
||||||
from openlp.core.lib.ui import UiStrings
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -165,7 +164,6 @@ class ServiceItem(object):
|
||||||
log.debug(u'Render called')
|
log.debug(u'Render called')
|
||||||
self._display_frames = []
|
self._display_frames = []
|
||||||
self.bg_image_bytes = None
|
self.bg_image_bytes = None
|
||||||
line_break = not self.is_capable(ItemCapabilities.NoLineBreaks)
|
|
||||||
theme = self.theme if self.theme else None
|
theme = self.theme if self.theme else None
|
||||||
self.main, self.footer = \
|
self.main, self.footer = \
|
||||||
self.renderer.set_override_theme(theme, use_override)
|
self.renderer.set_override_theme(theme, use_override)
|
||||||
|
@ -173,9 +171,8 @@ class ServiceItem(object):
|
||||||
if self.service_item_type == ServiceItemType.Text:
|
if self.service_item_type == ServiceItemType.Text:
|
||||||
log.debug(u'Formatting slides')
|
log.debug(u'Formatting slides')
|
||||||
for slide in self._raw_frames:
|
for slide in self._raw_frames:
|
||||||
formatted = self.renderer \
|
pages = self.renderer.format_slide(slide[u'raw_slide'], self)
|
||||||
.format_slide(slide[u'raw_slide'], line_break, self)
|
for page in pages:
|
||||||
for page in formatted:
|
|
||||||
page = page.replace(u'<br>', u'{br}')
|
page = page.replace(u'<br>', u'{br}')
|
||||||
html = expand_tags(cgi.escape(page.rstrip()))
|
html = expand_tags(cgi.escape(page.rstrip()))
|
||||||
self._display_frames.append({
|
self._display_frames.append({
|
||||||
|
@ -210,7 +207,7 @@ class ServiceItem(object):
|
||||||
"""
|
"""
|
||||||
self.service_item_type = ServiceItemType.Image
|
self.service_item_type = ServiceItemType.Image
|
||||||
self._raw_frames.append({u'title': title, u'path': path})
|
self._raw_frames.append({u'title': title, u'path': path})
|
||||||
self.renderer.image_manager.add_image(title, path)
|
self.renderer.imageManager.add_image(title, path)
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
|
||||||
def add_from_text(self, title, raw_slide, verse_tag=None):
|
def add_from_text(self, title, raw_slide, verse_tag=None):
|
||||||
|
@ -464,7 +461,7 @@ class ServiceItem(object):
|
||||||
elif not start and end:
|
elif not start and end:
|
||||||
return end
|
return end
|
||||||
else:
|
else:
|
||||||
return u'%s <br />%s' % (start, end)
|
return u'%s <br>%s' % (start, end)
|
||||||
|
|
||||||
def update_theme(self, theme):
|
def update_theme(self, theme):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -57,7 +57,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||||
self.dictionary = enchant.Dict()
|
self.dictionary = enchant.Dict()
|
||||||
self.highlighter = Highlighter(self.document())
|
self.highlighter = Highlighter(self.document())
|
||||||
self.highlighter.spellingDictionary = self.dictionary
|
self.highlighter.spellingDictionary = self.dictionary
|
||||||
except Error, DictNotFoundError:
|
except (Error, DictNotFoundError):
|
||||||
ENCHANT_AVAILABLE = False
|
ENCHANT_AVAILABLE = False
|
||||||
log.debug(u'Could not load default dictionary')
|
log.debug(u'Could not load default dictionary')
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,7 @@ import logging
|
||||||
from xml.dom.minidom import Document
|
from xml.dom.minidom import Document
|
||||||
from lxml import etree, objectify
|
from lxml import etree, objectify
|
||||||
|
|
||||||
from openlp.core.lib import str_to_bool, translate
|
from openlp.core.lib import str_to_bool
|
||||||
from openlp.core.lib.ui import UiStrings
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.core.lib.ui import UiStrings, create_accept_reject_button_box
|
from openlp.core.lib.ui import UiStrings
|
||||||
|
|
||||||
class Ui_DisplayTagDialog(object):
|
class Ui_DisplayTagDialog(object):
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Ui_FirstTimeWizard(object):
|
||||||
FirstTimeWizard.resize(550, 386)
|
FirstTimeWizard.resize(550, 386)
|
||||||
FirstTimeWizard.setModal(True)
|
FirstTimeWizard.setModal(True)
|
||||||
FirstTimeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
|
FirstTimeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
|
||||||
FirstTimeWizard.setOptions(QtGui.QWizard.IndependentPages|
|
FirstTimeWizard.setOptions(QtGui.QWizard.IndependentPages |
|
||||||
QtGui.QWizard.NoBackButtonOnStartPage |
|
QtGui.QWizard.NoBackButtonOnStartPage |
|
||||||
QtGui.QWizard.NoBackButtonOnLastPage)
|
QtGui.QWizard.NoBackButtonOnLastPage)
|
||||||
self.finishButton = self.button(QtGui.QWizard.FinishButton)
|
self.finishButton = self.button(QtGui.QWizard.FinishButton)
|
||||||
|
|
|
@ -48,13 +48,13 @@ class MainDisplay(QtGui.QGraphicsView):
|
||||||
"""
|
"""
|
||||||
This is the display screen.
|
This is the display screen.
|
||||||
"""
|
"""
|
||||||
def __init__(self, parent, image_manager, live):
|
def __init__(self, parent, imageManager, live):
|
||||||
if live:
|
if live:
|
||||||
QtGui.QGraphicsView.__init__(self)
|
QtGui.QGraphicsView.__init__(self)
|
||||||
else:
|
else:
|
||||||
QtGui.QGraphicsView.__init__(self, parent)
|
QtGui.QGraphicsView.__init__(self, parent)
|
||||||
self.isLive = live
|
self.isLive = live
|
||||||
self.image_manager = image_manager
|
self.imageManager = imageManager
|
||||||
self.screens = ScreenList.get_instance()
|
self.screens = ScreenList.get_instance()
|
||||||
self.alertTab = None
|
self.alertTab = None
|
||||||
self.hideMode = None
|
self.hideMode = None
|
||||||
|
@ -232,7 +232,7 @@ class MainDisplay(QtGui.QGraphicsView):
|
||||||
"""
|
"""
|
||||||
API for replacement backgrounds so Images are added directly to cache
|
API for replacement backgrounds so Images are added directly to cache
|
||||||
"""
|
"""
|
||||||
self.image_manager.add_image(name, path)
|
self.imageManager.add_image(name, path)
|
||||||
if hasattr(self, u'serviceItem'):
|
if hasattr(self, u'serviceItem'):
|
||||||
self.override[u'image'] = name
|
self.override[u'image'] = name
|
||||||
self.override[u'theme'] = self.serviceItem.themedata.theme_name
|
self.override[u'theme'] = self.serviceItem.themedata.theme_name
|
||||||
|
@ -249,7 +249,7 @@ class MainDisplay(QtGui.QGraphicsView):
|
||||||
The name of the image to be displayed
|
The name of the image to be displayed
|
||||||
"""
|
"""
|
||||||
log.debug(u'image to display')
|
log.debug(u'image to display')
|
||||||
image = self.image_manager.get_image_bytes(name)
|
image = self.imageManager.get_image_bytes(name)
|
||||||
self.resetVideo()
|
self.resetVideo()
|
||||||
self.displayImage(image)
|
self.displayImage(image)
|
||||||
return self.preview()
|
return self.preview()
|
||||||
|
@ -482,13 +482,13 @@ class MainDisplay(QtGui.QGraphicsView):
|
||||||
self.override = {}
|
self.override = {}
|
||||||
else:
|
else:
|
||||||
# replace the background
|
# replace the background
|
||||||
background = self.image_manager. \
|
background = self.imageManager. \
|
||||||
get_image_bytes(self.override[u'image'])
|
get_image_bytes(self.override[u'image'])
|
||||||
if self.serviceItem.themedata.background_filename:
|
if self.serviceItem.themedata.background_filename:
|
||||||
self.serviceItem.bg_image_bytes = self.image_manager. \
|
self.serviceItem.bg_image_bytes = self.imageManager. \
|
||||||
get_image_bytes(self.serviceItem.themedata.theme_name)
|
get_image_bytes(self.serviceItem.themedata.theme_name)
|
||||||
if image:
|
if image:
|
||||||
image_bytes = self.image_manager.get_image_bytes(image)
|
image_bytes = self.imageManager.get_image_bytes(image)
|
||||||
else:
|
else:
|
||||||
image_bytes = None
|
image_bytes = None
|
||||||
html = build_html(self.serviceItem, self.screen, self.alertTab,
|
html = build_html(self.serviceItem, self.screen, self.alertTab,
|
||||||
|
|
|
@ -66,7 +66,7 @@ class MediaDockManager(object):
|
||||||
match = False
|
match = False
|
||||||
for dock_index in range(0, self.media_dock.count()):
|
for dock_index in range(0, self.media_dock.count()):
|
||||||
if self.media_dock.widget(dock_index).settingsSection == \
|
if self.media_dock.widget(dock_index).settingsSection == \
|
||||||
media_item.plugin.name.lower():
|
media_item.plugin.name:
|
||||||
match = True
|
match = True
|
||||||
break
|
break
|
||||||
if not match:
|
if not match:
|
||||||
|
@ -84,6 +84,6 @@ class MediaDockManager(object):
|
||||||
for dock_index in range(0, self.media_dock.count()):
|
for dock_index in range(0, self.media_dock.count()):
|
||||||
if self.media_dock.widget(dock_index):
|
if self.media_dock.widget(dock_index):
|
||||||
if self.media_dock.widget(dock_index).settingsSection == \
|
if self.media_dock.widget(dock_index).settingsSection == \
|
||||||
media_item.plugin.name.lower():
|
media_item.plugin.name:
|
||||||
self.media_dock.widget(dock_index).setVisible(False)
|
self.media_dock.widget(dock_index).setVisible(False)
|
||||||
self.media_dock.removeItem(dock_index)
|
self.media_dock.removeItem(dock_index)
|
||||||
|
|
|
@ -240,7 +240,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||||
translate('OpenLP.ServiceManager', 'Notes: '), p,
|
translate('OpenLP.ServiceManager', 'Notes: '), p,
|
||||||
classId=u'itemNotesTitle')
|
classId=u'itemNotesTitle')
|
||||||
notes = self._addElement(u'span',
|
notes = self._addElement(u'span',
|
||||||
item.notes.replace(u'\n', u'<br />'), p,
|
item.notes.replace(u'\n', u'<br>'), p,
|
||||||
classId=u'itemNotesText')
|
classId=u'itemNotesText')
|
||||||
# Add play length of media files.
|
# Add play length of media files.
|
||||||
if item.is_media() and self.metaDataCheckBox.isChecked():
|
if item.is_media() and self.metaDataCheckBox.isChecked():
|
||||||
|
|
|
@ -781,48 +781,25 @@ class ServiceManager(QtGui.QWidget):
|
||||||
|
|
||||||
def onMoveSelectionUp(self):
|
def onMoveSelectionUp(self):
|
||||||
"""
|
"""
|
||||||
Moves the selection up the window. Called by the up arrow.
|
Moves the cursor selection up the window.
|
||||||
|
Called by the up arrow.
|
||||||
"""
|
"""
|
||||||
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
|
item = self.serviceManagerList.currentItem()
|
||||||
tempItem = None
|
itemBefore = self.serviceManagerList.itemAbove(item)
|
||||||
setLastItem = False
|
if itemBefore is None:
|
||||||
while serviceIterator.value():
|
return
|
||||||
if serviceIterator.value().isSelected() and tempItem is None:
|
self.serviceManagerList.setCurrentItem(itemBefore)
|
||||||
setLastItem = True
|
|
||||||
serviceIterator.value().setSelected(False)
|
|
||||||
if serviceIterator.value().isSelected():
|
|
||||||
# We are on the first record
|
|
||||||
if tempItem:
|
|
||||||
tempItem.setSelected(True)
|
|
||||||
serviceIterator.value().setSelected(False)
|
|
||||||
else:
|
|
||||||
tempItem = serviceIterator.value()
|
|
||||||
lastItem = serviceIterator.value()
|
|
||||||
serviceIterator += 1
|
|
||||||
# Top Item was selected so set the last one
|
|
||||||
if setLastItem:
|
|
||||||
lastItem.setSelected(True)
|
|
||||||
|
|
||||||
def onMoveSelectionDown(self):
|
def onMoveSelectionDown(self):
|
||||||
"""
|
"""
|
||||||
Moves the selection down the window. Called by the down arrow.
|
Moves the cursor selection down the window.
|
||||||
|
Called by the down arrow.
|
||||||
"""
|
"""
|
||||||
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
|
item = self.serviceManagerList.currentItem()
|
||||||
firstItem = None
|
itemAfter = self.serviceManagerList.itemBelow(item)
|
||||||
setSelected = False
|
if itemAfter is None:
|
||||||
while serviceIterator.value():
|
return
|
||||||
if not firstItem:
|
self.serviceManagerList.setCurrentItem(itemAfter)
|
||||||
firstItem = serviceIterator.value()
|
|
||||||
if setSelected:
|
|
||||||
setSelected = False
|
|
||||||
serviceIterator.value().setSelected(True)
|
|
||||||
elif serviceIterator.value() and \
|
|
||||||
serviceIterator.value().isSelected():
|
|
||||||
serviceIterator.value().setSelected(False)
|
|
||||||
setSelected = True
|
|
||||||
serviceIterator += 1
|
|
||||||
if setSelected:
|
|
||||||
firstItem.setSelected(True)
|
|
||||||
|
|
||||||
def onCollapseAll(self):
|
def onCollapseAll(self):
|
||||||
"""
|
"""
|
||||||
|
@ -966,7 +943,7 @@ class ServiceManager(QtGui.QWidget):
|
||||||
if item[u'service_item'] \
|
if item[u'service_item'] \
|
||||||
.is_capable(ItemCapabilities.AllowsVariableStartTime):
|
.is_capable(ItemCapabilities.AllowsVariableStartTime):
|
||||||
tips.append(item[u'service_item'].get_media_time())
|
tips.append(item[u'service_item'].get_media_time())
|
||||||
treewidgetitem.setToolTip(0, u'<br />'.join(tips))
|
treewidgetitem.setToolTip(0, u'<br>'.join(tips))
|
||||||
treewidgetitem.setData(0, QtCore.Qt.UserRole,
|
treewidgetitem.setData(0, QtCore.Qt.UserRole,
|
||||||
QtCore.QVariant(item[u'order']))
|
QtCore.QVariant(item[u'order']))
|
||||||
treewidgetitem.setSelected(item[u'selected'])
|
treewidgetitem.setSelected(item[u'selected'])
|
||||||
|
|
|
@ -29,7 +29,7 @@ The :mod:`settingsform` provides a user interface for the OpenLP settings
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, build_icon, PluginStatus
|
from openlp.core.lib import Receiver, build_icon, PluginStatus
|
||||||
from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab
|
from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab
|
||||||
|
|
|
@ -247,7 +247,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||||
alternate_label_text = action.defaultShortcuts[1].toString()
|
alternate_label_text = action.defaultShortcuts[1].toString()
|
||||||
shortcuts = self._actionShortcuts(action)
|
shortcuts = self._actionShortcuts(action)
|
||||||
# We do not want to loose pending changes, that is why we have to
|
# We do not want to loose pending changes, that is why we have to
|
||||||
# keep the text when, this function has not been triggered by a signal.
|
# keep the text when, this function has not been triggered by a
|
||||||
|
# signal.
|
||||||
if item is None:
|
if item is None:
|
||||||
primary_text = self.primaryPushButton.text()
|
primary_text = self.primaryPushButton.text()
|
||||||
alternate_text = self.alternatePushButton.text()
|
alternate_text = self.alternatePushButton.text()
|
||||||
|
@ -280,7 +281,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||||
"""
|
"""
|
||||||
Restores all default shortcuts.
|
Restores all default shortcuts.
|
||||||
"""
|
"""
|
||||||
if self.buttonBox.buttonRole(button) != QtGui.QDialogButtonBox.ResetRole:
|
if self.buttonBox.buttonRole(button) != \
|
||||||
|
QtGui.QDialogButtonBox.ResetRole:
|
||||||
return
|
return
|
||||||
if QtGui.QMessageBox.question(self,
|
if QtGui.QMessageBox.question(self,
|
||||||
translate('OpenLP.ShortcutListDialog', 'Restore Default Shortcuts'),
|
translate('OpenLP.ShortcutListDialog', 'Restore Default Shortcuts'),
|
||||||
|
|
|
@ -33,8 +33,8 @@ import copy
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
from PyQt4.phonon import Phonon
|
from PyQt4.phonon import Phonon
|
||||||
|
|
||||||
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
|
from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \
|
||||||
ItemCapabilities, translate, build_icon
|
translate, build_icon
|
||||||
from openlp.core.lib.ui import UiStrings, shortcut_action
|
from openlp.core.lib.ui import UiStrings, shortcut_action
|
||||||
from openlp.core.ui import HideMode, MainDisplay, ScreenList
|
from openlp.core.ui import HideMode, MainDisplay, ScreenList
|
||||||
from openlp.core.utils.actions import ActionList, CategoryOrder
|
from openlp.core.utils.actions import ActionList, CategoryOrder
|
||||||
|
@ -508,6 +508,11 @@ class SlideController(QtGui.QWidget):
|
||||||
self.mediabar.setVisible(False)
|
self.mediabar.setVisible(False)
|
||||||
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
||||||
self.toolbar.makeWidgetsInvisible(self.loopList)
|
self.toolbar.makeWidgetsInvisible(self.loopList)
|
||||||
|
# Reset the button
|
||||||
|
self.playSlidesOnce.setChecked(False)
|
||||||
|
self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png'))
|
||||||
|
self.playSlidesLoop.setChecked(False)
|
||||||
|
self.playSlidesLoop.setIcon(build_icon(u':/media/media_time.png'))
|
||||||
if item.is_text():
|
if item.is_text():
|
||||||
if QtCore.QSettings().value(
|
if QtCore.QSettings().value(
|
||||||
self.parent().songsSettingsSection + u'/display songbar',
|
self.parent().songsSettingsSection + u'/display songbar',
|
||||||
|
|
|
@ -459,25 +459,6 @@ def file_is_unicode(filename):
|
||||||
return None
|
return None
|
||||||
return ucsfile
|
return ucsfile
|
||||||
|
|
||||||
def string_is_unicode(test_string):
|
|
||||||
"""
|
|
||||||
Makes sure a string is unicode.
|
|
||||||
|
|
||||||
``test_string``
|
|
||||||
The string to confirm is unicode.
|
|
||||||
"""
|
|
||||||
return_string = u''
|
|
||||||
if not test_string:
|
|
||||||
return return_string
|
|
||||||
if isinstance(test_string, unicode):
|
|
||||||
return_string = test_string
|
|
||||||
if not isinstance(test_string, unicode):
|
|
||||||
try:
|
|
||||||
return_string = unicode(test_string, u'utf-8')
|
|
||||||
except UnicodeError:
|
|
||||||
log.exception("Error encoding string to unicode")
|
|
||||||
return return_string
|
|
||||||
|
|
||||||
def get_uno_command():
|
def get_uno_command():
|
||||||
"""
|
"""
|
||||||
Returns the UNO command to launch an openoffice.org instance.
|
Returns the UNO command to launch an openoffice.org instance.
|
||||||
|
@ -510,5 +491,5 @@ from actions import ActionList
|
||||||
|
|
||||||
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
||||||
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
||||||
u'ActionList', u'get_web_page', u'file_is_unicode', u'string_is_unicode',
|
u'ActionList', u'get_web_page', u'file_is_unicode', u'get_uno_command',
|
||||||
u'get_uno_command', u'get_uno_instance', u'delete_file']
|
u'get_uno_instance', u'delete_file']
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||||
from openlp.core.lib.db import Manager
|
from openlp.core.lib.db import Manager
|
||||||
|
@ -43,7 +43,7 @@ class AlertsPlugin(Plugin):
|
||||||
log.info(u'Alerts Plugin loaded')
|
log.info(u'Alerts Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Alerts', plugin_helpers,
|
Plugin.__init__(self, u'alerts', plugin_helpers,
|
||||||
settings_tab_class=AlertsTab)
|
settings_tab_class=AlertsTab)
|
||||||
self.weight = -3
|
self.weight = -3
|
||||||
self.icon_path = u':/plugins/plugin_alerts.png'
|
self.icon_path = u':/plugins/plugin_alerts.png'
|
||||||
|
|
|
@ -41,7 +41,7 @@ class BiblePlugin(Plugin):
|
||||||
log.info(u'Bible Plugin loaded')
|
log.info(u'Bible Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Bibles', plugin_helpers,
|
Plugin.__init__(self, u'bibles', plugin_helpers,
|
||||||
BibleMediaItem, BiblesTab)
|
BibleMediaItem, BiblesTab)
|
||||||
self.weight = -9
|
self.weight = -9
|
||||||
self.icon_path = u':/plugins/plugin_bibles.png'
|
self.icon_path = u':/plugins/plugin_bibles.png'
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
"""
|
"""
|
||||||
The bible import functions for OpenLP
|
The bible import functions for OpenLP
|
||||||
"""
|
"""
|
||||||
import csv
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -39,7 +38,7 @@ from openlp.core.lib import Receiver, translate
|
||||||
from openlp.core.lib.db import delete_database
|
from openlp.core.lib.db import delete_database
|
||||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||||
from openlp.core.utils import AppLocation, string_is_unicode
|
from openlp.core.utils import AppLocation
|
||||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB, clean_filename
|
from openlp.plugins.bibles.lib.db import BiblesResourcesDB, clean_filename
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ from openlp.core.lib.db import delete_database
|
||||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||||
from openlp.core.utils import AppLocation, delete_file
|
from openlp.core.utils import AppLocation, delete_file
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB,\
|
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB, \
|
||||||
BiblesResourcesDB, clean_filename
|
BiblesResourcesDB, clean_filename
|
||||||
from openlp.plugins.bibles.lib.http import BSExtract, BGExtract, CWExtract
|
from openlp.plugins.bibles.lib.http import BSExtract, BGExtract, CWExtract
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ from sqlalchemy import Column, ForeignKey, or_, Table, types
|
||||||
from sqlalchemy.orm import class_mapper, mapper, relation
|
from sqlalchemy.orm import class_mapper, mapper, relation
|
||||||
from sqlalchemy.orm.exc import UnmappedClassError
|
from sqlalchemy.orm.exc import UnmappedClassError
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate, check_directory_exists
|
from openlp.core.lib import Receiver, translate
|
||||||
from openlp.core.lib.db import BaseModel, init_db, Manager
|
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation
|
||||||
|
|
|
@ -29,9 +29,7 @@ The :mod:`http` module enables OpenLP to retrieve scripture from bible
|
||||||
websites.
|
websites.
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
import sqlite3
|
|
||||||
import socket
|
import socket
|
||||||
import urllib
|
import urllib
|
||||||
from HTMLParser import HTMLParseError
|
from HTMLParser import HTMLParseError
|
||||||
|
@ -40,7 +38,7 @@ from BeautifulSoup import BeautifulSoup, NavigableString, Tag
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.utils import AppLocation, get_web_page
|
from openlp.core.utils import get_web_page
|
||||||
from openlp.plugins.bibles.lib import SearchResults
|
from openlp.plugins.bibles.lib import SearchResults
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB, \
|
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB, \
|
||||||
Book
|
Book
|
||||||
|
|
|
@ -34,7 +34,7 @@ from openlp.core.lib import Receiver, SettingsManager, translate
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.utils import AppLocation, delete_file
|
from openlp.core.utils import AppLocation, delete_file
|
||||||
from openlp.plugins.bibles.lib import parse_reference
|
from openlp.plugins.bibles.lib import parse_reference
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB
|
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
|
||||||
from csvbible import CSVBible
|
from csvbible import CSVBible
|
||||||
from http import HTTPBible
|
from http import HTTPBible
|
||||||
from opensong import OpenSongBible
|
from opensong import OpenSongBible
|
||||||
|
|
|
@ -46,7 +46,7 @@ class CustomPlugin(Plugin):
|
||||||
log.info(u'Custom Plugin loaded')
|
log.info(u'Custom Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Custom', plugin_helpers,
|
Plugin.__init__(self, u'custom', plugin_helpers,
|
||||||
CustomMediaItem, CustomTab)
|
CustomMediaItem, CustomTab)
|
||||||
self.weight = -5
|
self.weight = -5
|
||||||
self.manager = Manager(u'custom', init_schema)
|
self.manager = Manager(u'custom', init_schema)
|
||||||
|
|
|
@ -36,7 +36,7 @@ class ImagePlugin(Plugin):
|
||||||
log.info(u'Image Plugin loaded')
|
log.info(u'Image Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Images', plugin_helpers, ImageMediaItem)
|
Plugin.__init__(self, u'images', plugin_helpers, ImageMediaItem)
|
||||||
self.weight = -7
|
self.weight = -7
|
||||||
self.icon_path = u':/plugins/plugin_images.png'
|
self.icon_path = u':/plugins/plugin_images.png'
|
||||||
self.icon = build_icon(self.icon_path)
|
self.icon = build_icon(self.icon_path)
|
||||||
|
|
|
@ -39,7 +39,7 @@ class MediaPlugin(Plugin):
|
||||||
log.info(u'%s MediaPlugin loaded', __name__)
|
log.info(u'%s MediaPlugin loaded', __name__)
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Media', plugin_helpers,
|
Plugin.__init__(self, u'media', plugin_helpers,
|
||||||
MediaMediaItem, MediaTab)
|
MediaMediaItem, MediaTab)
|
||||||
self.weight = -6
|
self.weight = -6
|
||||||
self.icon_path = u':/plugins/plugin_media.png'
|
self.icon_path = u':/plugins/plugin_media.png'
|
||||||
|
|
|
@ -52,7 +52,7 @@ class PresentationPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
log.debug(u'Initialised')
|
log.debug(u'Initialised')
|
||||||
self.controllers = {}
|
self.controllers = {}
|
||||||
Plugin.__init__(self, u'Presentations', plugin_helpers)
|
Plugin.__init__(self, u'presentations', plugin_helpers)
|
||||||
self.weight = -8
|
self.weight = -8
|
||||||
self.icon_path = u':/plugins/plugin_presentations.png'
|
self.icon_path = u':/plugins/plugin_presentations.png'
|
||||||
self.icon = build_icon(self.icon_path)
|
self.icon = build_icon(self.icon_path)
|
||||||
|
|
|
@ -357,7 +357,8 @@ class HttpConnection(object):
|
||||||
if ext == u'.html':
|
if ext == u'.html':
|
||||||
mimetype = u'text/html'
|
mimetype = u'text/html'
|
||||||
variables = self.template_vars
|
variables = self.template_vars
|
||||||
html = Template(filename=path, input_encoding=u'utf-8', output_encoding=u'utf-8').render(**variables)
|
html = Template(filename=path, input_encoding=u'utf-8',
|
||||||
|
output_encoding=u'utf-8').render(**variables)
|
||||||
elif ext == u'.css':
|
elif ext == u'.css':
|
||||||
mimetype = u'text/css'
|
mimetype = u'text/css'
|
||||||
elif ext == u'.js':
|
elif ext == u'.js':
|
||||||
|
|
|
@ -39,7 +39,7 @@ class RemotesPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
remotes constructor
|
remotes constructor
|
||||||
"""
|
"""
|
||||||
Plugin.__init__(self, u'Remotes', plugin_helpers,
|
Plugin.__init__(self, u'remotes', plugin_helpers,
|
||||||
settings_tab_class=RemoteTab)
|
settings_tab_class=RemoteTab)
|
||||||
self.icon_path = u':/plugins/plugin_remote.png'
|
self.icon_path = u':/plugins/plugin_remote.png'
|
||||||
self.icon = build_icon(self.icon_path)
|
self.icon = build_icon(self.icon_path)
|
||||||
|
|
|
@ -90,7 +90,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
||||||
self.onVerseListViewPressed)
|
self.onVerseListViewPressed)
|
||||||
QtCore.QObject.connect(self.themeAddButton,
|
QtCore.QObject.connect(self.themeAddButton,
|
||||||
QtCore.SIGNAL(u'clicked()'),
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
self.mediaitem.plugin.renderer.theme_manager.onAddTheme)
|
self.mediaitem.plugin.renderer.themeManager.onAddTheme)
|
||||||
QtCore.QObject.connect(self.maintenanceButton,
|
QtCore.QObject.connect(self.maintenanceButton,
|
||||||
QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
|
QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
|
|
@ -29,7 +29,7 @@ The :mod:`db` module provides the database and schema that is the backend for
|
||||||
the Songs plugin
|
the Songs plugin
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from sqlalchemy import Column, ForeignKey, Index, Table, types
|
from sqlalchemy import Column, ForeignKey, Table, types
|
||||||
from sqlalchemy.orm import mapper, relation
|
from sqlalchemy.orm import mapper, relation
|
||||||
|
|
||||||
from openlp.core.lib.db import BaseModel, init_db
|
from openlp.core.lib.db import BaseModel, init_db
|
||||||
|
|
|
@ -26,13 +26,10 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from lxml import etree, objectify
|
from lxml import etree, objectify
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
|
||||||
from openlp.plugins.songs.lib import VerseType
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ import struct
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
|
||||||
from openlp.plugins.songs.lib import VerseType
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib import retrieve_windows_encoding
|
from openlp.plugins.songs.lib import retrieve_windows_encoding
|
||||||
from songimport import SongImport
|
from songimport import SongImport
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
from zipfile import ZipFile
|
|
||||||
|
|
||||||
from lxml import objectify
|
from lxml import objectify
|
||||||
from lxml.etree import Error, LxmlError
|
from lxml.etree import Error, LxmlError
|
||||||
|
@ -110,45 +108,10 @@ class OpenSongImport(SongImport):
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
|
||||||
def do_import(self):
|
def do_import(self):
|
||||||
"""
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
Import either each of the files in self.import_source - each element of
|
|
||||||
which can be either a single opensong file, or a zipfile containing
|
|
||||||
multiple opensong files.
|
|
||||||
"""
|
|
||||||
numfiles = 0
|
|
||||||
for filename in self.import_source:
|
|
||||||
ext = os.path.splitext(filename)[1]
|
|
||||||
if ext.lower() == u'.zip':
|
|
||||||
z = ZipFile(filename, u'r')
|
|
||||||
numfiles += len(z.infolist())
|
|
||||||
z.close()
|
|
||||||
else:
|
|
||||||
numfiles += 1
|
|
||||||
log.debug(u'Total number of files: %d', numfiles)
|
|
||||||
self.import_wizard.progressBar.setMaximum(numfiles)
|
|
||||||
for filename in self.import_source:
|
for filename in self.import_source:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
return
|
return
|
||||||
ext = os.path.splitext(filename)[1]
|
|
||||||
if ext.lower() == u'.zip':
|
|
||||||
log.debug(u'Zipfile found %s', filename)
|
|
||||||
z = ZipFile(filename, u'r')
|
|
||||||
for song in z.infolist():
|
|
||||||
if self.stop_import_flag:
|
|
||||||
z.close()
|
|
||||||
return
|
|
||||||
parts = os.path.split(song.filename)
|
|
||||||
if parts[-1] == u'':
|
|
||||||
# No final part => directory
|
|
||||||
continue
|
|
||||||
log.info(u'Zip importing %s', parts[-1])
|
|
||||||
song_file = z.open(song)
|
|
||||||
self.do_import_file(song_file)
|
|
||||||
song_file.close()
|
|
||||||
z.close()
|
|
||||||
else:
|
|
||||||
# not a zipfile
|
|
||||||
log.info(u'Direct import %s', filename)
|
|
||||||
song_file = open(filename)
|
song_file = open(filename)
|
||||||
self.do_import_file(song_file)
|
self.do_import_file(song_file)
|
||||||
song_file.close()
|
song_file.close()
|
||||||
|
|
|
@ -36,7 +36,6 @@ import re
|
||||||
|
|
||||||
from openlp.plugins.songs.lib import VerseType
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
from openlp.plugins.songs.lib.ui import SongStrings
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,8 @@ import re
|
||||||
|
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate, check_directory_exists
|
from openlp.core.lib import Receiver, translate
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
from openlp.core.utils import AppLocation
|
|
||||||
from openlp.plugins.songs.lib import clean_song, VerseType
|
from openlp.plugins.songs.lib import clean_song, VerseType
|
||||||
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile
|
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile
|
||||||
from openlp.plugins.songs.lib.ui import SongStrings
|
from openlp.plugins.songs.lib.ui import SongStrings
|
||||||
|
|
|
@ -31,7 +31,6 @@ Worship songs into the OpenLP database.
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
BLOCK_TYPES = (u'V', u'C', u'B')
|
BLOCK_TYPES = (u'V', u'C', u'B')
|
||||||
|
|
|
@ -57,7 +57,7 @@ class SongsPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
Create and set up the Songs plugin.
|
Create and set up the Songs plugin.
|
||||||
"""
|
"""
|
||||||
Plugin.__init__(self, u'Songs', plugin_helpers, SongMediaItem, SongsTab)
|
Plugin.__init__(self, u'songs', plugin_helpers, SongMediaItem, SongsTab)
|
||||||
self.weight = -10
|
self.weight = -10
|
||||||
self.manager = Manager(u'songs', init_schema)
|
self.manager = Manager(u'songs', init_schema)
|
||||||
self.icon_path = u':/plugins/plugin_songs.png'
|
self.icon_path = u':/plugins/plugin_songs.png'
|
||||||
|
|
|
@ -33,7 +33,7 @@ from PyQt4 import QtCore, QtGui
|
||||||
from openlp.core.lib import Plugin, StringContent, Receiver, build_icon, \
|
from openlp.core.lib import Plugin, StringContent, Receiver, build_icon, \
|
||||||
translate
|
translate
|
||||||
from openlp.core.lib.db import Manager
|
from openlp.core.lib.db import Manager
|
||||||
from openlp.core.lib.ui import base_action, shortcut_action, UiStrings
|
from openlp.core.lib.ui import base_action, shortcut_action
|
||||||
from openlp.core.utils.actions import ActionList
|
from openlp.core.utils.actions import ActionList
|
||||||
from openlp.plugins.songusage.forms import SongUsageDetailForm, \
|
from openlp.plugins.songusage.forms import SongUsageDetailForm, \
|
||||||
SongUsageDeleteForm
|
SongUsageDeleteForm
|
||||||
|
@ -45,7 +45,7 @@ class SongUsagePlugin(Plugin):
|
||||||
log.info(u'SongUsage Plugin loaded')
|
log.info(u'SongUsage Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'SongUsage', plugin_helpers)
|
Plugin.__init__(self, u'songusage', plugin_helpers)
|
||||||
self.weight = -4
|
self.weight = -4
|
||||||
self.icon = build_icon(u':/plugins/plugin_songusage.png')
|
self.icon = build_icon(u':/plugins/plugin_songusage.png')
|
||||||
self.activeIcon = build_icon(u':/songusage/song_usage_active.png')
|
self.activeIcon = build_icon(u':/songusage/song_usage_active.png')
|
||||||
|
|
|
@ -5,7 +5,12 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# OpenLP - Open Source Lyrics Projection #
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
# --------------------------------------------------------------------------- #
|
# --------------------------------------------------------------------------- #
|
||||||
# Copyright (c) 2011 Raoul Snyman #
|
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
|
||||||
|
# Armin Köhler, Joshua Millar, 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 #
|
# 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 #
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
|
|
@ -46,12 +46,6 @@ PyEnchant
|
||||||
Inno Setup 5
|
Inno Setup 5
|
||||||
Inno Setup should be installed into "C:\%PROGRAMFILES%\Inno Setup 5"
|
Inno Setup should be installed into "C:\%PROGRAMFILES%\Inno Setup 5"
|
||||||
|
|
||||||
UPX
|
|
||||||
This is used to compress DLLs and EXEs so that they take up less space, but
|
|
||||||
still function exactly the same. To install UPX, download it from
|
|
||||||
http://upx.sourceforge.net/, extract it into C:\%PROGRAMFILES%\UPX, and then
|
|
||||||
add that directory to your PATH environment variable.
|
|
||||||
|
|
||||||
Sphinx
|
Sphinx
|
||||||
This is used to build the documentation. The documentation trunk must be at
|
This is used to build the documentation. The documentation trunk must be at
|
||||||
the same directory level as Openlp trunk and named "documentation"
|
the same directory level as Openlp trunk and named "documentation"
|
||||||
|
@ -179,6 +173,7 @@ def run_pyinstaller():
|
||||||
pyinstaller = Popen((python_exe, pyi_build,
|
pyinstaller = Popen((python_exe, pyi_build,
|
||||||
u'--noconfirm',
|
u'--noconfirm',
|
||||||
u'--windowed',
|
u'--windowed',
|
||||||
|
u'--noupx',
|
||||||
u'-o', branch_path,
|
u'-o', branch_path,
|
||||||
u'-i', win32_icon,
|
u'-i', win32_icon,
|
||||||
u'-p', branch_path,
|
u'-p', branch_path,
|
||||||
|
|
Loading…
Reference in New Issue