New branch

This commit is contained in:
Tim Bentley 2010-07-13 18:27:04 +01:00
commit 5c3d32cfd9
11 changed files with 999 additions and 495 deletions

View File

@ -165,15 +165,41 @@ def context_menu_separator(base):
action.setSeparator(True)
return action
def resize_image(image, width, height):
def image_to_byte(image):
"""
Resize an image to fit on the current screen for the web and retuns
it as a byte stream.
``image``
The image to converted.
"""
byte_array = QtCore.QByteArray()
buffer = QtCore.QBuffer(byte_array) #// use buffer to store pixmap into byteArray
buffer.open(QtCore.QIODevice.WriteOnly)
if isinstance(image, QtGui.QImage):
pixmap = QtGui.QPixmap.fromImage(image)
else:
pixmap = QtGui.QPixmap(image)
pixmap.save(buffer, "PNG")
#convert to base64 encoding so does not get missed!
return byte_array.toBase64()
def resize_image(image, width, height, background=QtCore.Qt.black):
"""
Resize an image to fit on the current screen.
``image``
The image to resize.
``width``
The new image width.
``height``
The new image height.
``background ``
The background colour defaults to black.
"""
preview = QtGui.QImage(image)
if not preview.isNull():
#Only resize if different size
if preview.width() == width and preview.height == height:
return preview
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
@ -183,7 +209,7 @@ def resize_image(image, width, height):
# and move it to the centre of the preview space
new_image = QtGui.QImage(width, height,
QtGui.QImage.Format_ARGB32_Premultiplied)
new_image.fill(QtCore.Qt.black)
new_image.fill(background)
painter = QtGui.QPainter(new_image)
painter.drawImage((width - realw) / 2, (height - realh) / 2, preview)
return new_image
@ -212,6 +238,7 @@ from settingstab import SettingsTab
from serviceitem import ServiceItem
from serviceitem import ServiceItemType
from serviceitem import ItemCapabilities
from htmlbuilder import build_html
from toolbar import OpenLPToolbar
from dockwidget import OpenLPDockWidget
from theme import ThemeLevel, ThemeXML

View File

@ -0,0 +1,171 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from openlp.core.lib import image_to_byte
HTMLSRC = u"""
<html>
<head>
<title>OpenLP Display</title>
<style>
*{
margin: 0;
padding:0
}
%s
%s
%s
%s
%s
</style>
<script language="javascript">
var t = null;
function startfade(newtext){
var text1 = document.getElementById('lyrics');
var text2 = document.getElementById('lyrics2');
if(text2.style.opacity==''||parseFloat(text2.style.opacity) < 0.5){
text2.innerHTML = text1.innerHTML;
text2.style.opacity = text1.style.opacity;
}
text1.style.opacity = 0;
text1.innerHTML = newtext;
if(t!=null)
clearTimeout(t);
t = setTimeout('fade()', 50);
}
function fade(){
var text1 = document.getElementById('lyrics');
var text2 = document.getElementById('lyrics2');
if(parseFloat(text1.style.opacity) < 1)
text1.style.opacity = parseFloat(text1.style.opacity) + 0.02;
if(parseFloat(text2.style.opacity) > 0)
text2.style.opacity = parseFloat(text2.style.opacity) - 0.02;
if((parseFloat(text1.style.opacity) < 1)||(parseFloat(text2.style.opacity) > 0))
t = setTimeout('fade()', 50);
}
</script>
</head>
<body>
<div id="lyrics" class="lyrics"></div>
<div id="lyrics2" class="lyrics"></div>
<div id="alert"></div>
<video id="video"></video>
%s
</body>
</html>
"""
def build_html(theme, screen, alert, image):
width = screen[u'size'].width()
height = screen[u'size'].height()
html = HTMLSRC % (build_video(theme, width, height, alert),
build_image(theme, width, height, alert),
build_lyrics(theme, width, height, alert),
build_alert(theme, width, height, alert),
build_image(theme, width, height, alert),
build_image_src(theme, width, height, alert, image))
print html
return html
def build_video(theme, width, height, alert):
video = """
#video {
position: absolute;
left: 0px;
top: 0px;
width: 640px
height: 480px;
z-index:1;
}
"""
return video
def build_image(theme, width, height, alert):
image = """
#image {
position: absolute;
left: 0px;
top: 0px;
width: %spx;
height: %spx;
z-index:2;
}
"""
return image % (width, height)
def build_image_src(theme, width, height, alert, image):
# <img src="" height="480" width="640" />
image_src = """
<img src="data:image/png;base64,%s">";
"""
return image_src % image_to_byte(image)
def build_lyrics(theme, width, height, alert):
lyrics = """
#lyrics {
position: absolute;
left: 0px;
top: 0px;
width: 640px;
height: 480px;
z-index:3;
%s;
%s;
font-family %s;
font-size: %spx;
}
"""
lyrics_html = u''
shadow = u''
outline = u''
if theme:
if theme.display_shadow:
shadow = u'text-shadow: %spx %spx %spx %s' %\
(theme.display_shadow_size, theme.display_shadow_size,
theme.display_shadow_size, theme.display_shadow_color)
if theme.display_outline:
# 1px is the blur radius
outline = u'text-outline: %spx 1px %s' %\
(theme.display_outline_size, theme.display_outline_color)
lyrics_html = lyrics % (shadow, outline, theme.font_main_name, theme.font_main_proportion)
print lyrics_html
return lyrics_html
def build_alert(theme, width, height, alert):
alert = """
#alert {
position: absolute;
left: 0px;
top: 70px;
width: %spx;
height: 10px;
z-index:4;
font-size: 50px;
}
#alert p {
background-color: red;
}
"""
return alert % (width)

View File

@ -145,8 +145,46 @@ class Renderer(object):
for line in lines:
text.append(line)
split_text = self.pre_render_text(text)
doc = QtGui.QTextDocument()
doc.setPageSize(QtCore.QSizeF(self._rect.width(), self._rect.height()))
df = doc.defaultFont()
df.setPixelSize(self._theme.font_main_proportion)
df.setFamily(self._theme.font_main_name)
main_weight = 50
if self._theme.font_main_weight == u'Bold':
main_weight = 75
df.setWeight(main_weight)
doc.setDefaultFont(df)
myCursor = QtGui.QTextCursor(doc)
layout = doc.documentLayout()
formatted = []
if self._theme.display_horizontalAlign == 2:
shell = "<p align=center>%s</font></p>"
elif self._theme.display_horizontalAlign == 1:
shell = "<p align=right>%s</font></p>"
else:
shell = "<p>%s</p>"
temp_text = u''
old_html_text = u''
page = []
for line in text:
# mark line ends
temp_text = temp_text + line + u'<br>'
html_text = shell % temp_text
doc.setHtml(html_text)
#Text too long so gone to next mage
if layout.pageCount() != 1:
page.append(shell % old_html_text)
formatted.append(page)
temp_text = line
old_html_text = temp_text
page.append(shell % old_html_text)
formatted.append(page)
log.debug(u'format_slide - End')
return split_text
#return split_text
return formatted
def pre_render_text(self, text):
metrics = QtGui.QFontMetrics(self.main_font)

View File

@ -98,9 +98,11 @@ class RenderManager(object):
def set_override_theme(self, theme):
"""
Set the appropriate theme depending on the theme level.
Called by the service item when building a display frame
``theme``
The name of the song-level theme.
The name of the song-level theme. None means the service
item wants to use the given value.
"""
log.debug(u'set override theme to %s', theme)
if self.theme_level == ThemeLevel.Global:
@ -127,6 +129,7 @@ class RenderManager(object):
self.calculate_default(self.screens.current[u'size'])
self.renderer.set_theme(self.themedata)
self.build_text_rectangle(self.themedata)
return self.renderer.bg_frame
def build_text_rectangle(self, theme):
"""
@ -180,8 +183,9 @@ class RenderManager(object):
footer.append(u'CCLI 123456')
formatted = self.renderer.format_slide(verse, False)
#Only Render the first slide page returned
return self.renderer.generate_frame_from_lines(formatted[0],
footer)[u'main']
image = self.previewDisplay.preview(self.renderer.bg_frame, verse, self.themedata)
return image #self.renderer.generate_frame_from_lines(formatted[0],
#footer)[u'main']
def format_slide(self, words):
"""
@ -207,7 +211,9 @@ class RenderManager(object):
log.debug(u'generate slide')
self.build_text_rectangle(self.themedata)
self.renderer.set_frame_dest(self.width, self.height)
return self.renderer.generate_frame_from_lines(main_text, footer_text)
image = self.previewDisplay.preview(self.renderer.bg_frame,
main_text[0], self.themedata)
return image
def calculate_default(self, screen):
"""

View File

@ -167,21 +167,22 @@ class ServiceItem(object):
has generated by the render method above.
"""
log.debug(u'render individual')
changed = False
if self.theme is None:
self.render_manager.set_override_theme(None)
bg_image = self.render_manager.set_override_theme(None)
else:
self.render_manager.set_override_theme(self.theme)
format = self._display_frames[row][u'text'].split(u'\n')
bg_image = self.render_manager.set_override_theme(self.theme)
raw_html = self._display_frames[row][u'text'].split(u'\n')
if self.cache.get(row):
frame = self.cache[row]
else:
if format[0]:
frame = self.render_manager.generate_slide(format,
if raw_html[0]:
frame = self.render_manager.generate_slide(raw_html,
self.raw_footer)
else:
frame = self.render_manager.generate_slide(format, u'')
frame = self.render_manager.generate_slide(raw_html, u'')
self.cache[row] = frame
return frame
return bg_image, frame, raw_html[0]
def add_from_image(self, path, title, image):
"""
@ -370,7 +371,7 @@ class ServiceItem(object):
if self.service_item_type == ServiceItemType.Text:
return self.render_individual(row)
else:
return {u'main':self._raw_frames[row][u'image'], u'trans':None}
return self._raw_frames[row][u'image']
def get_frame_title(self, row=0):
"""

View File

@ -40,8 +40,6 @@ from slidecontroller import HideMode
from servicenoteform import ServiceNoteForm
from serviceitemeditform import ServiceItemEditForm
from screen import ScreenList
from maindisplay import MainDisplay
from maindisplay import VideoDisplay
from maindisplay import DisplayManager
from amendthemeform import AmendThemeForm
from slidecontroller import SlideController

File diff suppressed because it is too large Load Diff

View File

@ -527,7 +527,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.songsSettingsSection = u'songs'
self.serviceNotSaved = False
self.settingsmanager = SettingsManager(screens)
self.displayManager = DisplayManager(screens)
self.displayManager = DisplayManager(self, screens)
self.aboutForm = AboutForm(self, applicationVersion)
self.settingsForm = SettingsForm(self.screens, self, self)
self.recentFiles = QtCore.QStringList()

View File

@ -590,6 +590,7 @@ class SlideController(QtGui.QWidget):
else:
self.PreviewListWidget.selectRow(slideno)
self.enableToolBar(serviceItem)
#Reset the display html
self.onSlideSelected()
self.PreviewListWidget.setFocus()
Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix,
@ -769,23 +770,19 @@ class SlideController(QtGui.QWidget):
self.updatePreview()
else:
before = time.time()
frame = self.serviceItem.get_rendered_frame(row)
changed, frame, raw_html = self.serviceItem.get_rendered_frame(row)
if isinstance(frame, QtGui.QImage):
self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
else:
if isinstance(frame[u'main'], basestring):
self.SlidePreview.setPixmap(
QtGui.QPixmap(frame[u'main']))
else:
self.SlidePreview.setPixmap(
QtGui.QPixmap.fromImage(frame[u'main']))
self.SlidePreview.setPixmap(QtGui.QPixmap(frame))
log.log(
15, u'Slide Rendering took %4s' % (time.time() - before))
if self.isLive:
if self.serviceItem.is_text():
self.mainDisplay.frameView(frame, True)
self.displayManager.buildHtml(changed)
self.displayManager.text(raw_html)
else:
self.displayManager.displayImage(frame[u'main'])
self.displayManager.displayImage(frame)
self.selectedRow = row
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row)

View File

@ -521,16 +521,16 @@ class BibleMediaItem(MediaManagerItem):
permission = self._decodeQtObject(reference, 'permission')
if self.parent.settings_tab.display_style == 1:
verse_text = self.formatVerse(old_chapter, chapter, verse,
u'(u', u')')
u'<sup>(u', u')</sup>')
elif self.parent.settings_tab.display_style == 2:
verse_text = self.formatVerse(old_chapter, chapter, verse,
u'{', u'}')
u'<sup>{', u'}</sup>')
elif self.parent.settings_tab.display_style == 3:
verse_text = self.formatVerse(old_chapter, chapter, verse,
u'[', u']')
u'<sup>[', u']</sup>')
else:
verse_text = self.formatVerse(old_chapter, chapter, verse,
u'', u'')
u'<sup>', u'</sup>')
old_chapter = chapter
footer = u'%s (%s %s)' % (book, version, copyright)
#If not found add to footer

View File

@ -0,0 +1,91 @@
%{!?python_sitelib:%global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
Summary: Open source Church presentation and lyrics projection application
Name: OpenLP
Version: 1.9.1.1
Release: 1%{?dist}
Source0: http://downloads.sourceforge.net/openlp/openlp/%{version}/%{name}-%{version}.tar.gz
License: GPLv2
Group: Applications/Multimedia
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildArch: noarch
URL: http://openlp.org/
BuildRequires: desktop-file-utils
BuildRequires: python2-devel
BuildRequires: python-setuptools
Requires: PyQt4
Requires: phonon
Requires: python-BeautifulSoup
Requires: python-chardet
Requires: python-lxml
Requires: python-sqlalchemy
Requires: hicolor-icon-theme
%description
OpenLP is a church presentation software, for lyrics projection software,
used to display slides of Songs, Bible verses, videos, images, and
presentations (if OpenOffice.org is installed) using a computer and projector.
%prep
%setup -q
%build
python setup.py build
%install
rm -rf %{buildroot}
python setup.py install --skip-build -O1 --root %{buildroot}
install -m644 -p -D resources/images/openlp-logo-16x16.png \
%{buildroot}%{_datadir}/icons/hicolor/16x16/apps/openlp.png
install -m644 -p -D resources/images/openlp-logo-32x32.png \
%{buildroot}%{_datadir}/icons/hicolor/32x32/apps/openlp.png
install -m644 -p -D resources/images/openlp-logo-48x48.png \
%{buildroot}%{_datadir}/icons/hicolor/48x48/apps/openlp.png
install -m644 -p -D resources/images/openlp-logo.svg \
%{buildroot}%{_datadir}/icons/hicolor/scalable/apps/openlp.svg
desktop-file-install \
--dir %{buildroot}/%{_datadir}/applications \
resources/openlp.desktop
mv %{buildroot}%{_bindir}/bible-1to2-converter.py \
%{buildroot}%{_bindir}/bible-1to2-converter
mv %{buildroot}%{_bindir}/openlp-1to2-converter.py \
%{buildroot}%{_bindir}/openlp-1to2-converter
mv %{buildroot}%{_bindir}/openlp-remoteclient.py \
%{buildroot}%{_bindir}/openlp-remoteclient
mv %{buildroot}%{_bindir}/openlp.pyw %{buildroot}%{_bindir}/openlp
%post
touch --no-create %{_datadir}/icons/hicolor ||:
gtk-update-icon-cache -q %{_datadir}/icons/hicolor 2> /dev/null ||:
%postun
touch --no-create %{_datadir}/icons/hicolor ||:
gtk-update-icon-cache -q %{_datadir}/icons/hicolor 2> /dev/null ||:
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root)
%doc copyright.txt LICENSE
%{_bindir}/bible-1to2-converter
%{_bindir}/openlp-1to2-converter
%{_bindir}/openlp-remoteclient
%{_bindir}/openlp
%{_datadir}/applications/openlp.desktop
%{_datadir}/icons/hicolor/*/apps/openlp.*
%{python_sitelib}/openlp/
%{python_sitelib}/OpenLP-%{version}*.egg-info
%doc documentation/*.txt
%changelog
* Sun Mar 28 2010 Tim Bentley <timbentley@openlp.org> 1.9.1.1
- Initial build version - Alpha 1 Release