This commit is contained in:
Jonathan Corwin 2010-09-25 11:41:31 +01:00
commit ba576f6426
50 changed files with 7667 additions and 6159 deletions

View File

@ -162,18 +162,18 @@ def main():
the PyQt4 Application. the PyQt4 Application.
""" """
# Set up command line options. # Set up command line options.
usage = u'Usage: %prog [options] [qt-options]' usage = 'Usage: %prog [options] [qt-options]'
parser = OptionParser(usage=usage) parser = OptionParser(usage=usage)
parser.add_option(u'-e', u'--no-error-form', dest=u'no_error_form', parser.add_option('-e', '--no-error-form', dest='no_error_form',
action=u'store_true', help=u'Disable the error notification form.') action='store_true', help='Disable the error notification form.')
parser.add_option(u'-l', u'--log-level', dest=u'loglevel', parser.add_option('-l', '--log-level', dest='loglevel',
default=u'warning', metavar=u'LEVEL', help=u'Set logging to LEVEL ' default='warning', metavar='LEVEL', help='Set logging to LEVEL '
u'level. Valid values are "debug", "info", "warning".') 'level. Valid values are "debug", "info", "warning".')
parser.add_option(u'-p', u'--portable', dest=u'portable', parser.add_option('-p', '--portable', dest='portable',
action=u'store_true', help=u'Specify if this should be run as a ' action='store_true', help='Specify if this should be run as a '
u'portable app, off a USB flash drive (not implemented).') 'portable app, off a USB flash drive (not implemented).')
parser.add_option(u'-s', u'--style', dest=u'style', parser.add_option('-s', '--style', dest='style',
help=u'Set the Qt4 style (passed directly to Qt4).') help='Set the Qt4 style (passed directly to Qt4).')
# Set up logging # Set up logging
log_path = AppLocation.get_directory(AppLocation.CacheDir) log_path = AppLocation.get_directory(AppLocation.CacheDir)
if not os.path.exists(log_path): if not os.path.exists(log_path):

View File

@ -220,6 +220,7 @@ def image_to_byte(image):
``image`` ``image``
The image to converted. The image to converted.
""" """
log.debug(u'image_to_byte')
byte_array = QtCore.QByteArray() byte_array = QtCore.QByteArray()
# use buffer to store pixmap into byteArray # use buffer to store pixmap into byteArray
buffie = QtCore.QBuffer(byte_array) buffie = QtCore.QBuffer(byte_array)
@ -249,6 +250,7 @@ def resize_image(image, width, height, background=QtCore.Qt.black):
The background colour defaults to black. The background colour defaults to black.
""" """
log.debug(u'resize_image')
preview = QtGui.QImage(image) preview = QtGui.QImage(image)
if not preview.isNull(): if not preview.isNull():
# Only resize if different size # Only resize if different size

View File

@ -27,8 +27,6 @@
import logging import logging
from PyQt4 import QtWebKit from PyQt4 import QtWebKit
from openlp.core.lib import image_to_byte
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
HTMLSRC = u""" HTMLSRC = u"""
@ -60,7 +58,10 @@ body {
#image { #image {
z-index:1; z-index:1;
} }
#video { #video1 {
z-index:2;
}
#video2 {
z-index:2; z-index:2;
} }
#alert { #alert {
@ -82,54 +83,12 @@ body {
<script language="javascript"> <script language="javascript">
var timer = null; var timer = null;
var video_timer = null; var video_timer = null;
var current_video = '1';
var transition = %s; var transition = %s;
function show_video(state, path, volume, loop){ function show_video(state, path, volume, loop){
var vid = document.getElementById('video'); // Note, the preferred method for looping would be to use the
if(path != null){ // video tag loop attribute.
vid.src = path;
vid.load();
}
if(volume != null){
vid.volume = volume;
}
switch(state){
case 'play':
vid.play();
vid.style.display = 'block';
if(loop)
video_timer = setInterval('video_loop()', 200);
break;
case 'pause':
if(video_timer!=null){
clearInterval(video_timer);
video_timer = null;
}
vid.pause();
vid.style.display = 'block';
break;
case 'stop':
if(video_timer!=null){
clearInterval(video_timer);
video_timer = null;
}
vid.pause();
vid.style.display = 'none';
vid.load();
break;
case 'close':
if(video_timer!=null){
clearInterval(video_timer);
video_timer = null;
}
vid.pause();
vid.style.display = 'none';
vid.src = '';
break;
}
}
function video_loop(){
// The preferred method would be to use the video tag loop attribute
// But QtWebKit doesn't support this. Neither does it support the // But QtWebKit doesn't support this. Neither does it support the
// onended event, hence the setInterval() // onended event, hence the setInterval()
// In addition, setting the currentTime attribute to zero to restart // In addition, setting the currentTime attribute to zero to restart
@ -140,12 +99,73 @@ body {
// Note, currently the background may go black between loops. Not // Note, currently the background may go black between loops. Not
// desirable. Need to investigate using two <video>'s, and hiding/ // desirable. Need to investigate using two <video>'s, and hiding/
// preloading one, and toggle between the two when looping. // preloading one, and toggle between the two when looping.
var vid = document.getElementById('video');
if(vid.ended||vid.currentTime+0.2>=vid.duration){ if(current_video=='1'){
vid.load(); var vid = document.getElementById('video1');
vid.play(); var vid2 = document.getElementById('video2');
} else {
var vid = document.getElementById('video2');
var vid2 = document.getElementById('video1');
}
if(volume != null){
vid.volume = volume;
vid2.volume = volume;
}
switch(state){
case 'init':
vid.src = path;
vid2.src = path;
if(loop == null) loop = false;
vid.looping = loop;
vid2.looping = loop;
vid.load();
break;
case 'load':
vid2.style.visibility = 'hidden';
vid2.load();
break;
case 'play':
vid.play();
vid.style.visibility = 'visible';
if(vid.looping){
video_timer = setInterval(
function() {
show_video('poll');
}, 200);
}
break;
case 'pause':
if(video_timer!=null){
clearInterval(video_timer);
video_timer = null;
}
vid.pause();
break;
case 'stop':
show_video('pause');
vid.style.visibility = 'hidden';
break;
case 'poll':
if(vid.ended||vid.currentTime+0.2>vid.duration)
show_video('swap');
break;
case 'swap':
show_video('pause');
if(current_video=='1')
current_video = '2';
else
current_video = '1';
show_video('play');
show_video('load');
break;
case 'close':
show_video('stop');
vid.src = '';
vid2.src = '';
break;
} }
} }
function show_image(src){ function show_image(src){
var img = document.getElementById('image'); var img = document.getElementById('image');
img.src = src; img.src = src;
@ -274,8 +294,11 @@ body {
</script> </script>
</head> </head>
<body> <body>
<img id="image" class="size" src="%s" /> <img id="image" class="size" %s />
<video id="video" class="size"></video> <video id="video1" class="size" style="visibility:hidden" autobuffer preload>
</video>
<video id="video2" class="size" style="visibility:hidden" autobuffer preload>
</video>
%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>
@ -301,10 +324,10 @@ def build_html(item, screen, alert, islive):
height = screen[u'size'].height() height = screen[u'size'].height()
theme = item.themedata theme = item.themedata
webkitvers = webkit_version() webkitvers = webkit_version()
if item.bg_frame: if item.bg_image_bytes:
image = u'data:image/png;base64,%s' % image_to_byte(item.bg_frame) image = u'src="data:image/png;base64,%s"' % item.bg_image_bytes
else: else:
image = u'' image = u'style="display:none;"'
html = HTMLSRC % (build_background_css(item, width, height), html = HTMLSRC % (build_background_css(item, width, height),
width, height, width, height,
build_alert_css(alert, width), build_alert_css(alert, width),
@ -426,8 +449,10 @@ def build_lyrics_css(item, webkitvers):
outline = build_lyrics_outline_css(theme) outline = build_lyrics_outline_css(theme)
if theme.display_shadow: if theme.display_shadow:
if theme.display_outline and webkitvers < 534.3: if theme.display_outline and webkitvers < 534.3:
shadow = u'padding-left: %spx; padding-top: %spx ' % \ shadow = u'padding-left: %spx; padding-top: %spx;' % \
(theme.display_shadow_size, theme.display_shadow_size) (int(theme.display_shadow_size) +
(int(theme.display_outline_size) * 2),
theme.display_shadow_size)
shadow += build_lyrics_outline_css(theme, True) shadow += build_lyrics_outline_css(theme, True)
else: else:
lyricsmain += u' text-shadow: %s %spx %spx;' % \ lyricsmain += u' text-shadow: %s %spx %spx;' % \
@ -487,13 +512,17 @@ def build_lyrics_format_css(theme, width, height):
valign = u'middle' valign = u'middle'
else: else:
valign = u'top' valign = u'top'
if theme.display_outline:
left_margin = int(theme.display_outline_size) * 2
else:
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%%; ' \ 'font-size: %spt; color: %s; line-height: %d%%; margin:0;' \
'margin:0; padding:0; width: %spx; height: %spx; ' % \ 'padding:0; padding-left:%spx; width: %spx; height: %spx; ' % \
(align, valign, theme.font_main_name, theme.font_main_proportion, (align, valign, theme.font_main_name, theme.font_main_proportion,
theme.font_main_color, 100 + int(theme.font_main_line_adjustment), theme.font_main_color, 100 + int(theme.font_main_line_adjustment),
width, height) left_margin, width, height)
if theme.display_outline: if theme.display_outline:
if webkit_version() < 534.3: if webkit_version() < 534.3:
lyrics += u' letter-spacing: 1px;' lyrics += u' letter-spacing: 1px;'

View File

@ -32,7 +32,8 @@ import logging
from PyQt4 import QtGui, QtCore, QtWebKit from PyQt4 import QtGui, QtCore, QtWebKit
from openlp.core.lib import resize_image, expand_tags, \ from openlp.core.lib import resize_image, expand_tags, \
build_lyrics_format_css, build_lyrics_outline_css build_lyrics_format_css, build_lyrics_outline_css, image_to_byte
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -54,6 +55,7 @@ class Renderer(object):
self.frame = None self.frame = None
self.bg_frame = None self.bg_frame = None
self.bg_image = None self.bg_image = None
self.bg_image_bytes = None
def set_theme(self, theme): def set_theme(self, theme):
""" """
@ -66,15 +68,12 @@ class Renderer(object):
self._theme = theme self._theme = theme
self.bg_frame = None self.bg_frame = None
self.bg_image = None self.bg_image = None
self.bg_image_bytes = None
self._bg_image_filename = None self._bg_image_filename = None
self.theme_name = theme.theme_name self.theme_name = theme.theme_name
if theme.background_type == u'image': if theme.background_type == u'image':
if theme.background_filename: if theme.background_filename:
self._bg_image_filename = unicode(theme.background_filename) self._bg_image_filename = unicode(theme.background_filename)
if self.frame:
self.bg_image = resize_image(self._bg_image_filename,
self.frame.width(),
self.frame.height())
def set_text_rectangle(self, rect_main, rect_footer): def set_text_rectangle(self, rect_main, rect_footer):
""" """
@ -89,6 +88,22 @@ class Renderer(object):
log.debug(u'set_text_rectangle %s , %s' % (rect_main, rect_footer)) log.debug(u'set_text_rectangle %s , %s' % (rect_main, rect_footer))
self._rect = rect_main self._rect = rect_main
self._rect_footer = rect_footer self._rect_footer = rect_footer
self.page_width = self._rect.width()
self.page_height = self._rect.height()
if self._theme.display_shadow:
self.page_width -= int(self._theme.display_shadow_size)
self.page_height -= int(self._theme.display_shadow_size)
self.web = QtWebKit.QWebView()
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
self.page_shell = u'<html><head><style>' \
u'*{margin: 0; padding: 0; border: 0;} '\
u'#main {position:absolute; top:0px; %s %s}</style><body>' \
u'<div id="main">' % \
(build_lyrics_format_css(self._theme, self.page_width,
self.page_height), build_lyrics_outline_css(self._theme))
def set_frame_dest(self, frame_width, frame_height): def set_frame_dest(self, frame_width, frame_height):
""" """
@ -110,15 +125,18 @@ class Renderer(object):
self.frame.width(), self.frame.height()) self.frame.width(), self.frame.height())
if self._theme.background_type == u'image': if self._theme.background_type == u'image':
self.bg_frame = QtGui.QImage(self.frame.width(), self.bg_frame = QtGui.QImage(self.frame.width(),
self.frame.height(), QtGui.QImage.Format_ARGB32_Premultiplied) self.frame.height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
painter = QtGui.QPainter() painter = QtGui.QPainter()
painter.begin(self.bg_frame) painter.begin(self.bg_frame)
painter.fillRect(self.frame.rect(), QtCore.Qt.black) painter.fillRect(self.frame.rect(), QtCore.Qt.black)
if self.bg_image: if self.bg_image:
painter.drawImage(0, 0, self.bg_image) painter.drawImage(0, 0, self.bg_image)
painter.end() painter.end()
self.bg_image_bytes = image_to_byte(self.bg_frame)
else: else:
self.bg_frame = None self.bg_frame = None
self.bg_image_bytes = None
def format_slide(self, words, line_break): def format_slide(self, words, line_break):
""" """
@ -139,29 +157,16 @@ class Renderer(object):
lines = verse.split(u'\n') lines = verse.split(u'\n')
for line in lines: for line in lines:
text.append(line) text.append(line)
web = QtWebKit.QWebView()
web.resize(self._rect.width(), self._rect.height())
web.setVisible(False)
frame = web.page().mainFrame()
# Adjust width and height to account for shadow. outline done in css
width = self._rect.width() - int(self._theme.display_shadow_size)
height = self._rect.height() - int(self._theme.display_shadow_size)
shell = u'<html><head><style>#main {%s %s}</style><body>' \
u'<div id="main">' % \
(build_lyrics_format_css(self._theme, width, height),
build_lyrics_outline_css(self._theme))
formatted = [] formatted = []
html_text = u'' html_text = u''
styled_text = u'' styled_text = u''
js_height = 'document.getElementById("main").scrollHeight'
for line in text: for line in text:
styled_line = expand_tags(line) + line_end styled_line = expand_tags(line) + line_end
styled_text += styled_line styled_text += styled_line
html = shell + styled_text + u'</div></body></html>' html = self.page_shell + styled_text + u'</div></body></html>'
web.setHtml(html) self.web.setHtml(html)
# Text too long so go to next page # Text too long so go to next page
text_height = int(frame.evaluateJavaScript(js_height).toString()) if self.web_frame.contentsSize().height() > self.page_height:
if text_height > height:
formatted.append(html_text) formatted.append(html_text)
html_text = u'' html_text = u''
styled_text = styled_line styled_text = styled_line

View File

@ -223,7 +223,6 @@ class RenderManager(object):
The words to go on the slides. The words to go on the slides.
""" """
log.debug(u'format slide') log.debug(u'format slide')
self.build_text_rectangle(self.themedata)
return self.renderer.format_slide(words, line_break) return self.renderer.format_slide(words, line_break)
def calculate_default(self, screen): def calculate_default(self, screen):

View File

@ -97,7 +97,7 @@ class ServiceItem(object):
self.themedata = None self.themedata = None
self.main = None self.main = None
self.footer = None self.footer = None
self.bg_frame = None self.bg_image_bytes = None
def _new_item(self): def _new_item(self):
""" """
@ -145,7 +145,7 @@ class ServiceItem(object):
""" """
log.debug(u'Render called') log.debug(u'Render called')
self._display_frames = [] self._display_frames = []
self.bg_frame = None self.bg_image_bytes = None
line_break = True line_break = True
if self.is_capable(ItemCapabilities.NoLineBreaks): if self.is_capable(ItemCapabilities.NoLineBreaks):
line_break = False line_break = False
@ -156,7 +156,7 @@ class ServiceItem(object):
theme = self.theme theme = self.theme
self.main, self.footer = \ self.main, self.footer = \
self.render_manager.set_override_theme(theme, useOverride) self.render_manager.set_override_theme(theme, useOverride)
self.bg_frame = self.render_manager.renderer.bg_frame self.bg_image_bytes = self.render_manager.renderer.bg_image_bytes
self.themedata = self.render_manager.renderer._theme self.themedata = self.render_manager.renderer._theme
for slide in self._raw_frames: for slide in self._raw_frames:
before = time.time() before = time.time()

View File

@ -28,6 +28,7 @@ import re
import sys import sys
try: try:
import enchant import enchant
from enchant import DictNotFoundError
enchant_available = True enchant_available = True
except ImportError: except ImportError:
enchant_available = False enchant_available = False
@ -43,7 +44,10 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
QtGui.QPlainTextEdit.__init__(self, *args) QtGui.QPlainTextEdit.__init__(self, *args)
# Default dictionary based on the current locale. # Default dictionary based on the current locale.
if enchant_available: if enchant_available:
self.dict = enchant.Dict() try:
self.dict = enchant.Dict()
except DictNotFoundError:
self.dict = enchant.Dict(u'en_US')
self.highlighter = Highlighter(self.document()) self.highlighter = Highlighter(self.document())
self.highlighter.setDict(self.dict) self.highlighter.setDict(self.dict)

View File

@ -99,6 +99,7 @@ class MainDisplay(DisplayWidget):
self.alertTab = None self.alertTab = None
self.hide_mode = None self.hide_mode = None
self.setWindowTitle(u'OpenLP Display') self.setWindowTitle(u'OpenLP Display')
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | self.setWindowFlags(QtCore.Qt.FramelessWindowHint |
QtCore.Qt.WindowStaysOnTopHint) QtCore.Qt.WindowStaysOnTopHint)
if self.isLive: if self.isLive:
@ -116,12 +117,18 @@ class MainDisplay(DisplayWidget):
self.screen = self.screens.current self.screen = self.screens.current
self.setVisible(False) self.setVisible(False)
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
self.scene = QtGui.QGraphicsScene() try:
self.setScene(self.scene) self.webView = QtWebKit.QGraphicsWebView()
self.webView = QtWebKit.QGraphicsWebView() self.scene = QtGui.QGraphicsScene(self)
self.scene.addItem(self.webView) self.setScene(self.scene)
self.webView.resize(self.screen[u'size'].width(), self.scene.addItem(self.webView)
self.screen[u'size'].height()) self.webView.setGeometry(QtCore.QRectF(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height()))
except AttributeError:
# QGraphicsWebView a recent addition, so fall back to QWebView
self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height())
self.page = self.webView.page() self.page = self.webView.page()
self.frame = self.page.mainFrame() self.frame = self.page.mainFrame()
QtCore.QObject.connect(self.webView, QtCore.QObject.connect(self.webView,
@ -157,7 +164,7 @@ class MainDisplay(DisplayWidget):
- splash_image.height()) / 2, - splash_image.height()) / 2,
splash_image) splash_image)
serviceItem = ServiceItem() serviceItem = ServiceItem()
serviceItem.bg_frame = initialFrame serviceItem.bg_image_bytes = image_to_byte(initialFrame)
self.webView.setHtml(build_html(serviceItem, self.screen, self.webView.setHtml(build_html(serviceItem, self.screen,
self.parent.alertTab, self.isLive)) self.parent.alertTab, self.isLive))
self.initialFrame = True self.initialFrame = True
@ -176,6 +183,9 @@ class MainDisplay(DisplayWidget):
The slide text to be displayed The slide text to be displayed
""" """
log.debug(u'text') log.debug(u'text')
# Wait for the webview to update before displayiong text.
while not self.loaded:
Receiver.send_message(u'openlp_process_events')
self.frame.evaluateJavaScript(u'show_text("%s")' % \ self.frame.evaluateJavaScript(u'show_text("%s")' % \
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"')) slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
return self.preview() return self.preview()
@ -227,8 +237,11 @@ class MainDisplay(DisplayWidget):
Display an image, as is. Display an image, as is.
""" """
if image: if image:
js = u'show_image("data:image/png;base64,%s");' % \ if isinstance(image, QtGui.QImage):
image_to_byte(image) js = u'show_image("data:image/png;base64,%s");' % \
image_to_byte(image)
else:
js = u'show_image("data:image/png;base64,%s");' % image
else: else:
js = u'show_image("");' js = u'show_image("");'
self.frame.evaluateJavaScript(js) self.frame.evaluateJavaScript(js)
@ -239,7 +252,7 @@ class MainDisplay(DisplayWidget):
Used after Image plugin has changed the background Used after Image plugin has changed the background
""" """
log.debug(u'resetImage') log.debug(u'resetImage')
self.displayImage(self.serviceItem.bg_frame) self.displayImage(self.serviceItem.bg_image_bytes)
def resetVideo(self): def resetVideo(self):
""" """
@ -286,7 +299,7 @@ class MainDisplay(DisplayWidget):
""" """
log.debug(u'video') log.debug(u'video')
self.loaded = True self.loaded = True
js = u'show_video("play", "%s", %s, true);' % \ js = u'show_video("init", "%s", %s, true); show_video("play");' % \
(videoPath.replace(u'\\', u'\\\\'), str(float(volume)/float(10))) (videoPath.replace(u'\\', u'\\\\'), str(float(volume)/float(10)))
self.frame.evaluateJavaScript(js) self.frame.evaluateJavaScript(js)
return self.preview() return self.preview()
@ -306,6 +319,7 @@ class MainDisplay(DisplayWidget):
# We must have a service item to preview # We must have a service item to preview
if not hasattr(self, u'serviceItem'): if not hasattr(self, u'serviceItem'):
return return
Receiver.send_message(u'openlp_process_events')
if self.isLive: if self.isLive:
# Wait for the fade to finish before geting the preview. # Wait for the fade to finish before geting the preview.
# Important otherwise preview will have incorrect text if at all ! # Important otherwise preview will have incorrect text if at all !
@ -318,6 +332,12 @@ class MainDisplay(DisplayWidget):
# Important otherwise first preview will miss the background ! # Important otherwise first preview will miss the background !
while not self.loaded: while not self.loaded:
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
# if was hidden keep it hidden
if self.isLive:
self.setVisible(True)
# if was hidden keep it hidden
if self.hide_mode and self.isLive:
self.hideDisplay(self.hide_mode)
preview = QtGui.QImage(self.screen[u'size'].width(), preview = QtGui.QImage(self.screen[u'size'].width(),
self.screen[u'size'].height(), self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied) QtGui.QImage.Format_ARGB32_Premultiplied)
@ -325,9 +345,6 @@ class MainDisplay(DisplayWidget):
painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.setRenderHint(QtGui.QPainter.Antialiasing)
self.frame.render(painter) self.frame.render(painter)
painter.end() painter.end()
# Make display show up if in single screen mode
if self.isLive:
self.setVisible(True)
return preview return preview
def buildHtml(self, serviceItem): def buildHtml(self, serviceItem):
@ -341,7 +358,9 @@ class MainDisplay(DisplayWidget):
self.serviceItem = serviceItem self.serviceItem = serviceItem
html = build_html(self.serviceItem, self.screen, self.parent.alertTab, html = build_html(self.serviceItem, self.screen, self.parent.alertTab,
self.isLive) self.isLive)
log.debug(u'buildHtml - pre setHtml')
self.webView.setHtml(html) self.webView.setHtml(html)
log.debug(u'buildHtml - post setHtml')
if serviceItem.foot_text and serviceItem.foot_text: if serviceItem.foot_text and serviceItem.foot_text:
self.footer(serviceItem.foot_text) self.footer(serviceItem.foot_text)
# if was hidden keep it hidden # if was hidden keep it hidden

View File

@ -343,7 +343,7 @@ class Ui_MainWindow(object):
Set up the translation system Set up the translation system
""" """
MainWindow.mainTitle = translate('OpenLP.MainWindow', 'OpenLP 2.0') MainWindow.mainTitle = translate('OpenLP.MainWindow', 'OpenLP 2.0')
MainWindow.language = translate('OpenLP.MainWindow', 'English') # MainWindow.language = translate('OpenLP.MainWindow', 'English')
MainWindow.setWindowTitle(MainWindow.mainTitle) MainWindow.setWindowTitle(MainWindow.mainTitle)
self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File')) self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import')) self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
@ -575,7 +575,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage) QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage)
self.LanguageGroup.triggered.connect(LanguageManager.set_language) self.LanguageGroup.triggered.connect(LanguageManager.set_language)
QtCore.QObject.connect(self.ModeDefaultItem, QtCore.QObject.connect(self.ModeDefaultItem,
QtCore.SIGNAL(u'triggered()'), self.setViewMode) QtCore.SIGNAL(u'triggered()'), self.onModeDefaultItemClicked)
QtCore.QObject.connect(self.ModeSetupItem, QtCore.QObject.connect(self.ModeSetupItem,
QtCore.SIGNAL(u'triggered()'), self.onModeSetupItemClicked) QtCore.SIGNAL(u'triggered()'), self.onModeSetupItemClicked)
QtCore.QObject.connect(self.ModeLiveItem, QtCore.QObject.connect(self.ModeLiveItem,
@ -670,6 +670,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.generalSettingsSection + u'/auto open', self.generalSettingsSection + u'/auto open',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
self.ServiceManagerContents.onLoadService(True) self.ServiceManagerContents.onLoadService(True)
view_mode = QtCore.QSettings().value(u'%s/view mode' % \
self.generalSettingsSection, u'default')
if view_mode == u'default':
self.ModeDefaultItem.setChecked(True)
elif view_mode == u'setup':
self.setViewMode(True, True, False, True, False)
self.ModeSetupItem.setChecked(True)
elif view_mode == u'live':
self.setViewMode(False, True, False, False, True)
self.ModeLiveItem.setChecked(True)
def blankCheck(self): def blankCheck(self):
""" """
@ -677,8 +687,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Triggered by delay thread. Triggered by delay thread.
""" """
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(self.generalSettingsSection) if settings.value(u'%s/screen blank' % self.generalSettingsSection,
if settings.value(u'screen blank', QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
self.LiveController.mainDisplaySetBackground() self.LiveController.mainDisplaySetBackground()
if settings.value(u'blank warning', if settings.value(u'blank warning',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
@ -687,7 +697,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
'OpenLP Main Display Blanked'), 'OpenLP Main Display Blanked'),
translate('OpenLP.MainWindow', translate('OpenLP.MainWindow',
'The Main Display has been blanked out')) 'The Main Display has been blanked out'))
settings.endGroup()
def onHelpWebSiteClicked(self): def onHelpWebSiteClicked(self):
""" """
@ -716,16 +725,31 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
""" """
self.settingsForm.exec_() self.settingsForm.exec_()
def onModeDefaultItemClicked(self):
"""
Put OpenLP into "Default" view mode.
"""
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'default')
self.setViewMode(True, True, True, True, True)
def onModeSetupItemClicked(self): def onModeSetupItemClicked(self):
""" """
Put OpenLP into "Setup" view mode. Put OpenLP into "Setup" view mode.
""" """
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'setup')
self.setViewMode(True, True, False, True, False) self.setViewMode(True, True, False, True, False)
def onModeLiveItemClicked(self): def onModeLiveItemClicked(self):
""" """
Put OpenLP into "Live" view mode. Put OpenLP into "Live" view mode.
""" """
settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'live')
self.setViewMode(False, True, False, False, True) self.setViewMode(False, True, False, False, True)
def setViewMode(self, media=True, service=True, theme=True, preview=True, def setViewMode(self, media=True, service=True, theme=True, preview=True,

View File

@ -383,20 +383,20 @@ class ServiceManager(QtGui.QWidget):
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList) serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
tempItem = None tempItem = None
setLastItem = False setLastItem = False
while serviceIterator: while serviceIterator.value():
if serviceIterator.isSelected() and tempItem is None: if serviceIterator.value().isSelected() and tempItem is None:
setLastItem = True setLastItem = True
serviceIterator.setSelected(False) serviceIterator.value().setSelected(False)
if serviceIterator.isSelected(): if serviceIterator.value().isSelected():
#We are on the first record # We are on the first record
if tempItem: if tempItem:
tempItem.setSelected(True) tempItem.setSelected(True)
serviceIterator.setSelected(False) serviceIterator.value().setSelected(False)
else: else:
tempItem = serviceIterator tempItem = serviceIterator.value()
lastItem = serviceIterator lastItem = serviceIterator.value()
++serviceIterator serviceIterator += 1
#Top Item was selected so set the last one # Top Item was selected so set the last one
if setLastItem: if setLastItem:
lastItem.setSelected(True) lastItem.setSelected(True)
@ -406,16 +406,18 @@ class ServiceManager(QtGui.QWidget):
Called by the down arrow Called by the down arrow
""" """
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList) serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
firstItem = serviceIterator firstItem = None
setSelected = False setSelected = False
while serviceIterator: while serviceIterator.value():
if not firstItem:
firstItem = serviceIterator.value()
if setSelected: if setSelected:
setSelected = False setSelected = False
serviceIterator.setSelected(True) serviceIterator.value().setSelected(True)
elif serviceIterator.isSelected(): elif serviceIterator.value() and serviceIterator.value().isSelected():
serviceIterator.setSelected(False) serviceIterator.value().setSelected(False)
setSelected = True setSelected = True
++serviceIterator serviceIterator += 1
if setSelected: if setSelected:
firstItem.setSelected(True) firstItem.setSelected(True)
@ -557,7 +559,7 @@ class ServiceManager(QtGui.QWidget):
QtCore.QVariant(item[u'order'])) QtCore.QVariant(item[u'order']))
for count, frame in enumerate(serviceitem.get_frames()): for count, frame in enumerate(serviceitem.get_frames()):
treewidgetitem1 = QtGui.QTreeWidgetItem(treewidgetitem) treewidgetitem1 = QtGui.QTreeWidgetItem(treewidgetitem)
text = frame[u'title'] text = frame[u'title'].replace(u'\n', u' ')
treewidgetitem1.setText(0, text[:40]) treewidgetitem1.setText(0, text[:40])
treewidgetitem1.setData(0, QtCore.Qt.UserRole, treewidgetitem1.setData(0, QtCore.Qt.UserRole,
QtCore.QVariant(count)) QtCore.QVariant(count))

View File

@ -637,9 +637,9 @@ class SlideController(QtGui.QWidget):
""" """
if not self.serviceItem: if not self.serviceItem:
return return
Receiver.send_message(u'%s_first' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(u'%s_first' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive])
self.updatePreview() self.updatePreview()
else: else:
self.PreviewListWidget.selectRow(0) self.PreviewListWidget.selectRow(0)
@ -652,9 +652,9 @@ class SlideController(QtGui.QWidget):
index = int(message[0]) index = int(message[0])
if not self.serviceItem: if not self.serviceItem:
return return
Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive, index])
if self.serviceItem.is_command(): if self.serviceItem.is_command():
Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive, index])
self.updatePreview() self.updatePreview()
else: else:
self.PreviewListWidget.selectRow(index) self.PreviewListWidget.selectRow(index)
@ -769,9 +769,9 @@ class SlideController(QtGui.QWidget):
row = self.PreviewListWidget.currentRow() row = self.PreviewListWidget.currentRow()
self.selectedRow = 0 self.selectedRow = 0
if row > -1 and row < self.PreviewListWidget.rowCount(): if row > -1 and row < self.PreviewListWidget.rowCount():
Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive, row])
if self.serviceItem.is_command() and self.isLive: if self.serviceItem.is_command() and self.isLive:
Receiver.send_message(u'%s_slide' % self.serviceItem.name.lower(),
[self.serviceItem, self.isLive, row])
self.updatePreview() self.updatePreview()
else: else:
frame, raw_html = self.serviceItem.get_rendered_frame(row) frame, raw_html = self.serviceItem.get_rendered_frame(row)

View File

@ -82,7 +82,8 @@ class LanguageManager(object):
""" """
translator = QtCore.QTranslator() translator = QtCore.QTranslator()
translator.load(qm_file) translator.load(qm_file)
return translator.translate('OpenLP.MainWindow', 'English') return translator.translate('OpenLP.MainWindow', 'English',
'Please add the name of your language here')
@staticmethod @staticmethod
def get_language(): def get_language():
@ -107,12 +108,13 @@ class LanguageManager(object):
``action`` ``action``
The language menu option The language menu option
""" """
action_name = u'%s' % action.objectName() language = u'en'
qm_list = LanguageManager.get_qm_list() if action:
if LanguageManager.auto_language: action_name = u'%s' % action.objectName()
language = u'[%s]' % qm_list[action_name] qm_list = LanguageManager.get_qm_list()
else:
language = u'%s' % qm_list[action_name] language = u'%s' % qm_list[action_name]
if LanguageManager.auto_language:
language = u'[%s]' % language
QtCore.QSettings().setValue( QtCore.QSettings().setValue(
u'general/language', QtCore.QVariant(language)) u'general/language', QtCore.QVariant(language))
log.info(u'Language file: \'%s\' written to conf file' % language) log.info(u'Language file: \'%s\' written to conf file' % language)
@ -129,9 +131,11 @@ class LanguageManager(object):
LanguageManager.__qm_list__ = {} LanguageManager.__qm_list__ = {}
qm_files = LanguageManager.find_qm_files() qm_files = LanguageManager.find_qm_files()
for counter, qmf in enumerate(qm_files): for counter, qmf in enumerate(qm_files):
name = unicode(qmf).split(u'.')[0] reg_ex = QtCore.QRegExp("^.*i18n/(.*).qm")
LanguageManager.__qm_list__[u'%#2i %s' % (counter + 1, if reg_ex.exactMatch(qmf):
LanguageManager.language_name(qmf))] = name name = u'%s' % reg_ex.cap(1)
LanguageManager.__qm_list__[u'%#2i %s' % (counter + 1,
LanguageManager.language_name(qmf))] = name
@staticmethod @staticmethod
def get_qm_list(): def get_qm_list():

View File

@ -40,7 +40,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', u'1.9.2', plugin_helpers) Plugin.__init__(self, u'Alerts', u'1.9.3', plugin_helpers)
self.weight = -3 self.weight = -3
self.icon = build_icon(u':/plugins/plugin_alerts.png') self.icon = build_icon(u':/plugins/plugin_alerts.png')
self.alertsmanager = AlertsManager(self) self.alertsmanager = AlertsManager(self)

View File

@ -37,7 +37,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', u'1.9.2', plugin_helpers) Plugin.__init__(self, u'Bibles', u'1.9.3', plugin_helpers)
self.weight = -9 self.weight = -9
self.icon_path = u':/plugins/plugin_bibles.png' self.icon_path = u':/plugins/plugin_bibles.png'
self.icon = build_icon(self.icon_path) self.icon = build_icon(self.icon_path)

View File

@ -126,29 +126,29 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
if self.field(u'osis_location').toString() == u'': if self.field(u'osis_location').toString() == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Bible Location'), 'Invalid Bible Location'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'You need to specify a file to import your ' 'You need to specify a file to import your '
'Bible from.')) 'Bible from.'))
self.OSISLocationEdit.setFocus() self.OSISLocationEdit.setFocus()
return False return False
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV: elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
if self.field(u'csv_booksfile').toString() == u'': if self.field(u'csv_booksfile').toString() == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Books File'), 'Invalid Books File'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'You need to specify a file with books of ' 'You need to specify a file with books of '
'the Bible to use in the import.')) 'the Bible to use in the import.'))
self.BooksLocationEdit.setFocus() self.BooksLocationEdit.setFocus()
return False return False
elif self.field(u'csv_versefile').toString() == u'': elif self.field(u'csv_versefile').toString() == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Verse File'), 'Invalid Verse File'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'You need to specify a file of Bible ' 'You need to specify a file of Bible '
'verses to import.')) 'verses to import.'))
self.CsvVerseLocationEdit.setFocus() self.CsvVerseLocationEdit.setFocus()
return False return False
elif self.field(u'source_format').toInt()[0] == \ elif self.field(u'source_format').toInt()[0] == \
@ -156,10 +156,10 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
if self.field(u'opensong_file').toString() == u'': if self.field(u'opensong_file').toString() == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid OpenSong Bible'), 'Invalid OpenSong Bible'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'You need to specify an OpenSong Bible ' 'You need to specify an OpenSong Bible '
'file to import.')) 'file to import.'))
self.OpenSongFileEdit.setFocus() self.OpenSongFileEdit.setFocus()
return False return False
return True return True
@ -171,29 +171,26 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
if license_version == u'': if license_version == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Empty Version Name'), 'Empty Version Name'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'You need to specify a version name for your ' 'You need to specify a version name for your Bible.'))
'Bible.'))
self.VersionNameEdit.setFocus() self.VersionNameEdit.setFocus()
return False return False
elif license_copyright == u'': elif license_copyright == u'':
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Empty Copyright'), 'Empty Copyright'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'You need to set a copyright for your Bible. ' 'You need to set a copyright for your Bible. '
'Bibles in the Public Domain need to be marked as ' 'Bibles in the Public Domain need to be marked as such.'))
'such.'))
self.CopyrightEdit.setFocus() self.CopyrightEdit.setFocus()
return False return False
elif self.manager.exists(license_version): elif self.manager.exists(license_version):
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Bible Exists'), 'This Bible already exists. Please import '
translate('BiblesPlugin.ImportWizardForm', 'a different Bible or first delete the existing one.'))
'This Bible already exists. Please import '
'a different Bible or first delete the existing one.'))
self.VersionNameEdit.setFocus() self.VersionNameEdit.setFocus()
return False return False
return True return True
@ -290,6 +287,9 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
def setDefaults(self): def setDefaults(self):
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(self.bibleplugin.settingsSection) settings.beginGroup(self.bibleplugin.settingsSection)
self.restart()
self.finishButton.setVisible(False)
self.cancelButton.setVisible(True)
self.setField(u'source_format', QtCore.QVariant(0)) self.setField(u'source_format', QtCore.QVariant(0))
self.setField(u'osis_location', QtCore.QVariant('')) self.setField(u'osis_location', QtCore.QVariant(''))
self.setField(u'csv_booksfile', QtCore.QVariant('')) self.setField(u'csv_booksfile', QtCore.QVariant(''))
@ -434,18 +434,16 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
unicode(self.field(u'proxy_username').toString()), unicode(self.field(u'proxy_username').toString()),
proxy_password=unicode(self.field(u'proxy_password').toString()) proxy_password=unicode(self.field(u'proxy_password').toString())
) )
success = importer.do_import() if importer.do_import():
if success:
self.manager.save_meta_data(license_version, license_version, self.manager.save_meta_data(license_version, license_version,
license_copyright, license_permission) license_copyright, license_permission)
self.manager.reload_bibles() self.manager.reload_bibles()
self.ImportProgressLabel.setText( self.ImportProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm', 'Finished import.'))
'Finished import.'))
else: else:
self.ImportProgressLabel.setText( self.ImportProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Your Bible import failed.')) 'Your Bible import failed.'))
delete_database(self.bibleplugin.settingsSection, importer.file) delete_database(self.bibleplugin.settingsSection, importer.file)
def postImport(self): def postImport(self):

View File

@ -65,12 +65,6 @@ class BibleMediaItem(MediaManagerItem):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles) QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles)
def _decodeQtObject(self, listobj, key):
obj = listobj[QtCore.QString(key)]
if isinstance(obj, QtCore.QVariant):
obj = obj.toPyObject()
return unicode(obj)
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
self.hasImportIcon = True self.hasImportIcon = True
@ -376,9 +370,6 @@ class BibleMediaItem(MediaManagerItem):
def onSearchProgressShow(self): def onSearchProgressShow(self):
self.SearchProgress.setVisible(True) self.SearchProgress.setVisible(True)
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
#self.SearchProgress.setMinimum(0)
#self.SearchProgress.setMaximum(2)
#self.SearchProgress.setValue(1)
def onSearchProgressHide(self): def onSearchProgressHide(self):
self.SearchProgress.setVisible(False) self.SearchProgress.setVisible(False)
@ -408,18 +399,28 @@ class BibleMediaItem(MediaManagerItem):
self.reloadBibles() self.reloadBibles()
def onAdvancedFromVerse(self): def onAdvancedFromVerse(self):
frm = self.AdvancedFromVerse.currentText() frm = int(self.AdvancedFromVerse.currentText())
self.adjustComboBox(frm, self.verses, self.AdvancedToVerse) chapter_frm = int(self.AdvancedFromChapter.currentText())
chapter_to = int(self.AdvancedToChapter.currentText())
def onAdvancedToChapter(self): if chapter_frm == chapter_to:
frm = unicode(self.AdvancedFromChapter.currentText())
to = unicode(self.AdvancedToChapter.currentText())
if frm != to:
bible = unicode(self.AdvancedVersionComboBox.currentText()) bible = unicode(self.AdvancedVersionComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText()) book = unicode(self.AdvancedBookComboBox.currentText())
# get the verse count for new chapter verses = self.parent.manager.get_verse_count(bible, book, chapter_to)
verses = self.parent.manager.get_verse_count(bible, book, int(to)) self.adjustComboBox(frm, verses, self.AdvancedToVerse)
def onAdvancedToChapter(self):
chapter_frm = int(self.AdvancedFromChapter.currentText())
chapter_to = int(self.AdvancedToChapter.currentText())
bible = unicode(self.AdvancedVersionComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText())
verses = self.parent.manager.get_verse_count(bible, book, chapter_to)
if chapter_frm != chapter_to:
self.adjustComboBox(1, verses, self.AdvancedToVerse) self.adjustComboBox(1, verses, self.AdvancedToVerse)
else:
frm = int(self.AdvancedFromVerse.currentText())
to = int(self.AdvancedToVerse.currentText())
if to < frm:
self.adjustComboBox(frm, verses, self.AdvancedToVerse)
def onAdvancedSearchButton(self): def onAdvancedSearchButton(self):
log.debug(u'Advanced Search Button pressed') log.debug(u'Advanced Search Button pressed')
@ -438,32 +439,72 @@ class BibleMediaItem(MediaManagerItem):
dual_bible, versetext) dual_bible, versetext)
if self.ClearAdvancedSearchComboBox.currentIndex() == 0: if self.ClearAdvancedSearchComboBox.currentIndex() == 0:
self.listView.clear() self.listView.clear()
self.displayResults(bible, dual_bible) if self.listView.count() != 0:
bitem = self.listView.item(0)
item_dual_bible = self._decodeQtObject(bitem, 'dual_bible')
if item_dual_bible and dual_bible or not item_dual_bible and \
not dual_bible:
self.displayResults(bible, dual_bible)
elif QtGui.QMessageBox.critical(self,
translate('BiblePlugin.MediaItem', 'Error'),
translate('BiblePlugin.MediaItem', 'You cannot combine single '
'and dual bible verses. Do you want to delete your search '
'results and start a new search?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
self.listView.clear()
self.displayResults(bible, dual_bible)
else:
self.displayResults(bible, dual_bible)
def onAdvancedFromChapter(self): def onAdvancedFromChapter(self):
bible = unicode(self.AdvancedVersionComboBox.currentText()) bible = unicode(self.AdvancedVersionComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText()) book = unicode(self.AdvancedBookComboBox.currentText())
cf = int(self.AdvancedFromChapter.currentText()) chapter_frm = int(self.AdvancedFromChapter.currentText())
self.adjustComboBox(cf, self.chapters_from, self.AdvancedToChapter) self.adjustComboBox(chapter_frm, self.chapters_from,
# get the verse count for new chapter self.AdvancedToChapter)
vse = self.parent.manager.get_verse_count(bible, book, cf) verse = self.parent.manager.get_verse_count(bible, book, chapter_frm)
self.adjustComboBox(1, vse, self.AdvancedFromVerse) self.adjustComboBox(1, verse, self.AdvancedToVerse)
self.adjustComboBox(1, vse, self.AdvancedToVerse) self.adjustComboBox(1, verse, self.AdvancedFromVerse)
def onQuickSearchButton(self): def onQuickSearchButton(self):
log.debug(u'Quick Search Button pressed') log.debug(u'Quick Search Button pressed')
bible = unicode(self.QuickVersionComboBox.currentText()) bible = unicode(self.QuickVersionComboBox.currentText())
dual_bible = unicode(self.QuickSecondBibleComboBox.currentText()) dual_bible = unicode(self.QuickSecondBibleComboBox.currentText())
text = unicode(self.QuickSearchEdit.text()) text = unicode(self.QuickSearchEdit.text())
if self.ClearQuickSearchComboBox.currentIndex() == 0:
self.listView.clear()
self.search_results = self.parent.manager.get_verses(bible, text) self.search_results = self.parent.manager.get_verses(bible, text)
if dual_bible: if dual_bible:
self.dual_search_results = self.parent.manager.get_verses( self.dual_search_results = self.parent.manager.get_verses(
dual_bible, text) dual_bible, text)
if self.search_results: if self.ClearQuickSearchComboBox.currentIndex() == 0:
self.listView.clear()
if self.listView.count() != 0 and self.search_results:
bitem = self.listView.item(0)
item_dual_bible = self._decodeQtObject(bitem, 'dual_bible')
if item_dual_bible and dual_bible or not item_dual_bible and \
not dual_bible:
self.displayResults(bible, dual_bible)
elif QtGui.QMessageBox.critical(self,
translate('BiblePlugin.MediaItem', 'Error'),
translate('BiblePlugin.MediaItem', 'You cannot combine single '
'and dual bible verses. Do you want to delete your search '
'results and start a new search?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
self.listView.clear()
self.displayResults(bible, dual_bible)
elif self.search_results:
self.displayResults(bible, dual_bible) self.displayResults(bible, dual_bible)
def _decodeQtObject(self, bitem, key):
reference = bitem.data(QtCore.Qt.UserRole)
if isinstance(reference, QtCore.QVariant):
reference = reference.toPyObject()
obj = reference[QtCore.QString(key)]
if isinstance(obj, QtCore.QVariant):
obj = obj.toPyObject()
return unicode(obj)
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None):
""" """
Generates and formats the slides for the service item as well as the Generates and formats the slides for the service item as well as the
@ -473,67 +514,40 @@ class BibleMediaItem(MediaManagerItem):
items = self.listView.selectedIndexes() items = self.listView.selectedIndexes()
if len(items) == 0: if len(items) == 0:
return False return False
has_dual_bible = False
bible_text = u'' bible_text = u''
old_chapter = u'' old_chapter = u''
raw_footer = [] raw_footer = []
raw_slides = [] raw_slides = []
raw_title = []
first_item = True
for item in items: for item in items:
bitem = self.listView.item(item.row()) bitem = self.listView.item(item.row())
reference = bitem.data(QtCore.Qt.UserRole) book = self._decodeQtObject(bitem, 'book')
if isinstance(reference, QtCore.QVariant): chapter = int(self._decodeQtObject(bitem, 'chapter'))
reference = reference.toPyObject() verse = int(self._decodeQtObject(bitem, 'verse'))
dual_bible = self._decodeQtObject(reference, 'dual_bible') bible = self._decodeQtObject(bitem, 'bible')
if dual_bible: version = self._decodeQtObject(bitem, 'version')
has_dual_bible = True copyright = self._decodeQtObject(bitem, 'copyright')
break permission = self._decodeQtObject(bitem, 'permission')
# Let's loop through the main lot, and assemble our verses. text = self._decodeQtObject(bitem, 'text')
for item in items: dual_bible = self._decodeQtObject(bitem, 'dual_bible')
bitem = self.listView.item(item.row()) dual_version = self._decodeQtObject(bitem, 'dual_version')
reference = bitem.data(QtCore.Qt.UserRole) dual_copyright = self._decodeQtObject(bitem, 'dual_copyright')
if isinstance(reference, QtCore.QVariant): dual_permission = self._decodeQtObject(bitem, 'dual_permission')
reference = reference.toPyObject() dual_text = self._decodeQtObject(bitem, 'dual_text')
book = self._decodeQtObject(reference, 'book')
chapter = self._decodeQtObject(reference, 'chapter')
verse = self._decodeQtObject(reference, 'verse')
bible = self._decodeQtObject(reference, 'bible')
version = self._decodeQtObject(reference, 'version')
copyright = self._decodeQtObject(reference, 'copyright')
permission = self._decodeQtObject(reference, 'permission')
text = self._decodeQtObject(reference, 'text')
dual_bible = self._decodeQtObject(reference, 'dual_bible')
if dual_bible:
dual_version = self._decodeQtObject(reference,
'dual_version')
dual_copyright = self._decodeQtObject(reference,
'dual_copyright')
dual_permission = self._decodeQtObject(reference,
'dual_permission')
dual_text = self._decodeQtObject(reference, 'dual_text')
verse_text = self.formatVerse(old_chapter, chapter, verse) verse_text = self.formatVerse(old_chapter, chapter, verse)
footer = u'%s (%s %s %s)' % (book, version, copyright, permission) footer = u'%s (%s %s %s)' % (book, version, copyright, permission)
if footer not in raw_footer: if footer not in raw_footer:
raw_footer.append(footer) raw_footer.append(footer)
if has_dual_bible: if dual_bible:
if dual_bible: footer = u'%s (%s %s %s)' % (book, dual_version, dual_copyright,
footer = u'%s (%s %s %s)' % (book, dual_version, dual_permission)
dual_copyright, dual_permission) if footer not in raw_footer:
if footer not in raw_footer: raw_footer.append(footer)
raw_footer.append(footer) bible_text = u'%s %s\n\n%s %s' % (verse_text, text, verse_text,
# If there is an old bible_text we have to add it. dual_text)
if bible_text: raw_slides.append(bible_text)
raw_slides.append(bible_text) bible_text = u''
bible_text = u''
bible_text = u'%s %s\n\n%s %s' % (verse_text, text,
verse_text, dual_text)
raw_slides.append(bible_text)
bible_text = u''
elif self.parent.settings_tab.layout_style == 0:
bible_text = u'%s %s' % (verse_text, text)
raw_slides.append(bible_text)
bible_text = u''
else:
bible_text = u'%s %s %s\n' % (bible_text, verse_text, text)
# If we are 'Verse Per Slide' then create a new slide. # If we are 'Verse Per Slide' then create a new slide.
elif self.parent.settings_tab.layout_style == 0: elif self.parent.settings_tab.layout_style == 0:
bible_text = u'%s %s' % (verse_text, text) bible_text = u'%s %s' % (verse_text, text)
@ -545,29 +559,31 @@ class BibleMediaItem(MediaManagerItem):
# We have to be 'Continuous'. # We have to be 'Continuous'.
else: else:
bible_text = u'%s %s %s\n' % (bible_text, verse_text, text) bible_text = u'%s %s %s\n' % (bible_text, verse_text, text)
if first_item:
start_item = item
first_item = False
elif self.checkTitle(item, old_item):
raw_title.append(self.formatTitle(start_item, old_item))
start_item = item
old_item = item
old_chapter = chapter old_chapter = chapter
raw_title.append(self.formatTitle(start_item, item))
# If there are no more items we check whether we have to add bible_text. # If there are no more items we check whether we have to add bible_text.
if bible_text: if bible_text:
raw_slides.append(bible_text) raw_slides.append(bible_text)
bible_text = u'' bible_text = u''
# Service Item: Capabilities # Service Item: Capabilities
if self.parent.settings_tab.layout_style == 2 and not has_dual_bible: if self.parent.settings_tab.layout_style == 2 and not dual_bible:
# split the line but do not replace line breaks in renderer # Split the line but do not replace line breaks in renderer.
service_item.add_capability(ItemCapabilities.NoLineBreaks) service_item.add_capability(ItemCapabilities.NoLineBreaks)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)
service_item.add_capability(ItemCapabilities.AllowsAdditions)
# Service Item: Title # Service Item: Title
if not service_item.title: for title in raw_title:
if dual_bible: if not service_item.title:
service_item.title = u'%s (%s, %s) %s' % (book, version, service_item.title = title
dual_version, verse_text)
else: else:
service_item.title = u'%s (%s) %s' % (book, version, verse_text) service_item.title += u', ' + title
elif service_item.title.find(
translate('BiblesPlugin.MediaItem', 'etc')) == -1:
service_item.title = u'%s, %s' % (service_item.title,
translate('BiblesPlugin.MediaItem', 'etc'))
# Service Item: Theme # Service Item: Theme
if len(self.parent.settings_tab.bible_theme) == 0: if len(self.parent.settings_tab.bible_theme) == 0:
service_item.theme = None service_item.theme = None
@ -582,12 +598,80 @@ class BibleMediaItem(MediaManagerItem):
service_item.raw_footer = raw_footer service_item.raw_footer = raw_footer
return True return True
def formatTitle(self, start_item, old_item):
"""
This methode is called, when we have to change the title, because
we are at the end of a verse range. E. g. if we want to add
Genesis 1:1-6 as well as Daniel 2:14.
"""
old_bitem = self.listView.item(old_item.row())
old_chapter = int(self._decodeQtObject(old_bitem, 'chapter'))
old_verse = int(self._decodeQtObject(old_bitem, 'verse'))
start_bitem = self.listView.item(start_item.row())
start_book = self._decodeQtObject(start_bitem, 'book')
start_chapter = int(self._decodeQtObject(start_bitem, 'chapter'))
start_verse = int(self._decodeQtObject(start_bitem, 'verse'))
start_bible = self._decodeQtObject(start_bitem, 'bible')
start_dual_bible = self._decodeQtObject(start_bitem, 'dual_bible')
if start_dual_bible:
if start_verse == old_verse and start_chapter == old_chapter:
title = u'%s %s:%s (%s, %s)' % (start_book, start_chapter,
start_verse, start_bible, start_dual_bible)
elif start_chapter == old_chapter:
title = u'%s %s:%s-%s (%s, %s)' % (start_book, start_chapter,
start_verse, old_verse, start_bible, start_dual_bible)
else:
title = u'%s %s:%s-%s:%s (%s, %s)' % (start_book, start_chapter,
start_verse, old_chapter, old_verse, start_bible,
start_dual_bible)
else:
if start_verse == old_verse and start_chapter == old_chapter:
title = u'%s %s:%s (%s)' % (start_book, start_chapter,
start_verse, start_bible)
elif start_chapter == old_chapter:
title = u'%s %s:%s-%s (%s)' % (start_book, start_chapter,
start_verse, old_verse, start_bible)
else:
title = u'%s %s:%s-%s:%s (%s)' % (start_book, start_chapter,
start_verse, old_chapter, old_verse, start_bible)
return title
def checkTitle(self, item, old_item):
"""
This methode checks if we are at the end of an verse range. If that is
the case, we return True, else False. E. g. if we added Genesis 1:1-6,
but the next verse is Daniel 2:14.
"""
bitem = self.listView.item(item.row())
book = self._decodeQtObject(bitem, 'book')
chapter = int(self._decodeQtObject(bitem, 'chapter'))
verse = int(self._decodeQtObject(bitem, 'verse'))
bible = self._decodeQtObject(bitem, 'bible')
dual_bible = self._decodeQtObject(bitem, 'dual_bible')
old_bitem = self.listView.item(old_item.row())
old_book = self._decodeQtObject(old_bitem, 'book')
old_chapter = int(self._decodeQtObject(old_bitem, 'chapter'))
old_verse = int(self._decodeQtObject(old_bitem, 'verse'))
old_bible = self._decodeQtObject(old_bitem, 'bible')
old_dual_bible = self._decodeQtObject(old_bitem, 'dual_bible')
if old_bible != bible or old_dual_bible != dual_bible or \
old_book != book:
return True
elif old_verse + 1 != verse and old_chapter == chapter:
return True
elif old_chapter + 1 == chapter and (verse != 1 or
old_verse != self.parent.manager.get_verse_count(
old_bible, old_book, old_chapter)):
return True
else:
return False
def formatVerse(self, old_chapter, chapter, verse): def formatVerse(self, old_chapter, chapter, verse):
if not self.parent.settings_tab.show_new_chapters or \ if not self.parent.settings_tab.show_new_chapters or \
old_chapter != chapter: old_chapter != chapter:
verse_text = chapter + u':' + verse verse_text = u'%s:%s' % (chapter, verse)
else: else:
verse_text = verse verse_text = u'%s' % verse
if self.parent.settings_tab.display_style == 1: if self.parent.settings_tab.display_style == 1:
verse_text = u'{su}(' + verse_text + u'){/su}' verse_text = u'{su}(' + verse_text + u'){/su}'
elif self.parent.settings_tab.display_style == 2: elif self.parent.settings_tab.display_style == 2:
@ -690,14 +774,15 @@ class BibleMediaItem(MediaManagerItem):
'copyright': QtCore.QVariant(copyright.value), 'copyright': QtCore.QVariant(copyright.value),
'permission': QtCore.QVariant(permission.value), 'permission': QtCore.QVariant(permission.value),
'text': QtCore.QVariant(verse.text), 'text': QtCore.QVariant(verse.text),
'dual_bible': QtCore.QVariant(dual_bible) 'dual_bible': QtCore.QVariant(u''),
'dual_version': QtCore.QVariant(u''),
'dual_copyright': QtCore.QVariant(u''),
'dual_permission': QtCore.QVariant(u''),
'dual_text': QtCore.QVariant(u'')
} }
bible_text = u' %s %d:%d (%s)' % (verse.book.name, bible_text = u' %s %d:%d (%s)' % (verse.book.name,
verse.chapter, verse.verse, version.value) verse.chapter, verse.verse, version.value)
# set the row title
bible_verse = QtGui.QListWidgetItem(bible_text) bible_verse = QtGui.QListWidgetItem(bible_text)
#bible_verse.setData(QtCore.Qt.UserRole,
# QtCore.QVariant(bible_text))
bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(vdict)) bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(vdict))
self.listView.addItem(bible_verse) self.listView.addItem(bible_verse)
row = self.listView.setCurrentRow(count + start_count) row = self.listView.setCurrentRow(count + start_count)

View File

@ -47,7 +47,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', u'1.9.2', plugin_helpers) Plugin.__init__(self, u'Custom', u'1.9.3', plugin_helpers)
self.weight = -5 self.weight = -5
self.custommanager = Manager(u'custom', init_schema) self.custommanager = Manager(u'custom', init_schema)
self.edit_custom_form = EditCustomForm(self.custommanager) self.edit_custom_form = EditCustomForm(self.custommanager)

View File

@ -35,7 +35,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', u'1.9.2', plugin_helpers) Plugin.__init__(self, u'Images', u'1.9.3', plugin_helpers)
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)

View File

@ -37,7 +37,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', u'1.9.2', plugin_helpers) Plugin.__init__(self, u'Media', u'1.9.3', plugin_helpers)
self.weight = -6 self.weight = -6
self.icon_path = u':/plugins/plugin_media.png' self.icon_path = u':/plugins/plugin_media.png'
self.icon = build_icon(self.icon_path) self.icon = build_icon(self.icon_path)

View File

@ -74,6 +74,7 @@ class ImpressController(PresentationController):
self.process = None self.process = None
self.desktop = None self.desktop = None
self.manager = None self.manager = None
self.uno_connection_type = u'pipe' #u'socket'
def check_available(self): def check_available(self):
""" """
@ -98,7 +99,14 @@ class ImpressController(PresentationController):
self.manager._FlagAsMethod(u'Bridge_GetValueObject') self.manager._FlagAsMethod(u'Bridge_GetValueObject')
else: else:
# -headless # -headless
cmd = u'openoffice.org -nologo -norestore -minimized -invisible -nofirststartwizard -accept="socket,host=localhost,port=2002;urp;"' if self.uno_connection_type == u'pipe':
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=pipe,name=openlp_pipe;urp;'
else:
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=socket,host=localhost,port=2002;urp;'
self.process = QtCore.QProcess() self.process = QtCore.QProcess()
self.process.startDetached(cmd) self.process.startDetached(cmd)
self.process.waitForStarted() self.process.waitForStarted()
@ -120,8 +128,14 @@ class ImpressController(PresentationController):
while ctx is None and loop < 3: while ctx is None and loop < 3:
try: try:
log.debug(u'get UNO Desktop Openoffice - resolve') log.debug(u'get UNO Desktop Openoffice - resolve')
ctx = resolver.resolve(u'uno:socket,host=localhost,port=2002;' if self.uno_connection_type == u'pipe':
u'urp;StarOffice.ComponentContext') ctx = resolver.resolve(u'uno:' \
+ u'pipe,name=openlp_pipe;' \
+ u'urp;StarOffice.ComponentContext')
else:
ctx = resolver.resolve(u'uno:' \
+ u'socket,host=localhost,port=2002;' \
+ u'urp;StarOffice.ComponentContext')
except: except:
log.exception(u'Unable to find running instance ') log.exception(u'Unable to find running instance ')
self.start_process() self.start_process()

View File

@ -51,7 +51,7 @@ class PresentationPlugin(Plugin):
""" """
log.debug(u'Initialised') log.debug(u'Initialised')
self.controllers = {} self.controllers = {}
Plugin.__init__(self, u'Presentations', u'1.9.2', plugin_helpers) Plugin.__init__(self, u'Presentations', u'1.9.3', 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)

View File

@ -38,7 +38,7 @@ class RemotesPlugin(Plugin):
""" """
remotes constructor remotes constructor
""" """
Plugin.__init__(self, u'Remotes', u'1.9.2', plugin_helpers) Plugin.__init__(self, u'Remotes', u'1.9.3', plugin_helpers)
self.icon = build_icon(u':/plugins/plugin_remote.png') self.icon = build_icon(u':/plugins/plugin_remote.png')
self.weight = -1 self.weight = -1
self.server = None self.server = None

View File

@ -629,7 +629,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.song.alternate_title = unicode(self.AlternativeEdit.text()) self.song.alternate_title = unicode(self.AlternativeEdit.text())
self.song.copyright = unicode(self.CopyrightEditItem.text()) self.song.copyright = unicode(self.CopyrightEditItem.text())
self.song.search_title = self.song.title + u'@' + \ self.song.search_title = self.song.title + u'@' + \
unicode(self.AlternativeEdit.text()) self.song.alternate_title
self.song.comments = unicode(self.CommentsEdit.toPlainText()) self.song.comments = unicode(self.CommentsEdit.toPlainText())
self.song.verse_order = unicode(self.VerseOrderEdit.text()) self.song.verse_order = unicode(self.VerseOrderEdit.text())
self.song.ccli_number = unicode(self.CCLNumberEdit.text()) self.song.ccli_number = unicode(self.CCLNumberEdit.text())
@ -669,7 +669,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
unicode(self.VerseListWidget.item(i, 0).text())) + u' ' unicode(self.VerseListWidget.item(i, 0).text())) + u' '
if (bits[1] > u'1') and (bits[0][0] not in multiple): if (bits[1] > u'1') and (bits[0][0] not in multiple):
multiple.append(bits[0][0]) multiple.append(bits[0][0])
self.song.search_lyrics = text self.song.search_lyrics = text.lower()
self.song.lyrics = unicode(sxml.extract_xml(), u'utf-8') self.song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
for verse in multiple: for verse in multiple:
self.song.verse_order = re.sub(u'([' + verse.upper() + self.song.verse_order = re.sub(u'([' + verse.upper() +
@ -682,4 +682,4 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def processTitle(self): def processTitle(self):
log.debug(u'processTitle') log.debug(u'processTitle')
self.song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'', self.song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'',
unicode(self.song.search_title)) unicode(self.song.search_title)).lower()

View File

@ -109,6 +109,9 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
QtCore.QObject.connect(self.genericRemoveButton, QtCore.QObject.connect(self.genericRemoveButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onGenericRemoveButtonClicked) self.onGenericRemoveButtonClicked)
QtCore.QObject.connect(self.ewBrowseButton,
QtCore.SIGNAL(u'clicked()'),
self.onEWBrowseButtonClicked)
QtCore.QObject.connect(self.cancelButton, QtCore.QObject.connect(self.cancelButton,
QtCore.SIGNAL(u'clicked(bool)'), QtCore.SIGNAL(u'clicked(bool)'),
self.onCancelButtonClicked) self.onCancelButtonClicked)
@ -214,6 +217,16 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
'presentation file to import from.')) 'presentation file to import from.'))
self.genericAddButton.setFocus() self.genericAddButton.setFocus()
return False return False
elif source_format == SongFormat.EasyWorship:
if self.ewFilenameEdit.text().isEmpty():
QtGui.QMessageBox.critical(self,
translate('SongsPlugin.ImportWizardForm',
'No EasyWorship Song Database Selected'),
translate('SongsPlugin.ImportWizardForm',
'You need to select an EasyWorship song database '
'file to import from.'))
self.ewBrowseButton.setFocus()
return False
return True return True
elif self.currentId() == 2: elif self.currentId() == 2:
# Progress page # Progress page
@ -322,6 +335,13 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
def onGenericRemoveButtonClicked(self): def onGenericRemoveButtonClicked(self):
self.removeSelectedItems(self.genericFileListWidget) self.removeSelectedItems(self.genericFileListWidget)
def onEWBrowseButtonClicked(self):
self.getFileName(
translate('SongsPlugin.ImportWizardForm',
'Select EasyWorship Database File'),
self.ewFilenameEdit
)
def onCancelButtonClicked(self, checked): def onCancelButtonClicked(self, checked):
""" """
Stop the import on pressing the cancel button. Stop the import on pressing the cancel button.
@ -341,6 +361,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
def setDefaults(self): def setDefaults(self):
self.restart() self.restart()
self.finishButton.setVisible(False)
self.cancelButton.setVisible(True)
self.formatComboBox.setCurrentIndex(0) self.formatComboBox.setCurrentIndex(0)
self.openLP2FilenameEdit.setText(u'') self.openLP2FilenameEdit.setText(u'')
self.openLP1FilenameEdit.setText(u'') self.openLP1FilenameEdit.setText(u'')
@ -350,6 +372,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
self.ccliFileListWidget.clear() self.ccliFileListWidget.clear()
self.songsOfFellowshipFileListWidget.clear() self.songsOfFellowshipFileListWidget.clear()
self.genericFileListWidget.clear() self.genericFileListWidget.clear()
self.ewFilenameEdit.setText(u'')
#self.csvFilenameEdit.setText(u'') #self.csvFilenameEdit.setText(u'')
def incrementProgressBar(self, status_text, increment=1): def incrementProgressBar(self, status_text, increment=1):
@ -420,6 +443,11 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
importer = self.plugin.importSongs(SongFormat.Generic, importer = self.plugin.importSongs(SongFormat.Generic,
filenames=self.getListOfFiles(self.genericFileListWidget) filenames=self.getListOfFiles(self.genericFileListWidget)
) )
elif source_format == SongFormat.EasyWorship:
# Import an OpenLP 2.0 database
importer = self.plugin.importSongs(SongFormat.EasyWorship,
filename=unicode(self.ewFilenameEdit.text())
)
success = importer.do_import() success = importer.do_import()
if success: if success:
# reload songs # reload songs

View File

@ -30,8 +30,8 @@ from openlp.core.lib import build_icon, translate
class Ui_SongImportWizard(object): class Ui_SongImportWizard(object):
def setupUi(self, songImportWizard): def setupUi(self, songImportWizard):
openIcon = build_icon(u':/general/general_open.png') self.openIcon = build_icon(u':/general/general_open.png')
deleteIcon = build_icon(u':/general/general_delete.png') self.deleteIcon = build_icon(u':/general/general_delete.png')
songImportWizard.setObjectName(u'songImportWizard') songImportWizard.setObjectName(u'songImportWizard')
songImportWizard.resize(550, 386) songImportWizard.resize(550, 386)
songImportWizard.setModal(True) songImportWizard.setModal(True)
@ -88,15 +88,6 @@ class Ui_SongImportWizard(object):
self.formatComboBox.sizePolicy().hasHeightForWidth()) self.formatComboBox.sizePolicy().hasHeightForWidth())
self.formatComboBox.setSizePolicy(sizePolicy) self.formatComboBox.setSizePolicy(sizePolicy)
self.formatComboBox.setObjectName(u'formatComboBox') self.formatComboBox.setObjectName(u'formatComboBox')
self.formatComboBox.addItem(u'')
self.formatComboBox.addItem(u'')
self.formatComboBox.addItem(u'')
self.formatComboBox.addItem(u'')
self.formatComboBox.addItem(u'')
self.formatComboBox.addItem(u'')
self.formatComboBox.addItem(u'')
self.formatComboBox.addItem(u'')
# self.formatComboBox.addItem(u'')
self.formatLayout.addWidget(self.formatComboBox) self.formatLayout.addWidget(self.formatComboBox)
self.formatSpacer = QtGui.QSpacerItem(40, 20, self.formatSpacer = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
@ -105,338 +96,28 @@ class Ui_SongImportWizard(object):
self.formatStackedWidget = QtGui.QStackedWidget(self.sourcePage) self.formatStackedWidget = QtGui.QStackedWidget(self.sourcePage)
self.formatStackedWidget.setObjectName(u'FormatStackedWidget') self.formatStackedWidget.setObjectName(u'FormatStackedWidget')
# OpenLP 2.0 # OpenLP 2.0
self.openLP2Page = QtGui.QWidget() self.addSingleFileSelectItem(u'openLP2')
self.openLP2Page.setObjectName(u'openLP2Page')
self.openLP2Layout = QtGui.QFormLayout(self.openLP2Page)
self.openLP2Layout.setMargin(0)
self.openLP2Layout.setSpacing(8)
self.openLP2Layout.setObjectName(u'openLP2Layout')
self.openLP2FilenameLabel = QtGui.QLabel(self.openLP2Page)
self.openLP2FilenameLabel.setObjectName(u'openLP2FilenameLabel')
self.openLP2Layout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.openLP2FilenameLabel)
self.openLP2FileLayout = QtGui.QHBoxLayout()
self.openLP2FileLayout.setSpacing(8)
self.openLP2FileLayout.setObjectName(u'openLP2FileLayout')
self.openLP2FilenameEdit = QtGui.QLineEdit(self.openLP2Page)
self.openLP2FilenameEdit.setObjectName(u'openLP2FilenameEdit')
self.openLP2FileLayout.addWidget(self.openLP2FilenameEdit)
self.openLP2BrowseButton = QtGui.QToolButton(self.openLP2Page)
self.openLP2BrowseButton.setIcon(openIcon)
self.openLP2BrowseButton.setObjectName(u'openLP2BrowseButton')
self.openLP2FileLayout.addWidget(self.openLP2BrowseButton)
self.openLP2Layout.setLayout(0, QtGui.QFormLayout.FieldRole,
self.openLP2FileLayout)
self.formatStackedWidget.addWidget(self.openLP2Page)
# openlp.org 1.x # openlp.org 1.x
self.openLP1Page = QtGui.QWidget() self.addSingleFileSelectItem(u'openLP1', None, True)
self.openLP1Page.setObjectName(u'openLP1Page')
self.openLP1Layout = QtGui.QVBoxLayout(self.openLP1Page)
self.openLP1Layout.setMargin(0)
self.openLP1Layout.setSpacing(0)
self.openLP1Layout.setObjectName(u'openLP1Layout')
self.openLP1DisabledWidget = QtGui.QWidget(self.openLP1Page)
self.openLP1DisabledLayout = QtGui.QVBoxLayout(self.openLP1DisabledWidget)
self.openLP1DisabledLayout.setMargin(0)
self.openLP1DisabledLayout.setSpacing(8)
self.openLP1DisabledLayout.setObjectName(u'openLP1DisabledLayout')
self.openLP1DisabledLabel = QtGui.QLabel(self.openLP1DisabledWidget)
self.openLP1DisabledLabel.setWordWrap(True)
self.openLP1DisabledLabel.setObjectName(u'openLP1DisabledLabel')
self.openLP1DisabledLayout.addWidget(self.openLP1DisabledLabel)
self.openLP1DisabledWidget.setVisible(False)
self.openLP1Layout.addWidget(self.openLP1DisabledWidget)
self.openLP1ImportWidget = QtGui.QWidget(self.openLP1Page)
self.openLP1ImportLayout = QtGui.QFormLayout(self.openLP1ImportWidget)
self.openLP1ImportLayout.setMargin(0)
self.openLP1ImportLayout.setSpacing(8)
self.openLP1ImportLayout.setObjectName(u'openLP1ImportLayout')
self.openLP1FilenameLabel = QtGui.QLabel(self.openLP1ImportWidget)
self.openLP1FilenameLabel.setObjectName(u'openLP1FilenameLabel')
self.openLP1ImportLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.openLP1FilenameLabel)
self.openLP1FileLayout = QtGui.QHBoxLayout()
self.openLP1FileLayout.setSpacing(8)
self.openLP1FileLayout.setObjectName(u'openLP1FileLayout')
self.openLP1FilenameEdit = QtGui.QLineEdit(self.openLP1ImportWidget)
self.openLP1FilenameEdit.setObjectName(u'openLP1FilenameEdit')
self.openLP1FileLayout.addWidget(self.openLP1FilenameEdit)
self.openLP1BrowseButton = QtGui.QToolButton(self.openLP1ImportWidget)
self.openLP1BrowseButton.setIcon(openIcon)
self.openLP1BrowseButton.setObjectName(u'openLP1BrowseButton')
self.openLP1FileLayout.addWidget(self.openLP1BrowseButton)
self.openLP1ImportLayout.setLayout(0, QtGui.QFormLayout.FieldRole,
self.openLP1FileLayout)
self.openLP1Layout.addWidget(self.openLP1ImportWidget)
self.formatStackedWidget.addWidget(self.openLP1Page)
# OpenLyrics # OpenLyrics
self.openLyricsPage = QtGui.QWidget() self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True)
self.openLyricsPage.setObjectName(u'OpenLyricsPage') # set OpenLyrics to disabled by default
self.openLyricsLayout = QtGui.QVBoxLayout(self.openLyricsPage) self.openLyricsDisabledWidget.setVisible(True)
self.openLyricsLayout.setSpacing(8) self.openLyricsImportWidget.setVisible(False)
self.openLyricsLayout.setMargin(0)
self.openLyricsLayout.setObjectName(u'OpenLyricsLayout')
self.openLyricsDisabledLabel = QtGui.QLabel(self.openLyricsPage)
self.openLyricsDisabledLabel.setWordWrap(True)
self.openLyricsDisabledLabel.setObjectName(u'openLyricsDisabledLabel')
self.openLyricsLayout.addWidget(self.openLyricsDisabledLabel)
# Commented out for future use.
#self.openLyricsFileListWidget = QtGui.QListWidget(self.openLyricsPage)
#self.openLyricsFileListWidget.setSelectionMode(
# QtGui.QAbstractItemView.ExtendedSelection)
#self.openLyricsFileListWidget.setObjectName(u'OpenLyricsFileListWidget')
#self.openLyricsLayout.addWidget(self.openLyricsFileListWidget)
#self.openLyricsButtonLayout = QtGui.QHBoxLayout()
#self.openLyricsButtonLayout.setSpacing(8)
#self.openLyricsButtonLayout.setObjectName(u'OpenLyricsButtonLayout')
#self.openLyricsAddButton = QtGui.QPushButton(self.openLyricsPage)
#self.openLyricsAddButton.setIcon(openIcon)
#self.openLyricsAddButton.setObjectName(u'OpenLyricsAddButton')
#self.openLyricsButtonLayout.addWidget(self.openLyricsAddButton)
#self.openLyricsButtonSpacer = QtGui.QSpacerItem(40, 20,
# QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
#self.openLyricsButtonLayout.addItem(self.openLyricsButtonSpacer)
#self.openLyricsRemoveButton = QtGui.QPushButton(self.openLyricsPage)
#self.openLyricsRemoveButton.setIcon(deleteIcon)
#self.openLyricsRemoveButton.setObjectName(u'OpenLyricsRemoveButton')
#self.openLyricsButtonLayout.addWidget(self.openLyricsRemoveButton)
#self.openLyricsLayout.addLayout(self.openLyricsButtonLayout)
self.formatStackedWidget.addWidget(self.openLyricsPage)
# Open Song # Open Song
self.openSongPage = QtGui.QWidget() self.addMultiFileSelectItem(u'openSong', u'OpenSong')
self.openSongPage.setObjectName(u'OpenSongPage')
self.openSongLayout = QtGui.QVBoxLayout(self.openSongPage)
self.openSongLayout.setSpacing(8)
self.openSongLayout.setMargin(0)
self.openSongLayout.setObjectName(u'OpenSongLayout')
self.openSongFileListWidget = QtGui.QListWidget(self.openSongPage)
self.openSongFileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
self.openSongFileListWidget.setObjectName(u'OpenSongFileListWidget')
self.openSongLayout.addWidget(self.openSongFileListWidget)
self.openSongButtonLayout = QtGui.QHBoxLayout()
self.openSongButtonLayout.setSpacing(8)
self.openSongButtonLayout.setObjectName(u'OpenSongButtonLayout')
self.openSongAddButton = QtGui.QPushButton(self.openSongPage)
self.openSongAddButton.setIcon(openIcon)
self.openSongAddButton.setObjectName(u'OpenSongAddButton')
self.openSongButtonLayout.addWidget(self.openSongAddButton)
self.openSongButtonSpacer = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.openSongButtonLayout.addItem(self.openSongButtonSpacer)
self.openSongRemoveButton = QtGui.QPushButton(self.openSongPage)
self.openSongRemoveButton.setIcon(deleteIcon)
self.openSongRemoveButton.setObjectName(u'OpenSongRemoveButton')
self.openSongButtonLayout.addWidget(self.openSongRemoveButton)
self.openSongLayout.addLayout(self.openSongButtonLayout)
self.formatStackedWidget.addWidget(self.openSongPage)
# Words of Worship # Words of Worship
self.wordsOfWorshipPage = QtGui.QWidget() self.addMultiFileSelectItem(u'wordsOfWorship')
self.wordsOfWorshipPage.setObjectName(u'wordsOfWorshipPage')
self.wordsOfWorshipLayout = QtGui.QVBoxLayout(self.wordsOfWorshipPage)
self.wordsOfWorshipLayout.setSpacing(8)
self.wordsOfWorshipLayout.setMargin(0)
self.wordsOfWorshipLayout.setObjectName(u'wordsOfWorshipLayout')
self.wordsOfWorshipFileListWidget = QtGui.QListWidget(
self.wordsOfWorshipPage)
self.wordsOfWorshipFileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
self.wordsOfWorshipFileListWidget.setObjectName(
u'wordsOfWorshipFileListWidget')
self.wordsOfWorshipLayout.addWidget(self.wordsOfWorshipFileListWidget)
self.wordsOfWorshipButtonLayout = QtGui.QHBoxLayout()
self.wordsOfWorshipButtonLayout.setSpacing(8)
self.wordsOfWorshipButtonLayout.setObjectName(
u'wordsOfWorshipButtonLayout')
self.wordsOfWorshipAddButton = QtGui.QPushButton(
self.wordsOfWorshipPage)
self.wordsOfWorshipAddButton.setIcon(openIcon)
self.wordsOfWorshipAddButton.setObjectName(u'wordsOfWorshipAddButton')
self.wordsOfWorshipButtonLayout.addWidget(self.wordsOfWorshipAddButton)
self.wordsOfWorshipButtonSpacer = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.wordsOfWorshipButtonLayout.addItem(self.wordsOfWorshipButtonSpacer)
self.wordsOfWorshipRemoveButton = QtGui.QPushButton(
self.wordsOfWorshipPage)
self.wordsOfWorshipRemoveButton.setIcon(deleteIcon)
self.wordsOfWorshipRemoveButton.setObjectName(
u'wordsOfWorshipRemoveButton')
self.wordsOfWorshipButtonLayout.addWidget(
self.wordsOfWorshipRemoveButton)
self.wordsOfWorshipLayout.addLayout(self.wordsOfWorshipButtonLayout)
self.formatStackedWidget.addWidget(self.wordsOfWorshipPage)
# CCLI File import # CCLI File import
self.ccliPage = QtGui.QWidget() self.addMultiFileSelectItem(u'ccli')
self.ccliPage.setObjectName(u'ccliPage')
self.ccliLayout = QtGui.QVBoxLayout(self.ccliPage)
self.ccliLayout.setSpacing(8)
self.ccliLayout.setMargin(0)
self.ccliLayout.setObjectName(u'ccliLayout')
self.ccliFileListWidget = QtGui.QListWidget(self.ccliPage)
self.ccliFileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
self.ccliFileListWidget.setObjectName(u'ccliFileListWidget')
self.ccliLayout.addWidget(self.ccliFileListWidget)
self.ccliButtonLayout = QtGui.QHBoxLayout()
self.ccliButtonLayout.setSpacing(8)
self.ccliButtonLayout.setObjectName(u'ccliButtonLayout')
self.ccliAddButton = QtGui.QPushButton(self.ccliPage)
self.ccliAddButton.setIcon(openIcon)
self.ccliAddButton.setObjectName(u'ccliAddButton')
self.ccliButtonLayout.addWidget(self.ccliAddButton)
self.ccliButtonSpacer = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.ccliButtonLayout.addItem(self.ccliButtonSpacer)
self.ccliRemoveButton = QtGui.QPushButton(self.ccliPage)
self.ccliRemoveButton.setIcon(deleteIcon)
self.ccliRemoveButton.setObjectName(u'ccliRemoveButton')
self.ccliButtonLayout.addWidget(self.ccliRemoveButton)
self.ccliLayout.addLayout(self.ccliButtonLayout)
self.formatStackedWidget.addWidget(self.ccliPage)
# Songs of Fellowship # Songs of Fellowship
self.songsOfFellowshipPage = QtGui.QWidget() self.addMultiFileSelectItem(u'songsOfFellowship', None, True)
self.songsOfFellowshipPage.setObjectName(u'songsOfFellowshipPage')
self.songsOfFellowshipLayout = QtGui.QVBoxLayout(
self.songsOfFellowshipPage)
self.songsOfFellowshipLayout.setMargin(0)
self.songsOfFellowshipLayout.setSpacing(0)
self.songsOfFellowshipLayout.setObjectName(u'songsOfFellowshipLayout')
self.songsOfFellowshipDisabledWidget = QtGui.QWidget(
self.songsOfFellowshipPage)
self.songsOfFellowshipDisabledWidget.setVisible(False)
self.songsOfFellowshipDisabledWidget.setObjectName(
u'songsOfFellowshipDisabledWidget')
self.songsOfFellowshipDisabledLayout = QtGui.QVBoxLayout(
self.songsOfFellowshipDisabledWidget)
self.songsOfFellowshipDisabledLayout.setMargin(0)
self.songsOfFellowshipDisabledLayout.setSpacing(8)
self.songsOfFellowshipDisabledLayout.setObjectName(
u'songsOfFellowshipDisabledLayout')
self.songsOfFellowshipDisabledLabel = QtGui.QLabel(
self.songsOfFellowshipDisabledWidget)
self.songsOfFellowshipDisabledLabel.setWordWrap(True)
self.songsOfFellowshipDisabledLabel.setObjectName(
u'songsOfFellowshipDisabledLabel')
self.songsOfFellowshipDisabledLayout.addWidget(
self.songsOfFellowshipDisabledLabel)
self.songsOfFellowshipLayout.addWidget(
self.songsOfFellowshipDisabledWidget)
self.songsOfFellowshipImportWidget = QtGui.QWidget(
self.songsOfFellowshipPage)
self.songsOfFellowshipImportWidget.setObjectName(
u'songsOfFellowshipImportWidget')
self.songsOfFellowshipImportLayout = QtGui.QVBoxLayout(
self.songsOfFellowshipImportWidget)
self.songsOfFellowshipImportLayout.setMargin(0)
self.songsOfFellowshipImportLayout.setSpacing(8)
self.songsOfFellowshipImportLayout.setObjectName(
u'songsOfFellowshipImportLayout')
self.songsOfFellowshipFileListWidget = QtGui.QListWidget(
self.songsOfFellowshipImportWidget)
self.songsOfFellowshipFileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
self.songsOfFellowshipFileListWidget.setObjectName(
u'songsOfFellowshipFileListWidget')
self.songsOfFellowshipImportLayout.addWidget(
self.songsOfFellowshipFileListWidget)
self.songsOfFellowshipButtonLayout = QtGui.QHBoxLayout()
self.songsOfFellowshipButtonLayout.setSpacing(8)
self.songsOfFellowshipButtonLayout.setObjectName(
u'songsOfFellowshipButtonLayout')
self.songsOfFellowshipAddButton = QtGui.QPushButton(
self.songsOfFellowshipImportWidget)
self.songsOfFellowshipAddButton.setIcon(openIcon)
self.songsOfFellowshipAddButton.setObjectName(
u'songsOfFellowshipAddButton')
self.songsOfFellowshipButtonLayout.addWidget(
self.songsOfFellowshipAddButton)
self.songsOfFellowshipButtonSpacer = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.songsOfFellowshipButtonLayout.addItem(
self.songsOfFellowshipButtonSpacer)
self.songsOfFellowshipRemoveButton = QtGui.QPushButton(
self.songsOfFellowshipImportWidget)
self.songsOfFellowshipRemoveButton.setIcon(deleteIcon)
self.songsOfFellowshipRemoveButton.setObjectName(
u'songsOfFellowshipRemoveButton')
self.songsOfFellowshipButtonLayout.addWidget(
self.songsOfFellowshipRemoveButton)
self.songsOfFellowshipImportLayout.addLayout(
self.songsOfFellowshipButtonLayout)
self.songsOfFellowshipLayout.addWidget(
self.songsOfFellowshipImportWidget)
self.formatStackedWidget.addWidget(self.songsOfFellowshipPage)
# Generic Document/Presentation import # Generic Document/Presentation import
self.genericPage = QtGui.QWidget() self.addMultiFileSelectItem(u'generic', None, True)
self.genericPage.setObjectName(u'genericPage') # EasyWorship
self.genericLayout = QtGui.QVBoxLayout(self.genericPage) self.addSingleFileSelectItem(u'ew')
self.genericLayout.setMargin(0)
self.genericLayout.setSpacing(0)
self.genericLayout.setObjectName(u'genericLayout')
self.genericDisabledWidget = QtGui.QWidget(self.genericPage)
self.genericDisabledWidget.setObjectName(u'genericDisabledWidget')
self.genericDisabledLayout = QtGui.QVBoxLayout(self.genericDisabledWidget)
self.genericDisabledLayout.setMargin(0)
self.genericDisabledLayout.setSpacing(8)
self.genericDisabledLayout.setObjectName(u'genericDisabledLayout')
self.genericDisabledLabel = QtGui.QLabel(self.genericDisabledWidget)
self.genericDisabledLabel.setWordWrap(True)
self.genericDisabledLabel.setObjectName(u'genericDisabledLabel')
self.genericDisabledWidget.setVisible(False)
self.genericDisabledLayout.addWidget(self.genericDisabledLabel)
self.genericLayout.addWidget(self.genericDisabledWidget)
self.genericImportWidget = QtGui.QWidget(self.genericPage)
self.genericImportWidget.setObjectName(u'genericImportWidget')
self.genericImportLayout = QtGui.QVBoxLayout(self.genericImportWidget)
self.genericImportLayout.setMargin(0)
self.genericImportLayout.setSpacing(8)
self.genericImportLayout.setObjectName(u'genericImportLayout')
self.genericFileListWidget = QtGui.QListWidget(self.genericImportWidget)
self.genericFileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
self.genericFileListWidget.setObjectName(u'genericFileListWidget')
self.genericImportLayout.addWidget(self.genericFileListWidget)
self.genericButtonLayout = QtGui.QHBoxLayout()
self.genericButtonLayout.setSpacing(8)
self.genericButtonLayout.setObjectName(u'genericButtonLayout')
self.genericAddButton = QtGui.QPushButton(self.genericImportWidget)
self.genericAddButton.setIcon(openIcon)
self.genericAddButton.setObjectName(u'genericAddButton')
self.genericButtonLayout.addWidget(self.genericAddButton)
self.genericButtonSpacer = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.genericButtonLayout.addItem(self.genericButtonSpacer)
self.genericRemoveButton = QtGui.QPushButton(self.genericImportWidget)
self.genericRemoveButton.setIcon(deleteIcon)
self.genericRemoveButton.setObjectName(u'genericRemoveButton')
self.genericButtonLayout.addWidget(self.genericRemoveButton)
self.genericImportLayout.addLayout(self.genericButtonLayout)
self.genericLayout.addWidget(self.genericImportWidget)
self.formatStackedWidget.addWidget(self.genericPage)
# Commented out for future use. # Commented out for future use.
# self.csvPage = QtGui.QWidget() # self.addSingleFileSelectItem(u'csv', u'CSV')
# self.csvPage.setObjectName(u'CSVPage')
# self.csvLayout = QtGui.QFormLayout(self.csvPage)
# self.csvLayout.setMargin(0)
# self.csvLayout.setSpacing(8)
# self.csvLayout.setObjectName(u'CSVLayout')
# self.csvFilenameLabel = QtGui.QLabel(self.csvPage)
# self.csvFilenameLabel.setObjectName(u'CSVFilenameLabel')
# self.csvLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
# self.csvFilenameLabel)
# self.csvFileLayout = QtGui.QHBoxLayout()
# self.csvFileLayout.setSpacing(8)
# self.csvFileLayout.setObjectName(u'CSVFileLayout')
# self.csvFilenameEdit = QtGui.QLineEdit(self.csvPage)
# self.csvFilenameEdit.setObjectName(u'CSVFilenameEdit')
# self.csvFileLayout.addWidget(self.csvFilenameEdit)
# self.csvBrowseButton = QtGui.QToolButton(self.csvPage)
# self.csvBrowseButton.setIcon(openIcon)
# self.csvBrowseButton.setObjectName(u'CSVBrowseButton')
# self.csvFileLayout.addWidget(self.csvBrowseButton)
# self.csvLayout.setLayout(0, QtGui.QFormLayout.FieldRole,
# self.csvFileLayout)
# self.formatStackedWidget.addWidget(self.csvPage)
self.sourceLayout.addWidget(self.formatStackedWidget) self.sourceLayout.addWidget(self.formatStackedWidget)
songImportWizard.addPage(self.sourcePage) songImportWizard.addPage(self.sourcePage)
self.importPage = QtGui.QWizardPage() self.importPage = QtGui.QWizardPage()
@ -497,7 +178,9 @@ class Ui_SongImportWizard(object):
self.formatComboBox.setItemText(7, self.formatComboBox.setItemText(7,
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Generic Document/Presentation')) 'Generic Document/Presentation'))
# self.formatComboBox.setItemText(8, self.formatComboBox.setItemText(8,
translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
# self.formatComboBox.setItemText(9,
# translate('SongsPlugin.ImportWizardForm', 'CSV')) # translate('SongsPlugin.ImportWizardForm', 'CSV'))
self.openLP2FilenameLabel.setText( self.openLP2FilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:')) translate('SongsPlugin.ImportWizardForm', 'Filename:'))
@ -549,6 +232,10 @@ class Ui_SongImportWizard(object):
translate('SongsPlugin.ImportWizardForm', 'The generic document/' translate('SongsPlugin.ImportWizardForm', 'The generic document/'
'presentation importer has been disabled because OpenLP cannot ' 'presentation importer has been disabled because OpenLP cannot '
'find OpenOffice.org on your computer.')) 'find OpenOffice.org on your computer.'))
self.ewFilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
self.ewBrowseButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Browse...'))
# self.csvFilenameLabel.setText( # self.csvFilenameLabel.setText(
# translate('SongsPlugin.ImportWizardForm', 'Filename:')) # translate('SongsPlugin.ImportWizardForm', 'Filename:'))
# self.csvBrowseButton.setText( # self.csvBrowseButton.setText(
@ -562,3 +249,123 @@ class Ui_SongImportWizard(object):
translate('SongsPlugin.ImportWizardForm', 'Ready.')) translate('SongsPlugin.ImportWizardForm', 'Ready.'))
self.importProgressBar.setFormat( self.importProgressBar.setFormat(
translate('SongsPlugin.ImportWizardForm', '%p%')) translate('SongsPlugin.ImportWizardForm', '%p%'))
def addSingleFileSelectItem(self, prefix, obj_prefix=None,
can_disable=False):
if not obj_prefix:
obj_prefix = prefix
page = QtGui.QWidget()
page.setObjectName(obj_prefix + u'Page')
if can_disable:
importWidget = self.disablableWidget(page, prefix, obj_prefix)
else:
importWidget = page
importLayout = QtGui.QFormLayout(importWidget)
importLayout.setMargin(0)
importLayout.setSpacing(8)
if can_disable:
importLayout.setObjectName(obj_prefix + u'ImportLayout')
else:
importLayout.setObjectName(obj_prefix + u'Layout')
filenameLabel = QtGui.QLabel(importWidget)
filenameLabel.setObjectName(obj_prefix + u'FilenameLabel')
importLayout.setWidget(0, QtGui.QFormLayout.LabelRole, filenameLabel)
fileLayout = QtGui.QHBoxLayout()
fileLayout.setSpacing(8)
fileLayout.setObjectName(obj_prefix + u'FileLayout')
filenameEdit = QtGui.QLineEdit(importWidget)
filenameEdit.setObjectName(obj_prefix + u'FilenameEdit')
fileLayout.addWidget(filenameEdit)
browseButton = QtGui.QToolButton(importWidget)
browseButton.setIcon(self.openIcon)
browseButton.setObjectName(obj_prefix + u'BrowseButton')
fileLayout.addWidget(browseButton)
importLayout.setLayout(0, QtGui.QFormLayout.FieldRole, fileLayout)
self.formatStackedWidget.addWidget(page)
setattr(self, prefix + u'Page', page)
setattr(self, prefix + u'FilenameLabel', filenameLabel)
setattr(self, prefix + u'FileLayout', fileLayout)
setattr(self, prefix + u'FilenameEdit', filenameEdit)
setattr(self, prefix + u'BrowseButton', browseButton)
if can_disable:
setattr(self, prefix + u'ImportLayout', importLayout)
else:
setattr(self, prefix + u'Layout', importLayout)
self.formatComboBox.addItem(u'')
def addMultiFileSelectItem(self, prefix, obj_prefix=None,
can_disable=False):
if not obj_prefix:
obj_prefix = prefix
page = QtGui.QWidget()
page.setObjectName(obj_prefix + u'Page')
if can_disable:
importWidget = self.disablableWidget(page, prefix, obj_prefix)
else:
importWidget = page
importLayout = QtGui.QVBoxLayout(importWidget)
importLayout.setMargin(0)
importLayout.setSpacing(8)
if can_disable:
importLayout.setObjectName(obj_prefix + u'ImportLayout')
else:
importLayout.setObjectName(obj_prefix + u'Layout')
fileListWidget = QtGui.QListWidget(importWidget)
fileListWidget.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
fileListWidget.setObjectName(obj_prefix + u'FileListWidget')
importLayout.addWidget(fileListWidget)
buttonLayout = QtGui.QHBoxLayout()
buttonLayout.setSpacing(8)
buttonLayout.setObjectName(obj_prefix + u'ButtonLayout')
addButton = QtGui.QPushButton(importWidget)
addButton.setIcon(self.openIcon)
addButton.setObjectName(obj_prefix + u'AddButton')
buttonLayout.addWidget(addButton)
buttonSpacer = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
buttonLayout.addItem(buttonSpacer)
removeButton = QtGui.QPushButton(importWidget)
removeButton.setIcon(self.deleteIcon)
removeButton.setObjectName(obj_prefix + u'RemoveButton')
buttonLayout.addWidget(removeButton)
importLayout.addLayout(buttonLayout)
self.formatStackedWidget.addWidget(page)
setattr(self, prefix + u'Page', page)
setattr(self, prefix + u'FileListWidget', fileListWidget)
setattr(self, prefix + u'ButtonLayout', buttonLayout)
setattr(self, prefix + u'ButtonSpacer', buttonSpacer)
setattr(self, prefix + u'AddButton', addButton)
setattr(self, prefix + u'RemoveButton', removeButton)
if can_disable:
setattr(self, prefix + u'ImportLayout', importLayout)
else:
setattr(self, prefix + u'Layout', importLayout)
self.formatComboBox.addItem(u'')
def disablableWidget(self, page, prefix, obj_prefix):
layout = QtGui.QVBoxLayout(page)
layout.setMargin(0)
layout.setSpacing(0)
layout.setObjectName(obj_prefix + u'Layout')
disabledWidget = QtGui.QWidget(page)
disabledWidget.setVisible(False)
disabledWidget.setObjectName(obj_prefix + u'DisabledWidget')
disabledLayout = QtGui.QVBoxLayout(disabledWidget)
disabledLayout.setMargin(0)
disabledLayout.setSpacing(8)
disabledLayout.setObjectName(obj_prefix + u'DisabledLayout')
disabledLabel = QtGui.QLabel(disabledWidget)
disabledLabel.setWordWrap(True)
disabledLabel.setObjectName(obj_prefix + u'DisabledLabel')
disabledLayout.addWidget(disabledLabel)
layout.addWidget(disabledWidget)
importWidget = QtGui.QWidget(page)
importWidget.setObjectName(obj_prefix + u'ImportWidget')
layout.addWidget(importWidget)
setattr(self, prefix + u'Layout', layout)
setattr(self, prefix + u'DisabledWidget', disabledWidget)
setattr(self, prefix + u'DisabledLayout', disabledLayout)
setattr(self, prefix + u'DisabledLabel', disabledLabel)
setattr(self, prefix + u'ImportWidget', importWidget)
return importWidget

View File

@ -0,0 +1,255 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
"""
The :mod:`ewimport` module provides the functionality for importing
EasyWorship song databases into the current installation database.
"""
import sys
import os
import struct
from songimport import SongImport
def strip_rtf(blob):
depth = 0
control = False
clear_text = []
control_word = []
for c in blob:
if control:
# for delimiters, set control to False
if c == '{':
if len(control_word) > 0:
depth += 1
control = False
elif c == '}':
if len(control_word) > 0:
depth -= 1
control = False
elif c == '\\':
new_control = (len(control_word) > 0)
control = False
elif c.isspace():
control = False
else:
control_word.append(c)
if len(control_word) == 3 and control_word[0] == '\'':
control = False
if not control:
if len(control_word) == 0:
if c == '{' or c == '}' or c == '\\':
clear_text.append(c)
else:
control_str = ''.join(control_word)
if control_str == 'par' or control_str == 'line':
clear_text.append(u'\n')
elif control_str == 'tab':
clear_text.append(u'\n')
elif control_str[0] == '\'':
# Really should take RTF character set into account but
# for now assume ANSI (Windows-1252) and call it good
s = chr(int(control_str[1:3], 16))
clear_text.append(s.decode(u'windows-1252'))
del control_word[:]
if c == '\\' and new_control:
control = True
elif c == '{':
depth += 1
elif c == '}':
depth -= 1
elif depth > 2:
continue
elif c == '\n' or c == '\r':
continue
elif c == '\\':
control = True
else:
clear_text.append(c)
return u''.join(clear_text)
class FieldDescEntry:
def __init__(self, name, type, size):
self.name = name
self.type = type
self.size = size
class EasyWorshipSongImport(SongImport):
"""
The :class:`EasyWorshipSongImport` class provides OpenLP with the
ability to import EasyWorship song files.
"""
def __init__(self, manager, **kwargs):
self.import_source = kwargs[u'filename']
SongImport.__init__(self, manager)
def do_import(self):
# Open the DB and MB files if they exist
import_source_mb = self.import_source.replace('.DB', '.MB')
if not os.path.isfile(self.import_source):
return False
if not os.path.isfile(import_source_mb):
return False
db_size = os.path.getsize(self.import_source)
if db_size < 0x800:
return False
db_file = open(self.import_source, 'rb')
self.memo_file = open(import_source_mb, 'rb')
# Don't accept files that are clearly not paradox files
record_size, header_size, block_size, first_block, num_fields \
= struct.unpack('<hhxb8xh17xh', db_file.read(35))
if header_size != 0x800 or block_size < 1 or block_size > 4:
db_file.close()
self.memo_file.close()
return False
# There does not appear to be a _reliable_ way of getting the number
# of songs/records, so let's use file blocks for measuring progress.
total_blocks = (db_size - header_size) / (block_size * 1024)
self.import_wizard.importProgressBar.setMaximum(total_blocks)
# Read the field description information
db_file.seek(120)
field_info = db_file.read(num_fields * 2)
db_file.seek(4 + (num_fields * 4) + 261, os.SEEK_CUR)
field_names = db_file.read(header_size - db_file.tell()).split('\0',
num_fields)
field_names.pop()
field_descs = []
for i,field_name in enumerate(field_names):
field_type, field_size = struct.unpack_from('BB', field_info, i * 2)
field_descs.append(FieldDescEntry(field_name, field_type,
field_size))
self.set_record_struct(field_descs)
# Pick out the field description indexes we will need
success = True
try:
fi_title = self.find_field(u'Title')
fi_author = self.find_field(u'Author')
fi_copy = self.find_field(u'Copyright')
fi_admin = self.find_field(u'Administrator')
fi_words = self.find_field(u'Words')
fi_ccli = self.find_field(u'Song Number')
except IndexError:
# This is the wrong table
success = False
# Loop through each block of the file
cur_block = first_block
while cur_block != 0 and success:
db_file.seek(header_size + ((cur_block - 1) * 1024 * block_size))
cur_block, rec_count = struct.unpack('<h2xh', db_file.read(6))
rec_count = (rec_count + record_size) / record_size
# Loop through each record within the current block
for i in range(rec_count):
if self.stop_import_flag:
success = False
break
raw_record = db_file.read(record_size)
self.fields = self.record_struct.unpack(raw_record)
self.set_defaults()
self.title = self.get_field(fi_title)
self.import_wizard.incrementProgressBar(
u'Importing "%s"...' % self.title, 0)
self.copyright = self.get_field(fi_copy) + \
u', Administered by ' + self.get_field(fi_admin)
self.ccli_number = self.get_field(fi_ccli)
# Format the lyrics
if self.stop_import_flag:
success = False
break
words = self.get_field(fi_words)
words = strip_rtf(words)
for verse in words.split(u'\n\n'):
self.add_verse(verse.strip(), u'V')
# Split up the authors
authors = self.get_field(fi_author)
author_list = authors.split(u'/')
if len(author_list) < 2:
author_list = authors.split(u',')
for author_name in author_list:
self.add_author(author_name.strip())
if self.stop_import_flag:
success = False
break
self.finish()
if not self.stop_import_flag:
self.import_wizard.incrementProgressBar(u'')
db_file.close()
self.memo_file.close()
return success
def find_field(self, field_name):
return [i for i,x in enumerate(self.field_descs) \
if x.name == field_name][0]
def set_record_struct(self, field_descs):
# Begin with empty field struct list
fsl = ['>']
for field_desc in field_descs:
if field_desc.type == 1:
# string
fsl.append('%ds' % field_desc.size)
elif field_desc.type == 3:
# 16-bit int
fsl.append('H')
elif field_desc.type == 4:
# 32-bit int
fsl.append('I')
elif field_desc.type == 9:
# Logical
fsl.append('B')
elif field_desc.type == 0x0c:
# Memo
fsl.append('%ds' % field_desc.size)
elif field_desc.type == 0x0d:
# Blob
fsl.append('%ds' % field_desc.size)
elif field_desc.type == 0x15:
# Timestamp
fsl.append('Q')
else:
fsl.append('%ds' % field_desc.size)
self.record_struct = struct.Struct(''.join(fsl))
self.field_descs = field_descs
def get_field(self, field_desc_index):
field = self.fields[field_desc_index]
field_desc = self.field_descs[field_desc_index]
# Check for 'blank' entries
if isinstance(field, str):
if len(field.rstrip('\0')) == 0:
return u''
elif field == 0:
return 0
# Format the field depending on the field type
if field_desc.type == 1:
# string
return field.rstrip('\0').decode(u'windows-1252')
elif field_desc.type == 3:
# 16-bit int
return field ^ 0x8000
elif field_desc.type == 4:
# 32-bit int
return field ^ 0x80000000
elif field_desc.type == 9:
# Logical
return (field ^ 0x80 == 1)
elif field_desc.type == 0x0c or field_desc.type == 0x0d:
# Memo or Blob
sub_block, block_start, blob_size = \
struct.unpack_from('<bhxi', field, len(field)-10)
self.memo_file.seek(block_start * 256)
memo_block_type, = struct.unpack('b', self.memo_file.read(1))
if memo_block_type == 2:
self.memo_file.seek(8, os.SEEK_CUR)
elif memo_block_type == 3:
if sub_block < 0 or sub_block > 63:
return u'';
self.memo_file.seek(11 + (5 * sub_block), os.SEEK_CUR)
sub_block_start, = struct.unpack('B', self.memo_file.read(1))
self.memo_file.seek((block_start * 256) +
(sub_block_start * 16))
else:
return u'';
return self.memo_file.read(blob_size)
else:
return 0

View File

@ -28,6 +28,7 @@ from opensongimport import OpenSongImport
from olpimport import OpenLPSongImport from olpimport import OpenLPSongImport
from wowimport import WowImport from wowimport import WowImport
from cclifileimport import CCLIFileImport from cclifileimport import CCLIFileImport
from ewimport import EasyWorshipSongImport
# Imports that might fail # Imports that might fail
try: try:
from olp1import import OpenLP1SongImport from olp1import import OpenLP1SongImport
@ -61,7 +62,8 @@ class SongFormat(object):
CCLI = 5 CCLI = 5
SongsOfFellowship = 6 SongsOfFellowship = 6
Generic = 7 Generic = 7
CSV = 8 #CSV = 8
EasyWorship = 8
@staticmethod @staticmethod
def get_class(format): def get_class(format):
@ -85,6 +87,8 @@ class SongFormat(object):
return OooImport return OooImport
elif format == SongFormat.CCLI: elif format == SongFormat.CCLI:
return CCLIFileImport return CCLIFileImport
elif format == SongFormat.EasyWorship:
return EasyWorshipSongImport
# else: # else:
return None return None
@ -101,7 +105,8 @@ class SongFormat(object):
SongFormat.WordsOfWorship, SongFormat.WordsOfWorship,
SongFormat.CCLI, SongFormat.CCLI,
SongFormat.SongsOfFellowship, SongFormat.SongsOfFellowship,
SongFormat.Generic SongFormat.Generic,
SongFormat.EasyWorship
] ]
@staticmethod @staticmethod

View File

@ -166,13 +166,13 @@ class SongMediaItem(MediaManagerItem):
if search_type == 0: if search_type == 0:
log.debug(u'Titles Search') log.debug(u'Titles Search')
search_results = self.parent.manager.get_all_objects(Song, search_results = self.parent.manager.get_all_objects(Song,
Song.search_title.like(u'%' + search_keywords + u'%'), Song.search_title.like(u'%' + search_keywords.lower() + u'%'),
Song.search_title.asc()) Song.search_title.asc())
self.displayResultsSong(search_results) self.displayResultsSong(search_results)
elif search_type == 1: elif search_type == 1:
log.debug(u'Lyrics Search') log.debug(u'Lyrics Search')
search_results = self.parent.manager.get_all_objects(Song, search_results = self.parent.manager.get_all_objects(Song,
Song.search_lyrics.like(u'%' + search_keywords + u'%'), Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'),
Song.search_lyrics.asc()) Song.search_lyrics.asc())
self.displayResultsSong(search_results) self.displayResultsSong(search_results)
elif search_type == 2: elif search_type == 2:

View File

@ -59,6 +59,7 @@ class OooImport(SongImport):
self.document = None self.document = None
self.process_started = False self.process_started = False
self.filenames = kwargs[u'filenames'] self.filenames = kwargs[u'filenames']
self.uno_connection_type = u'pipe' #u'socket'
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'song_stop_import'), self.stop_import) QtCore.SIGNAL(u'song_stop_import'), self.stop_import)
@ -106,8 +107,14 @@ class OooImport(SongImport):
loop = 0 loop = 0
while ctx is None and loop < 5: while ctx is None and loop < 5:
try: try:
ctx = resolver.resolve(u'uno:socket,host=localhost,' \ if self.uno_connection_type == u'pipe':
+ 'port=2002;urp;StarOffice.ComponentContext') ctx = resolver.resolve(u'uno:' \
+ u'pipe,name=openlp_pipe;' \
+ u'urp;StarOffice.ComponentContext')
else:
ctx = resolver.resolve(u'uno:' \
+ u'socket,host=localhost,port=2002;' \
+ u'urp;StarOffice.ComponentContext')
except: except:
pass pass
self.start_ooo_process() self.start_ooo_process()
@ -123,9 +130,14 @@ class OooImport(SongImport):
self.manager._FlagAsMethod(u'Bridge_GetStruct') self.manager._FlagAsMethod(u'Bridge_GetStruct')
self.manager._FlagAsMethod(u'Bridge_GetValueObject') self.manager._FlagAsMethod(u'Bridge_GetValueObject')
else: else:
cmd = u'openoffice.org -nologo -norestore -minimized ' \ if self.uno_connection_type == u'pipe':
+ u'-invisible -nofirststartwizard ' \ cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ '-accept="socket,host=localhost,port=2002;urp;"' + u'-invisible -nofirststartwizard ' \
+ u'-accept=pipe,name=openlp_pipe;urp;'
else:
cmd = u'openoffice.org -nologo -norestore -minimized ' \
+ u'-invisible -nofirststartwizard ' \
+ u'-accept=socket,host=localhost,port=2002;urp;'
process = QtCore.QProcess() process = QtCore.QProcess()
process.startDetached(cmd) process.startDetached(cmd)
process.waitForStarted() process.waitForStarted()

View File

@ -55,6 +55,7 @@ class SongImport(QtCore.QObject):
self.set_defaults() self.set_defaults()
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'songs_stop_import'), self.stop_import) QtCore.SIGNAL(u'songs_stop_import'), self.stop_import)
def set_defaults(self): def set_defaults(self):
""" """
Create defaults for properties - call this before each song Create defaults for properties - call this before each song
@ -262,8 +263,8 @@ class SongImport(QtCore.QObject):
log.info(u'commiting song %s to database', self.title) log.info(u'commiting song %s to database', self.title)
song = Song() song = Song()
song.title = self.title song.title = self.title
song.search_title = self.remove_punctuation(self.title) \ song.search_title = self.remove_punctuation(self.title).lower() \
+ '@' + self.alternate_title + '@' + self.remove_punctuation(self.alternate_title).lower()
song.song_number = self.song_number song.song_number = self.song_number
song.search_lyrics = u'' song.search_lyrics = u''
verses_changed_to_other = {} verses_changed_to_other = {}
@ -291,6 +292,7 @@ class SongImport(QtCore.QObject):
versetag = newversetag versetag = newversetag
sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext) sxml.add_verse_to_lyrics(versetype, versetag[1:], versetext)
song.search_lyrics += u' ' + self.remove_punctuation(versetext) song.search_lyrics += u' ' + self.remove_punctuation(versetext)
song.search_lyrics = song.search_lyrics.lower()
song.lyrics = unicode(sxml.extract_xml(), u'utf-8') song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
for i, current_verse_tag in enumerate(self.verse_order_list): for i, current_verse_tag in enumerate(self.verse_order_list):
if verses_changed_to_other.has_key(current_verse_tag): if verses_changed_to_other.has_key(current_verse_tag):

0
openlp/plugins/songs/lib/test/test3.opensong Executable file → Normal file
View File

View File

@ -50,7 +50,7 @@ class SongsPlugin(Plugin):
""" """
Create and set up the Songs plugin. Create and set up the Songs plugin.
""" """
Plugin.__init__(self, u'Songs', u'1.9.2', plugin_helpers) Plugin.__init__(self, u'Songs', u'1.9.3', plugin_helpers)
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'
@ -63,7 +63,7 @@ class SongsPlugin(Plugin):
log.info(u'Songs Initialising') log.info(u'Songs Initialising')
Plugin.initialise(self) Plugin.initialise(self)
self.mediaItem.displayResultsSong( self.mediaItem.displayResultsSong(
self.manager.get_all_objects(Song, order_by_ref=Song.title)) self.manager.get_all_objects(Song, order_by_ref=Song.search_title))
def getMediaManagerItem(self): def getMediaManagerItem(self):
""" """

View File

@ -41,7 +41,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', u'1.9.2', plugin_helpers) Plugin.__init__(self, u'SongUsage', u'1.9.3', 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.songusagemanager = None self.songusagemanager = None

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

0
resources/images/about-new.bmp Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

17
resources/openlp.desktop Normal file → Executable file
View File

@ -1,10 +1,21 @@
[Desktop Entry] [Desktop Entry]
Categories=AudioVideo;
Comment[de]=
Comment=
Encoding=UTF-8 Encoding=UTF-8
Name=OpenLP
GenericName=Church lyrics projection
Exec=openlp Exec=openlp
GenericName[de]=Church lyrics projection
GenericName=Church lyrics projection
Icon=openlp Icon=openlp
MimeType=
Name[de]=OpenLP
Name=OpenLP
Path=
StartupNotify=true StartupNotify=true
Terminal=false Terminal=false
TerminalOptions=
Type=Application Type=Application
Categories=AudioVideo; X-DBUS-ServiceName=
X-DBUS-StartupType=
X-KDE-SubstituteUID=false
X-KDE-Username=

View File

@ -127,6 +127,8 @@ def import_bible():
for row in rows: for row in rows:
key = unicode(row[0], u'cp1252') key = unicode(row[0], u'cp1252')
value = unicode(row[1], u'cp1252') value = unicode(row[1], u'cp1252')
if key == u'Permission':
key = u'Permissions'
sql_insert = u'INSERT INTO metadata '\ sql_insert = u'INSERT INTO metadata '\
'("key", "value") '\ '("key", "value") '\
'VALUES (?, ?)' 'VALUES (?, ?)'

View File

@ -52,6 +52,7 @@ This is done easily via the ``-d``, ``-p`` and ``-u`` options::
import os import os
import urllib import urllib
import re import re
from shutil import copy
from optparse import OptionParser from optparse import OptionParser
from PyQt4 import QtCore from PyQt4 import QtCore
@ -85,7 +86,9 @@ class CommandStack(object):
return len(self.data) return len(self.data)
def __getitem__(self, index): def __getitem__(self, index):
if self.data[index].get(u'arguments'): if not index in self.data:
return None
elif self.data[index].get(u'arguments'):
return self.data[index][u'command'], self.data[index][u'arguments'] return self.data[index][u'command'], self.data[index][u'arguments']
else: else:
return self.data[index][u'command'] return self.data[index][u'command']
@ -110,6 +113,21 @@ class CommandStack(object):
def reset(self): def reset(self):
self.current_index = 0 self.current_index = 0
def arguments(self):
if self.data[self.current_index - 1].get(u'arguments'):
return self.data[self.current_index - 1][u'arguments']
else:
return []
def __repr__(self):
results = []
for item in self.data:
if item.get(u'arguments'):
results.append(str((item[u'command'], item[u'arguments'])))
else:
results.append(str((item[u'command'], )))
return u'[%s]' % u', '.join(results)
def print_verbose(text): def print_verbose(text):
""" """
@ -139,6 +157,21 @@ def run(command):
print_verbose(u'Output:\n%s' % process.readAllStandardOutput()) print_verbose(u'Output:\n%s' % process.readAllStandardOutput())
print u' Done.' print u' Done.'
def update_export_at_pootle(source_filename):
"""
This is needed because of database and exported *.ts file can be out of sync
``source_filename``
The file to sync.
"""
language = source_filename[:-3]
REVIEW_URL = u'http://pootle.projecthq.biz/%s/openlp/review.html' % language
print_verbose(u'Accessing: %s' % (REVIEW_URL))
page = urllib.urlopen(REVIEW_URL)
page.close()
def download_file(source_filename, dest_filename): def download_file(source_filename, dest_filename):
""" """
Download a file and save it to disk. Download a file and save it to disk.
@ -165,11 +198,13 @@ def download_translations():
page = urllib.urlopen(SERVER_URL) page = urllib.urlopen(SERVER_URL)
soup = BeautifulSoup(page) soup = BeautifulSoup(page)
languages = soup.findAll(text=re.compile(r'.*\.ts')) languages = soup.findAll(text=re.compile(r'.*\.ts'))
for language in languages: for language_file in languages:
update_export_at_pootle(language_file)
for language_file in languages:
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n', filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n',
language) language_file)
print_verbose(u'Get Translation File: %s' % filename) print_verbose(u'Get Translation File: %s' % filename)
download_file(language, filename) download_file(language_file, filename)
print u' Done.' print u' Done.'
def prepare_project(): def prepare_project():
@ -227,11 +262,12 @@ def update_translations():
else: else:
os.chdir(os.path.abspath(u'..')) os.chdir(os.path.abspath(u'..'))
run(u'pylupdate4 -verbose -noobsolete openlp.pro') run(u'pylupdate4 -verbose -noobsolete openlp.pro')
os.chdir(os.path.abspath(u'scripts'))
def generate_binaries(): def generate_binaries():
print u'Generate the related *.qm files' print u'Generate the related *.qm files'
if not os.path.exists(os.path.join(os.path.abspath(u'..'), u'openlp.pro')): if not os.path.exists(os.path.join(os.path.abspath(u'..'), u'openlp.pro')):
print u'You have no generated a project file yet, please run this ' + \ print u'You have not generated a project file yet, please run this ' + \
u'script with the -p option. It is also recommended that you ' + \ u'script with the -p option. It is also recommended that you ' + \
u'this script with the -u option to update the translation ' + \ u'this script with the -u option to update the translation ' + \
u'files as well.' u'files as well.'
@ -239,6 +275,17 @@ def generate_binaries():
else: else:
os.chdir(os.path.abspath(u'..')) os.chdir(os.path.abspath(u'..'))
run(u'lrelease openlp.pro') run(u'lrelease openlp.pro')
os.chdir(os.path.abspath(u'scripts'))
src_path = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n')
dest_path = os.path.join(os.path.abspath(u'..'), u'openlp', u'i18n')
if not os.path.exists(dest_path):
os.makedirs(dest_path)
src_list = os.listdir(src_path)
for file in src_list:
if re.search('.qm$', file):
copy(os.path.join(src_path, u'%s' % file),
os.path.join(dest_path, u'%s' % file))
def create_translation(language): def create_translation(language):
""" """
@ -248,13 +295,15 @@ def create_translation(language):
The language file to create. The language file to create.
""" """
print "Create new Translation File" print "Create new Translation File"
if not language.endswith(u'.ts'):
language += u'.ts'
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n', language) filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n', language)
download_file(u'en.ts', filename) download_file(u'en.ts', filename)
print u'\n** Please Note **\n' print u' ** Please Note **'
print u'In order to get this file into OpenLP and onto the Pootle ' + \ print u' In order to get this file into OpenLP and onto the Pootle ' + \
u'translation server you will need to subscribe to the OpenLP' + \ u'translation server you will need to subscribe to the OpenLP' + \
u'Translators mailing list, and request that your language file ' + \ u'Translators mailing list, and request that your language file ' + \
u'be added to the project.\n' u'be added to the project.'
print u' Done' print u' Done'
def process_stack(command_stack): def process_stack(command_stack):
@ -278,7 +327,7 @@ def process_stack(command_stack):
elif command == Command.Generate: elif command == Command.Generate:
generate_binaries() generate_binaries()
elif command == Command.Create: elif command == Command.Create:
command, arguments = command_stack[command_stack.current_index] arguments = command_stack.arguments()
create_translation(*arguments) create_translation(*arguments)
print u'Finished processing commands.' print u'Finished processing commands.'
else: else:
@ -293,7 +342,7 @@ def main():
parser = OptionParser(usage=usage) parser = OptionParser(usage=usage)
parser.add_option('-d', '--download-ts', dest='download', parser.add_option('-d', '--download-ts', dest='download',
action='store_true', help='download language files from Pootle') action='store_true', help='download language files from Pootle')
parser.add_option('-c', '--create', dest=u'create', metavar='LANG', parser.add_option('-c', '--create', dest='create', metavar='LANG',
help='create a new translation file for language LANG, e.g. "en_GB"') help='create a new translation file for language LANG, e.g. "en_GB"')
parser.add_option('-p', '--prepare', dest='prepare', action='store_true', parser.add_option('-p', '--prepare', dest='prepare', action='store_true',
help='generate a project file, used to update the translations') help='generate a project file, used to update the translations')
@ -330,4 +379,3 @@ if __name__ == u'__main__':
print u'You need to run this script from the scripts directory.' print u'You need to run this script from the scripts directory.'
else: else:
main() main()

View File

@ -179,7 +179,16 @@ def copy_windows_files():
copy(os.path.join(iss_path, u'OpenLP.ico'), os.path.join(dist_path, u'OpenLP.ico')) copy(os.path.join(iss_path, u'OpenLP.ico'), os.path.join(dist_path, u'OpenLP.ico'))
copy(os.path.join(iss_path, u'LICENSE.txt'), os.path.join(dist_path, u'LICENSE.txt')) copy(os.path.join(iss_path, u'LICENSE.txt'), os.path.join(dist_path, u'LICENSE.txt'))
def update_translations():
print u'Updating translations...'
os.chdir(script_path)
translation_utils = Popen(u'python translation_utils.py -dpu')
code = translation_utils.wait()
if code != 0:
print u'Error running translation_utils.py'
def compile_translations(): def compile_translations():
print u'Compiling translations...'
files = os.listdir(i18n_path) files = os.listdir(i18n_path)
if not os.path.exists(os.path.join(dist_path, u'i18n')): if not os.path.exists(os.path.join(dist_path, u'i18n')):
os.makedirs(os.path.join(dist_path, u'i18n')) os.makedirs(os.path.join(dist_path, u'i18n'))
@ -221,6 +230,7 @@ def main():
copy_enchant() copy_enchant()
copy_plugins() copy_plugins()
copy_windows_files() copy_windows_files()
update_translations()
compile_translations() compile_translations()
run_innosetup() run_innosetup()
print "Done." print "Done."