Updated tests to pass again.

Found some device dependent problems in the tests of the theme
rendering (when monitor resolution changes, so does font size (in
pixels)). This meant that the tests failed (as they are comparisons
with golden-bitmaps). Have updated the tests to do a more "approximate
comparison", with a low tolerance.  This is slow currently, could do
with optimising.

bzr-revno: 411
This commit is contained in:
Martin Thompson 2009-03-12 20:19:24 +00:00
parent 1d9569236d
commit 90a91aa788
11 changed files with 143 additions and 107 deletions

View File

@ -36,6 +36,7 @@ class OpenLPToolbar(QtGui.QToolBar):
""" """
A method to help developers easily add a button to the toolbar. A method to help developers easily add a button to the toolbar.
""" """
ButtonIcon = None
if type(icon) is QtGui.QIcon: if type(icon) is QtGui.QIcon:
ButtonIcon = icon ButtonIcon = icon
elif type(icon) is types.StringType: elif type(icon) is types.StringType:
@ -46,6 +47,7 @@ class OpenLPToolbar(QtGui.QToolBar):
else: else:
ButtonIcon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(icon)), ButtonIcon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(icon)),
QtGui.QIcon.Normal, QtGui.QIcon.Off) QtGui.QIcon.Normal, QtGui.QIcon.Off)
if ButtonIcon is not None:
ToolbarButton = self.addAction(ButtonIcon, title) ToolbarButton = self.addAction(ButtonIcon, title)
if tooltip is not None: if tooltip is not None:
ToolbarButton.setToolTip(tooltip) ToolbarButton.setToolTip(tooltip)

View File

@ -45,7 +45,7 @@ class PluginManager(object):
self.basepath = os.path.abspath(dir) self.basepath = os.path.abspath(dir)
log.debug("Base path %s ", self.basepath) log.debug("Base path %s ", self.basepath)
self.plugins = [] self.plugins = []
# this has to happen after the UI is sroted self.find_plugins(dir) # this has to happen after the UI is sorted self.find_plugins(dir)
log.info("Plugin manager done init") log.info("Plugin manager done init")
def find_plugins(self, dir, preview_controller, live_controller): # xxx shouldn't dir come from self.basepath def find_plugins(self, dir, preview_controller, live_controller): # xxx shouldn't dir come from self.basepath

View File

@ -375,14 +375,19 @@ class Renderer:
print "_get_extent_and_render", [line], tlcorner, dodraw print "_get_extent_and_render", [line], tlcorner, dodraw
p=QtGui.QPainter() p=QtGui.QPainter()
p.begin(self._paint) p.begin(self._paint)
# use this to scale for rendering in "operators view" xxx
# p.SetUserScale(0.5,0.5)
# 'twould be more efficient to set this once when theme changes # 'twould be more efficient to set this once when theme changes
# or p changes # or p changes
font=QtGui.QFont(self._theme.FontName, font=QtGui.QFont(self._theme.FontName,
self._theme.FontProportion, # size self._theme.FontProportion, # size
QtGui.QFont.Normal, # weight QtGui.QFont.Normal, # weight
0)# italic 0)# italic
# to make the unit tests monitor independent, we have to be able to
# specify whether a font proportion is in pixels or points
if self._theme.FontUnits.lower() == "pixels":
print "pixels"
font.setPixelSize(self._theme.FontProportion)
print self._theme.FontName, self._theme.FontProportion
print font.family(), font.pointSize()
p.setFont(font) p.setFont(font)
if color == None: if color == None:
p.setPen(self._theme.FontColor) p.setPen(self._theme.FontColor)

View File

@ -7,7 +7,8 @@
<BackgroundParameter3/> <BackgroundParameter3/>
<FontName>Tahoma</FontName> <FontName>Tahoma</FontName>
<FontColor>$00007F</FontColor> <FontColor>$00007F</FontColor>
<FontProportion>32</FontProportion> <FontProportion>53</FontProportion>
<FontUnits>pixels</FontUnits>
<Shadow>0</Shadow> <Shadow>0</Shadow>
<ShadowColor>$000000</ShadowColor> <ShadowColor>$000000</ShadowColor>
<Outline>0</Outline> <Outline>0</Outline>

View File

@ -19,16 +19,13 @@ import os, sys
mypath=os.path.split(os.path.abspath(__file__))[0] mypath=os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0,(os.path.join(mypath, '..' ,'..', '..'))) sys.path.insert(0,(os.path.join(mypath, '..' ,'..', '..')))
from openlp.plugins import MediaManagerItem from openlp.core.lib import MediaManagerItem
class TestMediaManager: class TestMediaManager:
def setup_class(self): def setup_class(self):
self.app = QtGui.QApplication([]) self.app = QtGui.QApplication([])
logging.info ("App is " + str(self.app)) logging.info ("App is " + str(self.app))
self.main_window = QtGui.QMainWindow() self.main_window = QtGui.QMainWindow()
self.main_window.resize(200, 600) self.main_window.resize(200, 600)
# self.StatusBar = QtGui.QStatusBar(self.main_window)
# self.StatusBar.setObjectName("StatusBar")
# self.main_window.setStatusBar(self.StatusBar)
self.MediaManagerDock = QtGui.QDockWidget(self.main_window) self.MediaManagerDock = QtGui.QDockWidget(self.main_window)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -39,34 +36,29 @@ class TestMediaManager:
icon.addPixmap(QtGui.QPixmap(":/system/system_mediamanager.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) icon.addPixmap(QtGui.QPixmap(":/system/system_mediamanager.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.MediaManagerDock.setWindowIcon(icon) self.MediaManagerDock.setWindowIcon(icon)
self.MediaManagerDock.setFloating(False) self.MediaManagerDock.setFloating(False)
# self.MediaManagerDock.setObjectName("MediaManagerDock")
self.MediaManagerContents = QtGui.QWidget() self.MediaManagerContents = QtGui.QWidget()
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.MediaManagerContents.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.MediaManagerContents.sizePolicy().hasHeightForWidth())
self.MediaManagerContents.setSizePolicy(sizePolicy) self.MediaManagerContents.setSizePolicy(sizePolicy)
# self.MediaManagerContents.setObjectName("MediaManagerContents")
self.MediaManagerLayout = QtGui.QHBoxLayout(self.MediaManagerContents) self.MediaManagerLayout = QtGui.QHBoxLayout(self.MediaManagerContents)
self.MediaManagerLayout.setContentsMargins(0, 2, 0, 0) self.MediaManagerLayout.setContentsMargins(0, 2, 0, 0)
# self.MediaManagerLayout.setObjectName("MediaManagerLayout")
self.MediaToolBox = QtGui.QToolBox(self.MediaManagerContents) self.MediaToolBox = QtGui.QToolBox(self.MediaManagerContents)
# self.MediaToolBox.setObjectName("MediaToolBox")
self.MediaManagerDock.setWidget(self.MediaManagerContents) self.MediaManagerDock.setWidget(self.MediaManagerContents)
self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock) self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock)
self.MediaManagerLayout.addWidget(self.MediaToolBox) self.MediaManagerLayout.addWidget(self.MediaToolBox)
def test1(self): def test1(self):
log=logging.getLogger("test1") log=logging.getLogger("test1")
log.info("Start") log.info("Start")
# i1=MediaManagerItem()
# i2=MediaManagerItem()
i1=MediaManagerItem(self.MediaToolBox) i1=MediaManagerItem(self.MediaToolBox)
i2=MediaManagerItem(self.MediaToolBox) i2=MediaManagerItem(self.MediaToolBox)
i2.choose_area.text="More Stuff"
log.info("i1"+str(i1)) log.info("i1"+str(i1))
log.info("i2"+str(i2)) log.info("i2"+str(i2))
self.MediaToolBox.addItem(i1, i1.icon, "Test1") i1.addToolbar()
self.MediaToolBox.addItem(i2, i2.icon, "Test2") i1.addToolbarButton("Test1", "Test1", None)
i2.addToolbar()
i2.addToolbarButton("Test2", "Test2", None)
self.MediaToolBox.setItemText(self.MediaToolBox.indexOf(i1), QtGui.QApplication.translate("main_window", "Item1", None, QtGui.QApplication.UnicodeUTF8)) self.MediaToolBox.setItemText(self.MediaToolBox.indexOf(i1), QtGui.QApplication.translate("main_window", "Item1", None, QtGui.QApplication.UnicodeUTF8))
self.MediaToolBox.setItemText(self.MediaToolBox.indexOf(i2), QtGui.QApplication.translate("main_window", "Item2", None, QtGui.QApplication.UnicodeUTF8)) self.MediaToolBox.setItemText(self.MediaToolBox.indexOf(i2), QtGui.QApplication.translate("main_window", "Item2", None, QtGui.QApplication.UnicodeUTF8))
log.info("Show window") log.info("Show window")

View File

@ -23,7 +23,9 @@ from openlp.core.pluginmanager import PluginManager
# test the plugin manager with some plugins in the test_plugins directory # test the plugin manager with some plugins in the test_plugins directory
class TestPluginManager: class TestPluginManager:
def test_init(self): def test_init(self):
p=PluginManager("./testplugins") self.p=PluginManager("./testplugins")
p=self.p
p.find_plugins('./testplugins', None, None)
assert (len(p.plugins)==2); assert (len(p.plugins)==2);
# get list of the names of the plugins # get list of the names of the plugins
names=[plugin.name for plugin in p.plugins] names=[plugin.name for plugin in p.plugins]
@ -37,6 +39,8 @@ class TestPluginManager:
assert p.plugins[1].name=="testplugin1" assert p.plugins[1].name=="testplugin1"
if __name__=="__main__": if __name__=="__main__":
log.debug("Starting") log.debug("Starting")
p=PluginManager("./testplugins") t=TestPluginManager()
for plugin in p.plugins: t.test_init()
log.debug("List of plugins found:")
for plugin in t.p.plugins:
log.debug("Plugin %s, name=%s (version=%d)"%(str(plugin), plugin.name, plugin.version)) log.debug("Plugin %s, name=%s (version=%d)"%(str(plugin), plugin.name, plugin.version))

View File

@ -213,6 +213,7 @@ if __name__=="__main__":
t=TestRender() t=TestRender()
t.setup_class() t.setup_class()
t.setup_method(None) t.setup_method(None)
t.test_easy()
t.test_splits() t.test_splits()
t.teardown_method(None) t.teardown_method(None)

View File

@ -21,10 +21,33 @@ import sys
import os import os
mypath=os.path.split(os.path.abspath(__file__))[0] mypath=os.path.split(os.path.abspath(__file__))[0]
sys.path.insert(0,(os.path.join(mypath, '..', '..','..'))) sys.path.insert(0,(os.path.join(mypath, '..', '..','..')))
from openlp.theme import Theme from openlp.core.theme import Theme
from openlp.core import Renderer from openlp.core import Renderer
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
def compare_images(goldenim, testim, threshold=0.01):
# easy test first
if goldenim == testim:
return 1
# how close are they? Calculated the sum of absolute differences in
# each channel of each pixel and divide by the number of pixels in the image
# if this sum is < threshold, the images are deemed to be "close enough"
sad=0;
for x in range(goldenim.width()):
for y in range(goldenim.height()):
p1=goldenim.pixel(x,y)
p2=testim.pixel(x,y)
sad += abs((p1&0xFF)-(p2&0xFF))
sad += abs((p1>>8&0xFF)-(p2>>8&0xFF))
sad += abs((p1>>16&0xFF)-(p2>>16&0xFF))
sad /= float(goldenim.width()*goldenim.height())
if (sad < threshold):
return 1
return 0
class TestRenderTheme(TestRender_base): class TestRenderTheme(TestRender_base):
# {{{ Basics # {{{ Basics
@ -34,7 +57,7 @@ class TestRenderTheme(TestRender_base):
TestRender_base.setup_method(self, method) TestRender_base.setup_method(self, method)
print "Theme setup", method print "Theme setup", method
# print "setup theme" # print "setup theme"
self.r.set_theme(Theme()) # set "blank" theme self.r.set_theme(Theme('blank_theme.xml')) # set "blank" theme
self.r.set_text_rectangle(QtCore.QRect(0,0, self.size.width(), self.size.height())) self.r.set_text_rectangle(QtCore.QRect(0,0, self.size.width(), self.size.height()))
words="""How sweet the name of Jesus sounds words="""How sweet the name of Jesus sounds
In a believer's ear! In a believer's ear!
@ -70,7 +93,7 @@ And drives away his fear.
else: else:
print "File", goldenfilename, "not found" print "File", goldenfilename, "not found"
return False return False
if (goldenim == im): if (compare_images(goldenim, im)):
print name, "Images match" print name, "Images match"
return True return True
else: else:
@ -80,6 +103,7 @@ And drives away his fear.
def test_theme_basic(self): def test_theme_basic(self):
self.answer=self.r.render_screen(0) self.answer=self.r.render_screen(0)
self.bmpname=whoami() self.bmpname=whoami()
print self.r._theme.FontProportion
print self.answer, self.expected_answer, self.answer==self.expected_answer print self.answer, self.expected_answer, self.answer==self.expected_answer
# self.msg=self.bmpname # self.msg=self.bmpname
@ -105,14 +129,12 @@ And drives away his fear.
# }}} # }}}
# {{{ backgrounds # {{{ backgrounds
def test_bg_stretch_y(self): def test_bg_stretch_y(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 2 t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join('data_for_tests', "snowsmall.jpg"); t.BackgroundParameter1 = os.path.join('data_for_tests', "snowsmall.jpg");
t.BackgroundParameter2 = QtGui.QColor(0,0,64); t.BackgroundParameter2 = QtGui.QColor(0,0,64);
t.BackgroundParameter3 = 0 t.BackgroundParameter3 = 0
t.Name="stretch y" t.Name="stretch y"
print t
print "set theme"
self.r.set_theme(t) self.r.set_theme(t)
print "render" print "render"
self.answer=self.r.render_screen(0) self.answer=self.r.render_screen(0)
@ -120,7 +142,7 @@ And drives away his fear.
self.bmpname=whoami() self.bmpname=whoami()
print "fone" print "fone"
def test_bg_shrink_y(self): def test_bg_shrink_y(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 2 t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join('data_for_tests', "snowbig.jpg"); t.BackgroundParameter1 = os.path.join('data_for_tests', "snowbig.jpg");
t.BackgroundParameter2 = QtGui.QColor(0,0,64); t.BackgroundParameter2 = QtGui.QColor(0,0,64);
@ -131,7 +153,7 @@ And drives away his fear.
self.bmpname=whoami() self.bmpname=whoami()
def test_bg_stretch_x(self): def test_bg_stretch_x(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 2 t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join('data_for_tests', "treessmall.jpg"); t.BackgroundParameter1 = os.path.join('data_for_tests', "treessmall.jpg");
t.BackgroundParameter2 = QtGui.QColor(0,0,64); t.BackgroundParameter2 = QtGui.QColor(0,0,64);
@ -144,7 +166,7 @@ And drives away his fear.
self.bmpname=whoami() self.bmpname=whoami()
def test_bg_shrink_x(self): def test_bg_shrink_x(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 2 t.BackgroundType = 2
t.BackgroundParameter1 = os.path.join('data_for_tests', "treesbig.jpg"); t.BackgroundParameter1 = os.path.join('data_for_tests', "treesbig.jpg");
t.BackgroundParameter2 = QtGui.QColor(0,0,64); t.BackgroundParameter2 = QtGui.QColor(0,0,64);
@ -158,7 +180,7 @@ And drives away his fear.
# }}} # }}}
# {{{ Vertical alignment # {{{ Vertical alignment
def test_theme_vertical_align_top(self): def test_theme_vertical_align_top(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 0 t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64); t.BackgroundParameter1 = QtGui.QColor(0,0,64);
t.VerticalAlign = 0 t.VerticalAlign = 0
@ -168,7 +190,7 @@ And drives away his fear.
self.bmpname=whoami() self.bmpname=whoami()
def test_theme_vertical_align_bot(self): def test_theme_vertical_align_bot(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 0 t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64); t.BackgroundParameter1 = QtGui.QColor(0,0,64);
t.VerticalAlign = 1 t.VerticalAlign = 1
@ -179,7 +201,7 @@ And drives away his fear.
self.bmpname=whoami() self.bmpname=whoami()
def test_theme_vertical_align_cen(self): def test_theme_vertical_align_cen(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 0 t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64); t.BackgroundParameter1 = QtGui.QColor(0,0,64);
t.VerticalAlign = 2 t.VerticalAlign = 2
@ -191,7 +213,7 @@ And drives away his fear.
# }}} # }}}
# {{{ Horzontal alignment # {{{ Horzontal alignment
def test_theme_horizontal_align_left(self): def test_theme_horizontal_align_left(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 0 t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64); t.BackgroundParameter1 = QtGui.QColor(0,0,64);
t.VerticalAlign = 0 t.VerticalAlign = 0
@ -202,7 +224,7 @@ And drives away his fear.
self.bmpname=whoami() self.bmpname=whoami()
def test_theme_horizontal_align_right(self): def test_theme_horizontal_align_right(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 0 t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64); t.BackgroundParameter1 = QtGui.QColor(0,0,64);
t.VerticalAlign = 0 t.VerticalAlign = 0
@ -214,7 +236,7 @@ And drives away his fear.
self.bmpname=whoami() self.bmpname=whoami()
def test_theme_horizontal_align_centre(self): def test_theme_horizontal_align_centre(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 0 t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64); t.BackgroundParameter1 = QtGui.QColor(0,0,64);
t.VerticalAlign = 0 t.VerticalAlign = 0
@ -226,7 +248,7 @@ And drives away his fear.
self.bmpname=whoami() self.bmpname=whoami()
def test_theme_horizontal_align_left_lyric(self): def test_theme_horizontal_align_left_lyric(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 0 t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64); t.BackgroundParameter1 = QtGui.QColor(0,0,64);
t.VerticalAlign = 0 t.VerticalAlign = 0
@ -241,7 +263,8 @@ And drives away his fear.
# }}} # }}}
# {{{ Shadows and outlines # {{{ Shadows and outlines
def test_theme_shadow_outline(self): def test_theme_shadow_outline(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 0 t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,0); t.BackgroundParameter1 = QtGui.QColor(0,0,0);
t.Name="shadow/outline" t.Name="shadow/outline"
@ -259,7 +282,7 @@ And drives away his fear.
self.bmpname=whoami() self.bmpname=whoami()
# }}} # }}}
def test_theme_font(self): def test_theme_font(self):
t=Theme() t=Theme('blank_theme.xml')
t.BackgroundType = 0 t.BackgroundType = 0
t.BackgroundParameter1 = QtGui.QColor(0,0,64); t.BackgroundParameter1 = QtGui.QColor(0,0,64);
t.Name="font" t.Name="font"
@ -274,5 +297,5 @@ if __name__=="__main__":
t=TestRenderTheme() t=TestRenderTheme()
t.setup_class() t.setup_class()
t.setup_method(None) t.setup_method(None)
t.test_theme_font() t.test_bg_stretch_y()
t.teardown_method(None) t.teardown_method(None)

View File

@ -1,21 +1,3 @@
"""
OpenLP - Open Source Lyrics Projection
Copyright (c) 2008 Raoul Snyman
Portions copyright (c) 2008 Martin Thompson, Tim Bentley
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
"""
import os import os
import sys import sys
mypath=os.path.split(os.path.abspath(__file__))[0] mypath=os.path.split(os.path.abspath(__file__))[0]
@ -38,6 +20,7 @@ def test_read_theme():
assert(t.FontColor == QtGui.QColor(255,255,255)) assert(t.FontColor == QtGui.QColor(255,255,255))
assert(t.FontName == "Tahoma") assert(t.FontName == "Tahoma")
assert(t.FontProportion == 16) assert(t.FontProportion == 16)
assert(t.FontUnits == "pixels")
assert(t.HorizontalAlign == 2) assert(t.HorizontalAlign == 2)
assert(t.Name == "openlp.org Packaged Theme") assert(t.Name == "openlp.org Packaged Theme")
assert(t.Outline == -1) assert(t.Outline == -1)
@ -45,6 +28,7 @@ def test_read_theme():
assert(t.Shadow == -1) assert(t.Shadow == -1)
assert(t.ShadowColor == QtGui.QColor(0,0,1)) assert(t.ShadowColor == QtGui.QColor(0,0,1))
assert(t.VerticalAlign == 0) assert(t.VerticalAlign == 0)
def test_theme():
# test we create a "blank" theme correctly # test we create a "blank" theme correctly
t=Theme() t=Theme()
print t print t
@ -56,6 +40,7 @@ def test_read_theme():
assert(t.FontName == "Arial") assert(t.FontName == "Arial")
assert(t.FontProportion == 30) assert(t.FontProportion == 30)
assert(t.HorizontalAlign == 0) assert(t.HorizontalAlign == 0)
assert(t.FontUnits == "pixels")
assert(t.Name == "BlankStyle") assert(t.Name == "BlankStyle")
assert(t.Outline == 0) assert(t.Outline == 0)
assert(t.Shadow == 0) assert(t.Shadow == 0)
@ -64,8 +49,7 @@ def test_read_theme():
print "Tests passed" print "Tests passed"
def test_theme():
test_read_theme()
if __name__=="__main__": if __name__=="__main__":
test_read_theme() test_read_theme()
test_theme()

View File

@ -8,6 +8,7 @@
<FontName>Tahoma</FontName> <FontName>Tahoma</FontName>
<FontColor>clWhite</FontColor> <FontColor>clWhite</FontColor>
<FontProportion>16</FontProportion> <FontProportion>16</FontProportion>
<FontUnits>pixels</FontUnits>
<Shadow>-1</Shadow> <Shadow>-1</Shadow>
<ShadowColor>$00000001</ShadowColor> <ShadowColor>$00000001</ShadowColor>
<Outline>-1</Outline> <Outline>-1</Outline>

View File

@ -1,30 +1,15 @@
# -*- coding: utf-8 -*- import platform
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 ver = platform.python_version()
""" if ver >= '2.5':
OpenLP - Open Source Lyrics Projection from xml.etree.ElementTree import ElementTree, XML
Copyright (c) 2008 Raoul Snyman else:
Portions copyright (c) 2008 Martin Thompson, Tim Bentley from elementtree import ElementTree, XML
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
"""
import sys
import os
from PyQt4 import QtGui from PyQt4 import QtGui
sys.path.append(os.path.abspath("./../.."))
from openlp.core.lib import XmlRootClass DelphiColors={"clRed":0xFF0000,
"clBlack":0x000000,
"clWhite":0xFFFFFF}
blankstylexml=\ blankstylexml=\
'''<?xml version="1.0" encoding="iso-8859-1"?> '''<?xml version="1.0" encoding="iso-8859-1"?>
@ -37,6 +22,7 @@ blankstylexml=\
<FontName>Arial</FontName> <FontName>Arial</FontName>
<FontColor>clWhite</FontColor> <FontColor>clWhite</FontColor>
<FontProportion>30</FontProportion> <FontProportion>30</FontProportion>
<FontUnits>pixels</FontUnits>
<Shadow>0</Shadow> <Shadow>0</Shadow>
<Outline>0</Outline> <Outline>0</Outline>
<HorizontalAlign>0</HorizontalAlign> <HorizontalAlign>0</HorizontalAlign>
@ -45,11 +31,7 @@ blankstylexml=\
</Theme> </Theme>
''' '''
DelphiColors={"clRed":0xFF0000, class Theme:
"clBlack":0x000000,
"clWhite":0xFFFFFF}
class Theme(XmlRootClass):
def __init__(self, xmlfile=None): def __init__(self, xmlfile=None):
""" stores the info about a theme """ stores the info about a theme
attributes: attributes:
@ -70,7 +52,8 @@ class Theme(XmlRootClass):
FontName : name of font to use FontName : name of font to use
FontColor : color for main font FontColor : color for main font
FontProportion : point size of font FontProportion : size of font
FontUnits : whether size of font is in <pixels> or <points>
Shadow : 0 - no shadow, non-zero use shadow Shadow : 0 - no shadow, non-zero use shadow
ShadowColor : color for drop shadow ShadowColor : color for drop shadow
@ -87,19 +70,59 @@ class Theme(XmlRootClass):
1 - lyrics 1 - lyrics
""" """
# init to defaults # init to defaults
self._setFromXml(blankstylexml, 'Theme') self._set_from_XML(blankstylexml)
if xmlfile != None: if xmlfile != None:
# init from xmlfile # init from xmlfile
file=open(xmlfile) file=open(xmlfile)
t=''.join(file.readlines()) # read the file and change list to a string t=''.join(file.readlines()) # read the file and change list to a string
self._setFromXml(t, 'Theme') self._set_from_XML(t)
def post_tag_hook(self, tag, val): def _get_as_string(self):
if DelphiColors.has_key(val): s=""
val=DelphiColors[val] keys=dir(self)
if (tag.find("Color") > 0 or keys.sort()
(tag.find("BackgroundParameter") == 0 and type(val) == type(0))): for k in keys:
# convert to a QtGui.Color if k[0:1] != "_":
s+= "_%s_" %(getattr(self,k))
return s
def _set_from_XML(self, xml):
root=ElementTree(element=XML(xml))
iter=root.getiterator()
for element in iter:
if element.tag != "Theme":
t=element.text
# print element.tag, t, type(t)
if type(t) == type(None): # easy!
val=t
if type(t) == type(" "): # strings need special handling to sort the colours out
# print "str",
if t[0] == "$": # might be a hex number
# print "hex",
try:
val=int(t[1:], 16)
except ValueError: # nope
# print "nope",
pass
elif DelphiColors.has_key(t):
# print "colour",
val=DelphiColors[t]
else:
try:
val=int(t)
except ValueError:
val=t
if (element.tag.find("Color") > 0 or
(element.tag.find("BackgroundParameter") == 0 and type(val) == type(0))):
# convert to a wx.Colour
val= QtGui.QColor((val>>16) & 0xFF, (val>>8)&0xFF, val&0xFF) val= QtGui.QColor((val>>16) & 0xFF, (val>>8)&0xFF, val&0xFF)
# print [val]
setattr(self,element.tag, val)
def __str__(self):
s=""
for k in dir(self):
if k[0:1] != "_":
s+= "%30s : %s\n" %(k,getattr(self,k))
return s
return (tag, val)