← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~meths/openlp/trivialfixes into lp:openlp

 

Jon Tibble has proposed merging lp:~meths/openlp/trivialfixes into lp:openlp.

Requested reviews:
    openlp.org Core (openlp-core)

All code run and testcompiled

Cleanup
- Fix the incorrect backslash code continuation after open bracket - no backslash required
- Finishes whitespace fixes involving ==

Fix
- Turned out the theme loading is a bit of a mess with themes loaded in multiple places - this fixes all places for previously introduced formatted XML theme files.  Does amendthemeform.py need refactoring to use thememanager.py to load the theme so only one piece of code loads theme files from disk?

New feature
- Introduces the ability to save the UI so users can set it how they wish and have those wishes respected across sessions.  Currently only saves the items displayed.  Future work should include item positions.
-- 
https://code.launchpad.net/~meths/openlp/trivialfixes/+merge/11282
Your team openlp.org Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py	2009-09-03 17:46:46 +0000
+++ openlp/core/lib/renderer.py	2009-09-06 13:57:32 +0000
@@ -310,7 +310,7 @@
                 rectPath.lineTo(max_x, 0)
                 rectPath.closeSubpath()
                 painter.drawPath(rectPath)
-            elif self._theme.background_type== u'image':
+            elif self._theme.background_type == u'image':
                 # image
                 painter.fillRect(self._frame.rect(), QtCore.Qt.black)
                 if self.bg_image is not None:

=== modified file 'openlp/core/test/test_plugin_manager.py'
--- openlp/core/test/test_plugin_manager.py	2009-09-03 15:19:30 +0000
+++ openlp/core/test/test_plugin_manager.py	2009-09-06 13:57:32 +0000
@@ -24,23 +24,24 @@
 # test the plugin manager with some plugins in the test_plugins directory
 class TestPluginManager:
     def test_init(self):
-        self.p=PluginManager(u'./testplugins')
-        p=self.p
+        self.p = PluginManager(u'./testplugins')
+        p = self.p
         p.find_plugins(u'./testplugins', None, None)
-        assert (len(p.plugins)==2);
+        assert(len(p.plugins) == 2)
         # get list of the names of the plugins
-        names=[plugin.name for plugin in p.plugins]
+        names = [plugin.name for plugin in p.plugins]
         # see which ones we've got
-        assert (u'testplugin1' in names)
-        assert (u'testplugin2' in names)
+        assert(u'testplugin1' in names)
+        assert(u'testplugin2' in names)
         # and not got - it's too deep in the hierarchy!
-        assert (u'testplugin3' not in names)
+        assert(u'testplugin3' not in names)
         # test that the weighting is done right
-        assert p.plugins[0].name == "testplugin2"
-        assert p.plugins[1].name == "testplugin1"
+        assert(p.plugins[0].name == "testplugin2")
+        assert(p.plugins[1].name == "testplugin1")
+
 if __name__ == "__main__":
     log.debug(u'Starting')
-    t=TestPluginManager()
+    t = TestPluginManager()
     t.test_init()
     log.debug(u'List of plugins found:')
     for plugin in t.p.plugins:

=== modified file 'openlp/core/test/test_render.py'
--- openlp/core/test/test_render.py	2009-09-03 15:19:30 +0000
+++ openlp/core/test/test_render.py	2009-09-06 15:26:02 +0000
@@ -21,10 +21,12 @@
 import os, os.path
 from PyQt4 import QtGui, QtCore
 
-mypath=os.path.split(os.path.abspath(__file__))[0]
-sys.path.insert(0,(os.path.join(mypath, '..', '..','..')))
 from openlp.core.theme import Theme
 from openlp.core import Renderer
+
+mypath = os.path.split(os.path.abspath(__file__))[0]
+sys.path.insert(0, (os.path.join(mypath, '..', '..', '..')))
+
 # from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66062
 def whoami(depth=1):
     return sys._getframe(depth).f_code.co_name
@@ -34,8 +36,8 @@
 
     def __init__(self, size):
         """Create the DemoPanel."""
-        self.width=size.width();
-        self.height=size.height();
+        self.width = size.width();
+        self.height = size.height();
         # create something to be painted into
         self._Buffer = QtGui.QPixmap(self.width, self.height)
     def GetPixmap(self):
@@ -47,10 +49,10 @@
     def __init__(self):
         if not os.path.exists(u'test_results'):
             os.mkdir(u'test_results')
-        self.app=None
+        self.app = None
     def write_to_file(self, pixmap, name):
         im=pixmap.toImage()
-        testpathname=os.path.join(u'test_results', name+'.bmp')
+        testpathname = os.path.join(u'test_results', name+'.bmp')
         if os.path.exists(testpathname):
             os.unlink(testpathname)
         im.save(testpathname, 'bmp')
@@ -85,7 +87,7 @@
     def setup_method(self, method):
         print "SSsetup", method
         if not hasattr(self, 'app'):
-            self.app=None
+            self.app = None
         try: # see if we already have an app for some reason.
             # have to try and so something, cant just test against None
             print "app", self.app, ";;;"
@@ -98,14 +100,14 @@
 #             print "App", self.app
 #         self.app = QtGui.QApplication([])
         print "Application created and sorted"
-        self.size=QtCore.QSize(800,600)
-        frame=TstFrame(size=self.size)
-        self.frame=frame
-        self.paintdest=frame.GetPixmap()
+        self.size = QtCore.QSize(800,600)
+        frame = TstFrame(size = self.size)
+        self.frame = frame
+        self.paintdest = frame.GetPixmap()
         self.r=Renderer()
         self.r.set_paint_dest(self.paintdest)
-        self.expected_answer="Don't know yet"
-        self.answer=None
+        self.expected_answer = "Don't know yet"
+        self.answer = None
         print "--------------- Setup Done -------------"
 
     def teardown_method(self, method):
@@ -118,34 +120,34 @@
     def setup_method(self, method):
         TestRender_base.setup_method(self, method)
         self.r.set_debug(1)
-        themefile=os.path.abspath(u'data_for_tests/render_theme.xml')
+        themefile = os.path.abspath(u'data_for_tests/render_theme.xml')
         self.r.set_theme(Theme(themefile)) # set default theme
         self.r._render_background()
         self.r.set_text_rectangle(QtCore.QRect(0,0, self.size.width()-1,
 	    self.size.height()-1))
-        self.msg=None
+        self.msg = None
 
     def test_easy(self):
-        answer=self.r._render_single_line(u'Test line', tlcorner=(0,100))
-        assert (answer==(219,163))
+        answer = self.r._render_single_line(u'Test line', tlcorner = (0,100))
+        assert(answer == (219,163))
     def test_longer(self):
-        answer=self.r._render_single_line(
+        answer = self.r._render_single_line(
 	    u'Test line with more words than fit on one line',
-	    tlcorner=(10,10))
-        assert (answer==(753,136))
+	    tlcorner = (10,10))
+        assert(answer == (753,136))
     def test_even_longer(self):
-        answer=self.r._render_single_line(
+        answer = self.r._render_single_line(
 	    u'Test line with more words than fit on either one or two lines',
-            tlcorner=(10,10))
-        assert(answer==(753,199))
+            tlcorner = (10,10))
+        assert(answer == (753,199))
     def test_lines(self):
-        lines=[]
+        lines = []
         lines.append(u'Line One')
         lines.append(u'Line Two')
         lines.append(u'Line Three and should be long enough to wrap')
         lines.append(u'Line Four and should be long enough to wrap also')
-        answer=self.r._render_lines(lines)
-        assert(answer==QtCore.QRect(0,0,741,378))
+        answer = self.r._render_lines(lines)
+        assert(answer == QtCore.QRect(0,0,741,378))
 
     def test_set_words_openlp(self):
         words="""
@@ -158,9 +160,9 @@
 Verse 3: Line 1
 Line 2
 Line 3"""
-        expected_answer=["Verse 1: Line 1\nLine 2","Verse 2: Line 1\nLine 2","Verse 3: Line 1\nLine 2\nLine 3"]
-        answer=self.r.set_words_openlp(words)
-        assert (answer==expected_answer)
+        expected_answer = ["Verse 1: Line 1\nLine 2","Verse 2: Line 1\nLine 2","Verse 3: Line 1\nLine 2\nLine 3"]
+        answer = self.r.set_words_openlp(words)
+        assert(answer == expected_answer)
 
     def test_render_screens(self):
         words="""
@@ -173,15 +175,16 @@
 Verse 3: Line 1
 Line 2
 Line 3"""
-        verses=self.r.set_words_openlp(words)
-        expected_answer=["Verse 1: Line 1\nLine 2","Verse 2: Line 1\nLine 2","Verse 3: Line 1\nLine 2\nLine 3"]
-        assert (verses==expected_answer)
+        verses = self.r.set_words_openlp(words)
+        expected_answer = ["Verse 1: Line 1\nLine 2","Verse 2: Line 1\nLine 2","Verse 3: Line 1\nLine 2\nLine 3"]
+        assert(verses == expected_answer)
 
-        expected_answer=[QtCore.QRect(0,0,397,126), QtCore.QRect(0,0,397,126), QtCore.QRect(0,0,397,189)]
+        expected_answer = [QtCore.QRect(0,0,397,126), QtCore.QRect(0,0,397,126),
+            QtCore.QRect(0,0,397,189)]
         for v in range(len(verses)):
             answer=self.r.render_screen(v)
 #             print v, answer.x(), answer.y(), answer.width(), answer.height()
-            assert(answer==expected_answer[v])
+            assert(answer == expected_answer[v])
 
     def split_test(self, number, answer, expected_answers):
         lines=[]
@@ -189,34 +192,37 @@
         for i in range(number):
             extra=""
             if i == 51: # make an extra long line on line 51 to test wrapping
-                extra="Some more words to make it wrap around don't you know until it wraps so many times we don't know what to do"
+                extra = "Some more words to make it wrap around don't you know until it wraps so many times we don't know what to do"
             lines.append(u'Line %d %s' % (i, extra))
-        result=self.r.split_set_of_lines(lines)
+        result = self.r.split_set_of_lines(lines)
         print "results---------------__", result
         for i in range(len(result)):
             self.setup_method(None)
-            answer=self.r._render_lines(result[i])
+            answer = self.r._render_lines(result[i])
             print answer
             self.write_to_file(self.frame.GetPixmap(), "split_test_%03d"% i)
-            print number, i, answer.x(), answer.y(), answer.width(), answer.height()
-
-            e=expected_answers[i]
-            assert(answer==QtCore.QRect(e[0],e[1],e[2],e[3]))
+            print number, i, answer.x(), answer.y(), answer.width(), \
+                answer.height()
+            e = expected_answers[i]
+            assert(answer == QtCore.QRect(e[0],e[1],e[2],e[3]))
 
 
     def test_splits(self):
         print "Test splits"
-        self.split_test(100, 11, [(0,0,180,567), (0,0,214,567), (0,0,214,567), (0,0,214,567), (0,0,214,567), (0,0,214,378), (0,0,759,567),
-                                  (0,0,214,567), (0,0,214,567), (0,0,214,567), (0,0,214,567), (0,0,214,567), (0,0,214,567)])
-        self.split_test(30, 4, [ (0,0,180,441), (0,0,214,441), (0,0,214,441), (0,0,214,441)])
+        self.split_test(100, 11, [(0,0,180,567), (0,0,214,567), (0,0,214,567),
+            (0,0,214,567), (0,0,214,567), (0,0,214,378), (0,0,759,567),
+            (0,0,214,567), (0,0,214,567), (0,0,214,567), (0,0,214,567),
+            (0,0,214,567), (0,0,214,567)])
+        self.split_test(30, 4, [ (0,0,180,441), (0,0,214,441), (0,0,214,441),
+            (0,0,214,441)])
         self.split_test(20, 3, [(0,0,180,378), (0,0,214,378), (0,0,214,378)])
         self.split_test(12, 2, [(0,0,180,378), (0,0,214,378)])
         self.split_test(4, 1, [(0,0,180,252)])
         self.split_test(6, 1, [(0,0,180,378)])
         self.split_test(8, 1, [(0,0,180,504)])
-if __name__=="__main__":
 
-    t=TestRender()
+if __name__ == "__main__":
+    t = TestRender()
     t.setup_class()
     t.setup_method(None)
     t.test_easy()

=== modified file 'openlp/core/test/test_render_theme.py'
--- openlp/core/test/test_render_theme.py	2009-09-03 15:19:30 +0000
+++ openlp/core/test/test_render_theme.py	2009-09-06 15:26:02 +0000
@@ -15,16 +15,17 @@
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
-
-from test_render import TestRender_base, whoami
 import sys
 import os
-mypath=os.path.split(os.path.abspath(__file__))[0]
-sys.path.insert(0,(os.path.join(mypath, '..', '..','..')))
+
+from PyQt4 import QtGui, QtCore
+
 from openlp.core.theme import Theme
 from openlp.core import Renderer
+from test_render import TestRender_base, whoami
 
-from PyQt4 import QtGui, QtCore
+pypath = os.path.split(os.path.abspath(__file__))[0]
+sys.path.insert(0, (os.path.join(mypath, '..', '..', '..')))
 
 def compare_images(goldenim, testim, threshold=0.01):
     # easy test first
@@ -53,22 +54,24 @@
 
     def __init__(self):
         TestRender_base.__init__(self)
+
     def setup_method(self, method):
         TestRender_base.setup_method(self, method)
         print "Theme setup", method
 #         print "setup theme"
         self.r.set_theme(Theme(u'blank_theme.xml')) # set "blank" theme
-        self.r.set_text_rectangle(QtCore.QRect(0,0, self.size.width(), self.size.height()))
-        words="""How sweet the name of Jesus sounds
+        self.r.set_text_rectangle(QtCore.QRect(0,0, self.size.width(),
+            self.size.height()))
+        words = """How sweet the name of Jesus sounds
 In a believer's ear!
 It soothes his sorrows, heals his wounds,
 And drives away his fear.
 """
-        verses=self.r.set_words_openlp(words)
+        verses = self.r.set_words_openlp(words)
 #         usually the same
-        self.expected_answer= QtCore.QRect(0, 0, 559, 342)
-        self.msg=None
-        self.bmpname="Not set a bitmap yet"
+        self.expected_answer = QtCore.QRect(0, 0, 559, 342)
+        self.msg = None
+        self.bmpname = "Not set a bitmap yet"
         print "------------- setup done --------------"
 
     def teardown_method(self, method):
@@ -76,20 +79,21 @@
         if self.bmpname != None:
             assert (self.compare_DC_to_file(self.bmpname))
         if self.expected_answer != None: # result=None => No result to check
-            assert self.expected_answer==self.answer
+            assert self.expected_answer == self.answer
         print "============ teardown done ========="
+
     def compare_DC_to_file(self, name):
-        """writes DC out to a bitmap file and then compares it with a golden one
-        returns True if OK, False if not (so you can assert on it)
+        """writes DC out to a bitmap file and then compares it with a golden
+        one returns True if OK, False if not (so you can assert on it)
 
         """
         print "--- compare DC to file --- ", name
-        p=self.frame.GetPixmap()
-        im=self.write_to_file(p, name)
+        p = self.frame.GetPixmap()
+        im = self.write_to_file(p, name)
         print "Compare"
         goldenfilename=os.path.join(u'golden_bitmaps",name+".bmp')
         if os.path.exists(goldenfilename):
-            goldenim=QtGui.QImage(goldenfilename)
+            goldenim = QtGui.QImage(goldenfilename)
         else:
             print "File", goldenfilename, "not found"
             return False
@@ -101,201 +105,210 @@
             return False
 
     def test_theme_basic(self):
-        self.answer=self.r.render_screen(0)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        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
 
     # }}}
+
     # {{{ Gradients
     def test_gradient_h(self):
         # normally we wouldn't hack with these directly!
         self.r._theme.BackgroundType = 1
-        self.r._theme.BackgroundParameter1 = QtGui.QColor(255,0,0);
-        self.r._theme.BackgroundParameter2 = QtGui.QColor(255,255,0);
+        self.r._theme.BackgroundParameter1 = QtGui.QColor(255,0,0)
+        self.r._theme.BackgroundParameter2 = QtGui.QColor(255,255,0)
         self.r._theme.BackgroundParameter3 = 1
-        self.answer=self.r.render_screen(0)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.bmpname = whoami()
 
     def test_gradient_v(self):
         # normally we wouldn't hack with these directly!
         self.r._theme.BackgroundType = 1
-        self.r._theme.BackgroundParameter1 = QtGui.QColor(255,0,0);
-        self.r._theme.BackgroundParameter2 = QtGui.QColor(255,255,0);
+        self.r._theme.BackgroundParameter1 = QtGui.QColor(255,0,0)
+        self.r._theme.BackgroundParameter2 = QtGui.QColor(255,255,0)
         self.r._theme.BackgroundParameter3 = 0
-        self.answer=self.r.render_screen(0)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.bmpname = whoami()
     # }}}
+
     # {{{ backgrounds
     def test_bg_stretch_y(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 2
-        t.BackgroundParameter1 = os.path.join(u'data_for_tests', 'snowsmall.jpg');
-        t.BackgroundParameter2 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = os.path.join(u'data_for_tests',
+            'snowsmall.jpg')
+        t.BackgroundParameter2 = QtGui.QColor(0,0,64)
         t.BackgroundParameter3 = 0
-        t.Name="stretch y"
+        t.Name = "stretch y"
         self.r.set_theme(t)
         print "render"
-        self.answer=self.r.render_screen(0)
+        self.answer = self.r.render_screen(0)
         print "whoami"
-        self.bmpname=whoami()
+        self.bmpname = whoami()
         print "fone"
+
     def test_bg_shrink_y(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 2
-        t.BackgroundParameter1 = os.path.join(u'data_for_tests', 'snowbig.jpg');
-        t.BackgroundParameter2 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = os.path.join(u'data_for_tests', 'snowbig.jpg')
+        t.BackgroundParameter2 = QtGui.QColor(0,0,64)
         t.BackgroundParameter3 = 0
-        t.Name="shrink y"
+        t.Name = "shrink y"
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.bmpname = whoami()
 
     def test_bg_stretch_x(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 2
         t.BackgroundParameter1 = os.path.join(u'data_for_tests',
-	    'treessmall.jpg');
-        t.BackgroundParameter2 = QtGui.QColor(0,0,64);
+	        'treessmall.jpg')
+        t.BackgroundParameter2 = QtGui.QColor(0,0,64)
         t.BackgroundParameter3 = 0
         t.VerticalAlign = 2
-        t.Name="stretch x"
+        t.Name = "stretch x"
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        self.expected_answer= QtCore.QRect(0, 129, 559, 342)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.expected_answer = QtCore.QRect(0, 129, 559, 342)
+        self.bmpname = whoami()
 
     def test_bg_shrink_x(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 2
-        t.BackgroundParameter1 = os.path.join(u'data_for_tests', 'treesbig.jpg');
-        t.BackgroundParameter2 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = os.path.join(u'data_for_tests',
+            'treesbig.jpg')
+        t.BackgroundParameter2 = QtGui.QColor(0,0,64)
         t.BackgroundParameter3 = 0
         t.VerticalAlign = 2
-        t.Name="shrink x"
+        t.Name = "shrink x"
         self.r.set_theme(t)
-        self.expected_answer= QtCore.QRect(0, 129, 559, 342)
-        self.answer=self.r.render_screen(0)
-        self.bmpname=whoami()
+        self.expected_answer = QtCore.QRect(0, 129, 559, 342)
+        self.answer = self.r.render_screen(0)
+        self.bmpname = whoami()
     # }}}
+
     # {{{ Vertical alignment
     def test_theme_vertical_align_top(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 0
-        t.BackgroundParameter1 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = QtGui.QColor(0,0,64)
         t.VerticalAlign = 0
-        t.Name="valign top"
+        t.Name = "valign top"
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.bmpname = whoami()
 
     def test_theme_vertical_align_bot(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 0
-        t.BackgroundParameter1 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = QtGui.QColor(0,0,64)
         t.VerticalAlign = 1
-        t.Name="valign bot"
+        t.Name = "valign bot"
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        self.expected_answer= QtCore.QRect(0, 257, 559, 342)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.expected_answer = QtCore.QRect(0, 257, 559, 342)
+        self.bmpname = whoami()
 
     def test_theme_vertical_align_cen(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 0
-        t.BackgroundParameter1 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = QtGui.QColor(0,0,64)
         t.VerticalAlign = 2
-        t.Name="valign cen"
+        t.Name = "valign cen"
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        self.expected_answer= QtCore.QRect(0, 129, 559, 342)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.expected_answer = QtCore.QRect(0, 129, 559, 342)
+        self.bmpname = whoami()
     # }}}
+
     # {{{ Horzontal alignment
     def test_theme_horizontal_align_left(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 0
-        t.BackgroundParameter1 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = QtGui.QColor(0,0,64)
         t.VerticalAlign = 0
         t.HorizontalAlign = 0
-        t.Name="halign left"
+        t.Name = "halign left"
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.bmpname = whoami()
 
     def test_theme_horizontal_align_right(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 0
-        t.BackgroundParameter1 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = QtGui.QColor(0,0,64)
         t.VerticalAlign = 0
         t.HorizontalAlign = 1
-        t.Name="halign right"
+        t.Name = "halign right"
         self.r.set_theme(t)
-        self.expected_answer= QtCore.QRect(0, 0, 800, 342)
-        self.answer=self.r.render_screen(0)
-        self.bmpname=whoami()
+        self.expected_answer = QtCore.QRect(0, 0, 800, 342)
+        self.answer = self.r.render_screen(0)
+        self.bmpname = whoami()
 
     def test_theme_horizontal_align_centre(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 0
-        t.BackgroundParameter1 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = QtGui.QColor(0,0,64)
         t.VerticalAlign = 0
         t.HorizontalAlign = 2
-        t.Name="halign centre"
+        t.Name = "halign centre"
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        self.expected_answer= QtCore.QRect(0, 0, 679, 342)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.expected_answer = QtCore.QRect(0, 0, 679, 342)
+        self.bmpname = whoami()
 
     def test_theme_horizontal_align_left_lyric(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 0
-        t.BackgroundParameter1 = QtGui.QColor(0,0,64);
+        t.BackgroundParameter1 = QtGui.QColor(0,0,64)
         t.VerticalAlign = 0
         t.HorizontalAlign = 0
-        t.WrapStyle=1
-        t.Name="halign left lyric"
+        t.WrapStyle = 1
+        t.Name = "halign left lyric"
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        self.expected_answer=QtCore.QRect(0, 0, 778, 342)
-        self.bmpname=whoami()
+        self.answer = self.r.render_screen(0)
+        self.expected_answer = QtCore.QRect(0, 0, 778, 342)
+        self.bmpname = whoami()
+    # }}}
 
-    # }}}
     # {{{ Shadows and outlines
     def test_theme_shadow_outline(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
 
         t.BackgroundType = 0
         t.BackgroundParameter1 = QtGui.QColor(0,0,0);
         t.Name="shadow/outline"
-        t.Shadow=1
-        t.Outline=1
-        t.ShadowColor=QtGui.QColor(64,128,0)
-        t.OutlineColor=QtGui.QColor(128,0,0)
+        t.Shadow = 1
+        t.Outline = 1
+        t.ShadowColor = QtGui.QColor(64,128,0)
+        t.OutlineColor = QtGui.QColor(128,0,0)
         self.r.set_debug(1)
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        hoffset=self.r._shadow_offset+2*(self.r._outline_offset)
-        voffset=hoffset * (len(self.r.words[0])+1)
+        self.answer = self.r.render_screen(0)
+        hoffset = self.r._shadow_offset+2*(self.r._outline_offset)
+        voffset = hoffset * (len(self.r.words[0])+1)
 
-        self.expected_answer= QtCore.QRect(0, 0, 559+hoffset, 342+voffset)
-        self.bmpname=whoami()
+        self.expected_answer = QtCore.QRect(0, 0, 559+hoffset, 342+voffset)
+        self.bmpname = whoami()
     # }}}
+
     def test_theme_font(self):
-        t=Theme(u'blank_theme.xml')
+        t = Theme(u'blank_theme.xml')
         t.BackgroundType = 0
-        t.BackgroundParameter1 = QtGui.QColor(0,0,64);
-        t.Name="font"
-        t.FontName="Times New Roman"
+        t.BackgroundParameter1 = QtGui.QColor(0,0,64)
+        t.Name = "font"
+        t.FontName = "Times New Roman"
         self.r.set_theme(t)
-        self.answer=self.r.render_screen(0)
-        self.expected_answer= QtCore.QRect(0, 0, 499, 336)
+        self.answer = self.r.render_screen(0)
+        self.expected_answer = QtCore.QRect(0, 0, 499, 336)
         self.bmpname=whoami()
 
 
-if __name__=="__main__":
-    t=TestRenderTheme()
+if __name__ == "__main__":
+    t = TestRenderTheme()
     t.setup_class()
     t.setup_method(None)
     t.test_bg_stretch_y()

=== modified file 'openlp/core/theme/test/test_theme.py'
--- openlp/core/theme/test/test_theme.py	2009-09-03 15:19:30 +0000
+++ openlp/core/theme/test/test_theme.py	2009-09-06 13:57:32 +0000
@@ -50,6 +50,6 @@
     print "Tests passed"
 
     
-if __name__=="__main__":
+if __name__ == "__main__":
     test_read_theme()
     test_theme()

=== modified file 'openlp/core/ui/amendthemeform.py'
--- openlp/core/ui/amendthemeform.py	2009-09-05 01:22:05 +0000
+++ openlp/core/ui/amendthemeform.py	2009-09-07 02:17:36 +0000
@@ -1,710 +1,666 @@
-# -*- coding: utf-8 -*-
-# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
-"""
-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 logging
-import os, os.path
-
-from PyQt4 import QtCore, QtGui
-from openlp.core.lib import ThemeXML, Renderer, file_to_xml, str_to_bool, \
-    translate
-
-from amendthemedialog import Ui_AmendThemeDialog
-
-log = logging.getLogger(u'AmendThemeForm')
-
-class AmendThemeForm(QtGui.QDialog,  Ui_AmendThemeDialog):
-
-    def __init__(self, thememanager, parent=None):
-        QtGui.QDialog.__init__(self, parent)
-        self.thememanager = thememanager
-        self.path = None
-        self.theme = ThemeXML()
-        self.setupUi(self)
-        #define signals
-        #Buttons
-        QtCore.QObject.connect(self.Color1PushButton ,
-            QtCore.SIGNAL(u'pressed()'), self.onColor1PushButtonClicked)
-        QtCore.QObject.connect(self.Color2PushButton ,
-            QtCore.SIGNAL(u'pressed()'), self.onColor2PushButtonClicked)
-        QtCore.QObject.connect(self.FontMainColorPushButton,
-            QtCore.SIGNAL(u'pressed()'), self.onFontMainColorPushButtonClicked)
-        QtCore.QObject.connect(self.FontFooterColorPushButton,
-            QtCore.SIGNAL(u'pressed()'),
-            self.onFontFooterColorPushButtonClicked)
-        QtCore.QObject.connect(self.OutlineColorPushButton,
-            QtCore.SIGNAL(u'pressed()'), self.onOutlineColorPushButtonClicked)
-        QtCore.QObject.connect(self.ShadowColorPushButton,
-            QtCore.SIGNAL(u'pressed()'), self.onShadowColorPushButtonClicked)
-        QtCore.QObject.connect(self.ImageToolButton,
-            QtCore.SIGNAL(u'pressed()'), self.onImageToolButtonClicked)
-        #Combo boxes
-        QtCore.QObject.connect(self.BackgroundComboBox,
-            QtCore.SIGNAL(u'activated(int)'), self.onBackgroundComboBoxSelected)
-        QtCore.QObject.connect(self.BackgroundTypeComboBox,
-            QtCore.SIGNAL(u'activated(int)'),
-            self.onBackgroundTypeComboBoxSelected)
-        QtCore.QObject.connect(self.GradientComboBox,
-            QtCore.SIGNAL(u'activated(int)'), self.onGradientComboBoxSelected)
-        QtCore.QObject.connect(self.FontMainComboBox,
-            QtCore.SIGNAL(u'activated(int)'), self.onFontMainComboBoxSelected)
-        QtCore.QObject.connect(self.FontMainWeightComboBox,
-            QtCore.SIGNAL(u'activated(int)'),
-            self.onFontMainWeightComboBoxSelected)
-        QtCore.QObject.connect(self.FontFooterComboBox,
-            QtCore.SIGNAL(u'activated(int)'), self.onFontFooterComboBoxSelected)
-        QtCore.QObject.connect(self.FontFooterWeightComboBox,
-            QtCore.SIGNAL(u'activated(int)'),
-            self.onFontFooterWeightComboBoxSelected)
-        QtCore.QObject.connect(self.HorizontalComboBox,
-            QtCore.SIGNAL(u'activated(int)'), self.onHorizontalComboBoxSelected)
-        QtCore.QObject.connect(self.VerticalComboBox,
-            QtCore.SIGNAL(u'activated(int)'), self.onVerticalComboBoxSelected)
-        #Spin boxes
-        QtCore.QObject.connect(self.FontMainSizeSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'),
-            self.onFontMainSizeSpinBoxChanged)
-        QtCore.QObject.connect(self.FontFooterSizeSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'),
-            self.onFontFooterSizeSpinBoxChanged)
-        QtCore.QObject.connect(self.FontMainDefaultCheckBox,
-            QtCore.SIGNAL(u'stateChanged(int)'),
-            self.onFontMainDefaultCheckBoxChanged)
-        QtCore.QObject.connect(self.FontMainXSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'), self.onFontMainXSpinBoxChanged)
-        QtCore.QObject.connect(self.FontMainYSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'), self.onFontMainYSpinBoxChanged)
-        QtCore.QObject.connect(self.FontMainWidthSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'),
-            self.onFontMainWidthSpinBoxChanged)
-        QtCore.QObject.connect(self.FontMainHeightSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'),
-            self.onFontMainHeightSpinBoxChanged)
-        QtCore.QObject.connect(self.FontFooterDefaultCheckBox,
-            QtCore.SIGNAL(u'stateChanged(int)'),
-            self.onFontFooterDefaultCheckBoxChanged)
-        QtCore.QObject.connect(self.FontFooterXSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'),
-            self.onFontFooterXSpinBoxChanged)
-        QtCore.QObject.connect(self.FontFooterYSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'),
-            self.onFontFooterYSpinBoxChanged)
-        QtCore.QObject.connect(self.FontFooterWidthSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'),
-            self.onFontFooterWidthSpinBoxChanged)
-        QtCore.QObject.connect(self.FontFooterHeightSpinBox,
-            QtCore.SIGNAL(u'editingFinished()'),
-            self.onFontFooterHeightSpinBoxChanged)
-        QtCore.QObject.connect(self.OutlineCheckBox,
-            QtCore.SIGNAL(u'stateChanged(int)'), self.onOutlineCheckBoxChanged)
-        QtCore.QObject.connect(self.ShadowCheckBox,
-            QtCore.SIGNAL(u'stateChanged(int)'), self.onShadowCheckBoxChanged)
-
-    def accept(self):
-        new_theme = ThemeXML()
-        theme_name = unicode(self.ThemeNameEdit.displayText())
-        new_theme.new_document(theme_name)
-        save_from = None
-        save_to = None
-        if self.theme.background_mode == u'transparent':
-            new_theme.add_background_transparent()
-        else:
-            if self.theme.background_type == u'solid':
-                new_theme.add_background_solid( \
-                    unicode(self.theme.background_color))
-            elif self.theme.background_type == u'gradient':
-                new_theme.add_background_gradient( \
-                    unicode(self.theme.background_startColor),
-                    unicode(self.theme.background_endColor),
-                    self.theme.background_direction)
-            else:
-                (path, filename) = \
-                    os.path.split(unicode(self.theme.background_filename))
-                new_theme.add_background_image(filename)
-                save_to= os.path.join(self.path, theme_name, filename )
-                save_from = self.theme.background_filename
-
-        new_theme.add_font(unicode(self.theme.font_main_name),
-                unicode(self.theme.font_main_color),
-                unicode(self.theme.font_main_proportion),
-                unicode(self.theme.font_main_override), u'main',
-                unicode(self.theme.font_main_weight),
-                unicode(self.theme.font_main_italics),
-                unicode(self.theme.font_main_x),
-                unicode(self.theme.font_main_y),
-                unicode(self.theme.font_main_width),
-                unicode(self.theme.font_main_height))
-        new_theme.add_font(unicode(self.theme.font_footer_name),
-                unicode(self.theme.font_footer_color),
-                unicode(self.theme.font_footer_proportion),
-                unicode(self.theme.font_footer_override), u'footer',
-                unicode(self.theme.font_footer_weight),
-                unicode(self.theme.font_footer_italics),
-                unicode(self.theme.font_footer_x),
-                unicode(self.theme.font_footer_y),
-                unicode(self.theme.font_footer_width),
-                unicode(self.theme.font_footer_height) )
-        new_theme.add_display(unicode(self.theme.display_shadow),
-                unicode(self.theme.display_shadow_color),
-                unicode(self.theme.display_outline),
-                unicode(self.theme.display_outline_color),
-                unicode(self.theme.display_horizontalAlign),
-                unicode(self.theme.display_verticalAlign),
-                unicode(self.theme.display_wrapStyle))
-        theme = new_theme.extract_xml()
-        pretty_theme = new_theme.extract_formatted_xml()
-        if self.thememanager.saveTheme(theme_name, theme, pretty_theme,
-            save_from, save_to) is not False:
-            return QtGui.QDialog.accept(self)
-
-    def loadTheme(self, theme):
-        log.debug(u'LoadTheme %s', theme)
-        if theme == None:
-            self.theme.parse(self.baseTheme())
-        else:
-            xml_file = os.path.join(self.path, theme, theme + u'.xml')
-            xml = file_to_xml(xml_file)
-            self.theme.parse(xml)
-            self.theme.extend_image_filename(self.path)
-        self.cleanTheme(self.theme)
-        self.allowPreview = False
-        self.paintUi(self.theme)
-        self.allowPreview = True
-        self.previewTheme(self.theme)
-
-    def cleanTheme(self, theme):
-        self.theme.background_color = theme.background_color.strip()
-        self.theme.background_direction = theme.background_direction.strip()
-        self.theme.background_endColor = theme.background_endColor.strip()
-        if theme.background_filename:
-            self.theme.background_filename = theme.background_filename.strip()
-        #self.theme.background_mode
-        self.theme.background_startColor = theme.background_startColor.strip()
-        #self.theme.background_type
-        self.theme.display_display = theme.display_display.strip()
-        self.theme.display_horizontalAlign = \
-            theme.display_horizontalAlign.strip()
-        self.theme.display_outline = str_to_bool(theme.display_outline)
-        #self.theme.display_outline_color
-        self.theme.display_shadow = str_to_bool(theme.display_shadow)
-        #self.theme.display_shadow_color
-        self.theme.display_verticalAlign = \
-            theme.display_verticalAlign.strip()
-        self.theme.display_wrapStyle = theme.display_wrapStyle.strip()
-        self.theme.font_footer_color = theme.font_footer_color.strip()
-        self.theme.font_footer_height = theme.font_footer_height.strip()
-        self.theme.font_footer_italics = str_to_bool(theme.font_footer_italics)
-        self.theme.font_footer_name = theme.font_footer_name.strip()
-        #self.theme.font_footer_override
-        self.theme.font_footer_proportion = \
-            theme.font_footer_proportion.strip()
-        self.theme.font_footer_weight = theme.font_footer_weight.strip()
-        self.theme.font_footer_width = theme.font_footer_width.strip()
-        self.theme.font_footer_x = theme.font_footer_x.strip()
-        self.theme.font_footer_y = theme.font_footer_y.strip()
-        self.theme.font_main_color = theme.font_main_color.strip()
-        self.theme.font_main_height = theme.font_main_height.strip()
-        self.theme.font_main_italics = str_to_bool(theme.font_main_italics)
-        self.theme.font_main_name = theme.font_main_name.strip()
-        #self.theme.font_main_override
-        self.theme.font_main_proportion = theme.font_main_proportion.strip()
-        self.theme.font_main_weight = theme.font_main_weight.strip()
-        self.theme.font_main_x = theme.font_main_x.strip()
-        self.theme.font_main_y = theme.font_main_y.strip()
-        #self.theme.theme_mode
-        self.theme.theme_name = theme.theme_name.strip()
-        #self.theme.theme_version
-
-    def onImageToolButtonClicked(self):
-        filename = QtGui.QFileDialog.getOpenFileName(self, 'Open file')
-        if filename != "":
-            self.ImageLineEdit.setText(filename)
-            self.theme.background_filename = filename
-            self.previewTheme(self.theme)
-    #
-    #Main Font Tab
-    #
-    def onFontMainComboBoxSelected(self):
-        self.theme.font_main_name = self.FontMainComboBox.currentFont().family()
-        self.previewTheme(self.theme)
-
-    def onFontMainWeightComboBoxSelected(self, value):
-        if value  ==0:
-            self.theme.font_main_weight = u'Normal'
-            self.theme.font_main_italics = False
-        elif value  == 1:
-            self.theme.font_main_weight = u'Bold'
-            self.theme.font_main_italics = False
-        elif value  == 2:
-            self.theme.font_main_weight = u'Normal'
-            self.theme.font_main_italics = True
-        else:
-            self.theme.font_main_weight = u'Bold'
-            self.theme.font_main_italics = True
-        self.previewTheme(self.theme)
-
-    def onFontMainColorPushButtonClicked(self):
-        self.theme.font_main_color = QtGui.QColorDialog.getColor(
-            QtGui.QColor(self.theme.font_main_color), self).name()
-
-        self.FontMainColorPushButton.setStyleSheet(
-            u'background-color: %s' % unicode(self.theme.font_main_color))
-        self.previewTheme(self.theme)
-
-    def onFontMainSizeSpinBoxChanged(self):
-        if self.theme.font_main_proportion != self.FontMainSizeSpinBox.value():
-            self.theme.font_main_proportion = self.FontMainSizeSpinBox.value()
-            self.previewTheme(self.theme)
-
-    def onFontMainDefaultCheckBoxChanged(self, value):
-        if value == 2:  # checked
-            self.theme.font_main_override = False
-        else:
-            self.theme.font_main_override = True
-
-        if int(self.theme.font_main_x) == 0 and \
-            int(self.theme.font_main_y) == 0 and \
-            int(self.theme.font_main_width) == 0 and \
-            int(self.theme.font_main_height) == 0:
-            self.theme.font_main_x = u'10'
-            self.theme.font_main_y = u'10'
-            self.theme.font_main_width = u'1024'
-            self.theme.font_main_height = u'730'
-            self.FontMainXSpinBox.setValue(int(self.theme.font_main_x))
-            self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))
-            self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))
-            self.FontMainHeightSpinBox.setValue(int( \
-                self.theme.font_main_height))
-        self.stateChanging(self.theme)
-        self.previewTheme(self.theme)
-
-    def onFontMainXSpinBoxChanged(self):
-        if self.theme.font_main_x != self.FontMainXSpinBox.value():
-            self.theme.font_main_x = self.FontMainXSpinBox.value()
-            self.previewTheme(self.theme)
-
-    def onFontMainYSpinBoxChanged(self):
-        if self.theme.font_main_y != self.FontMainYSpinBox.value():
-            self.theme.font_main_y = self.FontMainYSpinBox.value()
-            self.previewTheme(self.theme)
-
-    def onFontMainWidthSpinBoxChanged(self):
-        if self.theme.font_main_width != self.FontMainWidthSpinBox.value():
-            self.theme.font_main_width = self.FontMainWidthSpinBox.value()
-            self.previewTheme(self.theme)
-
-    def onFontMainHeightSpinBoxChanged(self):
-        if self.theme.font_main_height != self.FontMainHeightSpinBox.value():
-            self.theme.font_main_height = self.FontMainHeightSpinBox.value()
-            self.previewTheme(self.theme)
-    #
-    #Footer Font Tab
-    #
-    def onFontFooterComboBoxSelected(self):
-        self.theme.font_footer_name = \
-            self.FontFooterComboBox.currentFont().family()
-        self.previewTheme(self.theme)
-
-    def onFontFooterWeightComboBoxSelected(self, value):
-        if value  == 0:
-            self.theme.font_footer_weight = u'Normal'
-            self.theme.font_footer_italics = False
-        elif value  == 1:
-            self.theme.font_footer_weight = u'Bold'
-            self.theme.font_footer_italics = False
-        elif value  == 2:
-            self.theme.font_footer_weight = u'Normal'
-            self.theme.font_footer_italics = True
-        else:
-            self.theme.font_footer_weight = u'Bold'
-            self.theme.font_footer_italics = True
-        self.previewTheme(self.theme)
-
-    def onFontFooterColorPushButtonClicked(self):
-        self.theme.font_footer_color = QtGui.QColorDialog.getColor(
-            QtGui.QColor(self.theme.font_footer_color), self).name()
-
-        self.FontFooterColorPushButton.setStyleSheet(
-            'background-color: %s' % unicode(self.theme.font_footer_color))
-        self.previewTheme(self.theme)
-
-    def onFontFooterSizeSpinBoxChanged(self):
-        if self.theme.font_footer_proportion != \
-            self.FontFooterSizeSpinBox.value():
-            self.theme.font_footer_proportion = \
-                self.FontFooterSizeSpinBox.value()
-            self.previewTheme(self.theme)
-
-    def onFontFooterDefaultCheckBoxChanged(self, value):
-        if value == 2:  # checked
-            self.theme.font_footer_override = False
-        else:
-            self.theme.font_footer_override = True
-
-        if int(self.theme.font_footer_x) == 0 and \
-            int(self.theme.font_footer_y) == 0 and \
-            int(self.theme.font_footer_width) == 0 and \
-            int(self.theme.font_footer_height) == 0:
-            self.theme.font_footer_x = u'10'
-            self.theme.font_footer_y = u'730'
-            self.theme.font_footer_width = u'1024'
-            self.theme.font_footer_height = u'38'
-
-            self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))
-            self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))
-            self.FontFooterWidthSpinBox.setValue(int( \
-                self.theme.font_footer_width))
-            self.FontFooterHeightSpinBox.setValue(int( \
-                self.theme.font_footer_height))
-
-        self.stateChanging(self.theme)
-        self.previewTheme(self.theme)
-
-    def onFontFooterXSpinBoxChanged(self):
-        if self.theme.font_footer_x != self.FontFooterXSpinBox.value():
-            self.theme.font_footer_x = self.FontFooterXSpinBox.value()
-            self.previewTheme(self.theme)
-
-    def onFontFooterYSpinBoxChanged(self):
-        if self.theme.font_footer_y != self.FontFooterYSpinBox.value():
-            self.theme.font_footer_y = self.FontFooterYSpinBox.value()
-            self.previewTheme(self.theme)
-
-    def onFontFooterWidthSpinBoxChanged(self):
-        if self.theme.font_footer_width != self.FontFooterWidthSpinBox.value():
-            self.theme.font_footer_width = self.FontFooterWidthSpinBox.value()
-            self.previewTheme(self.theme)
-
-    def onFontFooterHeightSpinBoxChanged(self):
-        if self.theme.font_footer_height != \
-            self.FontFooterHeightSpinBox.value():
-            self.theme.font_footer_height = self.FontFooterHeightSpinBox.value()
-            self.previewTheme(self.theme)
-    #
-    #Background Tab
-    #
-    def onGradientComboBoxSelected(self, currentIndex):
-        self.setBackground(self.BackgroundTypeComboBox.currentIndex(),
-            currentIndex)
-
-    def onBackgroundComboBoxSelected(self, currentIndex):
-        if currentIndex == 0: # Opaque
-            self.theme.background_mode = u'opaque'
-        else:
-            self.theme.background_mode = u'transparent'
-        self.stateChanging(self.theme)
-        self.previewTheme(self.theme)
-
-    def onBackgroundTypeComboBoxSelected(self, currentIndex):
-        self.setBackground(currentIndex, self.GradientComboBox.currentIndex())
-
-    def setBackground(self, background, gradient):
-        if background == 0: # Solid
-            self.theme.background_type = u'solid'
-            if self.theme.background_color is None :
-                self.theme.background_color = u'#000000'
-        elif background == 1: # Gradient
-            self.theme.background_type = u'gradient'
-            if gradient == 0: # Horizontal
-                self.theme.background_direction = u'horizontal'
-            elif gradient == 1: # vertical
-                self.theme.background_direction = u'vertical'
-            else:
-                self.theme.background_direction = u'circular'
-            if self.theme.background_startColor is None :
-                self.theme.background_startColor = u'#000000'
-            if self.theme.background_endColor is None :
-                self.theme.background_endColor = u'#ff0000'
-        else:
-            self.theme.background_type = u'image'
-        self.stateChanging(self.theme)
-        self.previewTheme(self.theme)
-
-    def onColor1PushButtonClicked(self):
-        if self.theme.background_type == u'solid':
-            self.theme.background_color = QtGui.QColorDialog.getColor(
-                QtGui.QColor(self.theme.background_color), self).name()
-            self.Color1PushButton.setStyleSheet(
-                u'background-color: %s' % unicode(self.theme.background_color))
-        else:
-            self.theme.background_startColor = QtGui.QColorDialog.getColor(
-                QtGui.QColor(self.theme.background_startColor), self).name()
-            self.Color1PushButton.setStyleSheet(
-                u'background-color: %s' % \
-                    unicode(self.theme.background_startColor))
-
-        self.previewTheme(self.theme)
-
-    def onColor2PushButtonClicked(self):
-        self.theme.background_endColor = QtGui.QColorDialog.getColor(
-            QtGui.QColor(self.theme.background_endColor), self).name()
-        self.Color2PushButton.setStyleSheet(
-            u'background-color: %s' % unicode(self.theme.background_endColor))
-
-        self.previewTheme(self.theme)
-    #
-    #Other Tab
-    #
-    def onOutlineCheckBoxChanged(self, value):
-        if value == 2:  # checked
-            self.theme.display_outline = True
-        else:
-            self.theme.display_outline = False
-        self.stateChanging(self.theme)
-        self.previewTheme(self.theme)
-
-    def onOutlineColorPushButtonClicked(self):
-        self.theme.display_outline_color = QtGui.QColorDialog.getColor(
-            QtGui.QColor(self.theme.display_outline_color), self).name()
-        self.OutlineColorPushButton.setStyleSheet(
-            u'background-color: %s' % unicode(self.theme.display_outline_color))
-        self.previewTheme(self.theme)
-
-    def onShadowCheckBoxChanged(self, value):
-        if value == 2:  # checked
-            self.theme.display_shadow = True
-        else:
-            self.theme.display_shadow = False
-        self.stateChanging(self.theme)
-        self.previewTheme(self.theme)
-
-    def onShadowColorPushButtonClicked(self):
-        self.theme.display_shadow_color = QtGui.QColorDialog.getColor(
-            QtGui.QColor(self.theme.display_shadow_color), self).name()
-        self.ShadowColorPushButton.setStyleSheet(
-            u'background-color: %s' % unicode(self.theme.display_shadow_color))
-        self.previewTheme(self.theme)
-
-    def onHorizontalComboBoxSelected(self, currentIndex):
-        self.theme.display_horizontalAlign = currentIndex
-        self.stateChanging(self.theme)
-        self.previewTheme(self.theme)
-
-    def onVerticalComboBoxSelected(self, currentIndex):
-        self.theme.display_verticalAlign = currentIndex
-        self.stateChanging(self.theme)
-        self.previewTheme(self.theme)
-    #
-    #Local Methods
-    #
-    def baseTheme(self):
-        log.debug(u'base theme created')
-        newtheme = ThemeXML()
-        newtheme.new_document(u'New Theme')
-        newtheme.add_background_solid(unicode(u'#000000'))
-        newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
-            unicode(30), u'False')
-        newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
-            unicode(12), u'False', u'footer')
-        newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',
-            unicode(u'#FFFFFF'),
-            unicode(0), unicode(0), unicode(0))
-
-        return newtheme.extract_xml()
-
-    def paintUi(self, theme):
-        self.stateChanging(theme)
-        self.ThemeNameEdit.setText(self.theme.theme_name)
-        if self.theme.background_mode == u'opaque':
-            self.BackgroundComboBox.setCurrentIndex(0)
-        else:
-            self.BackgroundComboBox.setCurrentIndex(1)
-
-        if theme.background_type == u'solid':
-            self.BackgroundTypeComboBox.setCurrentIndex(0)
-        elif theme.background_type == u'gradient':
-            self.BackgroundTypeComboBox.setCurrentIndex(1)
-        else:
-            self.BackgroundTypeComboBox.setCurrentIndex(2)
-
-        if self.theme.background_direction == u'horizontal':
-            self.GradientComboBox.setCurrentIndex(0)
-        elif self.theme.background_direction == u'vertical':
-            self.GradientComboBox.setCurrentIndex(1)
-        else:
-            self.GradientComboBox.setCurrentIndex(2)
-
-        self.FontMainSizeSpinBox.setValue(int(self.theme.font_main_proportion))
-        if not self.theme.font_main_italics and \
-            self.theme.font_main_weight == u'Normal':
-            self.FontMainWeightComboBox.setCurrentIndex(0)
-        elif not self.theme.font_main_italics and \
-            self.theme.font_main_weight == u'Bold':
-            self.FontMainWeightComboBox.setCurrentIndex(1)
-        elif self.theme.font_main_italics and \
-            self.theme.font_main_weight == u'Normal':
-            self.FontMainWeightComboBox.setCurrentIndex(2)
-        else:
-            self.FontMainWeightComboBox.setCurrentIndex(3)
-
-        self.FontMainXSpinBox.setValue(int(self.theme.font_main_x))
-        self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))
-        self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))
-        self.FontMainHeightSpinBox.setValue(int(self.theme.font_main_height))
-        self.FontFooterSizeSpinBox.setValue(int( \
-            self.theme.font_footer_proportion))
-        if not self.theme.font_footer_italics and \
-            self.theme.font_footer_weight == u'Normal':
-            self.FontFooterWeightComboBox.setCurrentIndex(0)
-        elif not self.theme.font_footer_italics and \
-            self.theme.font_footer_weight == u'Bold':
-            self.FontFooterWeightComboBox.setCurrentIndex(1)
-        elif self.theme.font_footer_italics and \
-            self.theme.font_footer_weight == u'Normal':
-            self.FontFooterWeightComboBox.setCurrentIndex(2)
-        else:
-            self.FontFooterWeightComboBox.setCurrentIndex(3)
-        self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))
-        self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))
-        self.FontFooterWidthSpinBox.setValue(int(self.theme.font_footer_width))
-        self.FontFooterHeightSpinBox.setValue(int( \
-            self.theme.font_footer_height))
-        self.FontMainColorPushButton.setStyleSheet(
-            u'background-color: %s' % unicode(theme.font_main_color))
-        self.FontFooterColorPushButton.setStyleSheet(
-            u'background-color: %s' % unicode(theme.font_footer_color))
-
-        if self.theme.font_main_override == False:
-            self.FontMainDefaultCheckBox.setChecked(True)
-        else:
-            self.FontMainDefaultCheckBox.setChecked(False)
-
-        if self.theme.font_footer_override == False:
-            self.FontFooterDefaultCheckBox.setChecked(True)
-        else:
-            self.FontFooterDefaultCheckBox.setChecked(False)
-
-        self.OutlineColorPushButton.setStyleSheet(
-            u'background-color: %s' % unicode(theme.display_outline_color))
-        self.ShadowColorPushButton.setStyleSheet(
-            u'background-color: %s' % unicode(theme.display_shadow_color))
-
-        if self.theme.display_outline:
-            self.OutlineCheckBox.setChecked(True)
-            self.OutlineColorPushButton.setEnabled(True)
-        else:
-            self.OutlineCheckBox.setChecked(False)
-            self.OutlineColorPushButton.setEnabled(False)
-
-        if self.theme.display_shadow:
-            self.ShadowCheckBox.setChecked(True)
-            self.ShadowColorPushButton.setEnabled(True)
-        else:
-            self.ShadowCheckBox.setChecked(False)
-            self.ShadowColorPushButton.setEnabled(False)
-
-        self.HorizontalComboBox.setCurrentIndex(int( \
-            self.theme.display_horizontalAlign))
-        self.VerticalComboBox.setCurrentIndex(int( \
-            self.theme.display_verticalAlign))
-
-    def stateChanging(self, theme):
-        if theme.background_mode == u'transparent':
-                self.Color1Label.setVisible(False)
-                self.Color1PushButton.setVisible(False)
-                self.Color2Label.setVisible(False)
-                self.Color2PushButton.setVisible(False)
-                self.ImageLabel.setVisible(False)
-                self.ImageLineEdit.setVisible(False)
-                self.ImageFilenameWidget.setVisible(False)
-                self.GradientLabel.setVisible(False)
-                self.GradientComboBox.setVisible(False)
-                self.BackgroundTypeComboBox.setVisible(False)
-                self.BackgroundTypeLabel.setVisible(False)
-        else:
-            self.BackgroundTypeComboBox.setVisible(True)
-            self.BackgroundTypeLabel.setVisible(True)
-            if theme.background_type == u'solid':
-                self.Color1PushButton.setStyleSheet(
-                    u'background-color: %s' % unicode(theme.background_color))
-                self.Color1Label.setText(translate(u'ThemeManager',
-                    u'Background Color:'))
-                self.Color1Label.setVisible(True)
-                self.Color1PushButton.setVisible(True)
-                self.Color2Label.setVisible(False)
-                self.Color2PushButton.setVisible(False)
-                self.ImageLabel.setVisible(False)
-                self.ImageLineEdit.setVisible(False)
-                self.ImageFilenameWidget.setVisible(False)
-                self.GradientLabel.setVisible(False)
-                self.GradientComboBox.setVisible(False)
-            elif theme.background_type == u'gradient':
-                self.Color1PushButton.setStyleSheet(u'background-color: %s' \
-                    % unicode(theme.background_startColor))
-                self.Color2PushButton.setStyleSheet(u'background-color: %s' \
-                    % unicode(theme.background_endColor))
-                self.Color1Label.setText(translate(u'ThemeManager',
-                    u'First  Color:'))
-                self.Color2Label.setText(translate(u'ThemeManager',
-                    u'Second Color:'))
-                self.Color1Label.setVisible(True)
-                self.Color1PushButton.setVisible(True)
-                self.Color2Label.setVisible(True)
-                self.Color2PushButton.setVisible(True)
-                self.ImageLabel.setVisible(False)
-                self.ImageLineEdit.setVisible(False)
-                self.ImageFilenameWidget.setVisible(False)
-                self.GradientLabel.setVisible(True)
-                self.GradientComboBox.setVisible(True)
-            else: # must be image
-                self.Color1Label.setVisible(False)
-                self.Color1PushButton.setVisible(False)
-                self.Color2Label.setVisible(False)
-                self.Color2PushButton.setVisible(False)
-                self.ImageLabel.setVisible(True)
-                self.ImageLineEdit.setVisible(True)
-                self.ImageFilenameWidget.setVisible(True)
-                self.GradientLabel.setVisible(False)
-                self.GradientComboBox.setVisible(False)
-
-        if theme.font_main_override == False:
-            self.FontMainXSpinBox.setEnabled(False)
-            self.FontMainYSpinBox.setEnabled(False)
-            self.FontMainWidthSpinBox.setEnabled(False)
-            self.FontMainHeightSpinBox.setEnabled(False)
-        else:
-            self.FontMainXSpinBox.setEnabled(True)
-            self.FontMainYSpinBox.setEnabled(True)
-            self.FontMainWidthSpinBox.setEnabled(True)
-            self.FontMainHeightSpinBox.setEnabled(True)
-
-        if theme.font_footer_override == False:
-            self.FontFooterXSpinBox.setEnabled(False)
-            self.FontFooterYSpinBox.setEnabled(False)
-            self.FontFooterWidthSpinBox.setEnabled(False)
-            self.FontFooterHeightSpinBox.setEnabled(False)
-        else:
-            self.FontFooterXSpinBox.setEnabled(True)
-            self.FontFooterYSpinBox.setEnabled(True)
-            self.FontFooterWidthSpinBox.setEnabled(True)
-            self.FontFooterHeightSpinBox.setEnabled(True)
-
-        if self.theme.display_outline:
-            self.OutlineColorPushButton.setEnabled(True)
-        else:
-            self.OutlineColorPushButton.setEnabled(False)
-
-        if self.theme.display_shadow:
-            self.ShadowColorPushButton.setEnabled(True)
-        else:
-            self.ShadowColorPushButton.setEnabled(False)
-
-    def previewTheme(self, theme):
-        if self.allowPreview:
-            frame = self.thememanager.generateImage(theme)
-            self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+"""
+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 logging
+import os, os.path
+
+from PyQt4 import QtCore, QtGui
+from openlp.core.lib import ThemeXML, Renderer, file_to_xml, translate
+
+from amendthemedialog import Ui_AmendThemeDialog
+
+log = logging.getLogger(u'AmendThemeForm')
+
+class AmendThemeForm(QtGui.QDialog,  Ui_AmendThemeDialog):
+
+    def __init__(self, thememanager, parent=None):
+        QtGui.QDialog.__init__(self, parent)
+        self.thememanager = thememanager
+        self.path = None
+        self.theme = ThemeXML()
+        self.setupUi(self)
+        #define signals
+        #Buttons
+        QtCore.QObject.connect(self.Color1PushButton ,
+            QtCore.SIGNAL(u'pressed()'), self.onColor1PushButtonClicked)
+        QtCore.QObject.connect(self.Color2PushButton ,
+            QtCore.SIGNAL(u'pressed()'), self.onColor2PushButtonClicked)
+        QtCore.QObject.connect(self.FontMainColorPushButton,
+            QtCore.SIGNAL(u'pressed()'), self.onFontMainColorPushButtonClicked)
+        QtCore.QObject.connect(self.FontFooterColorPushButton,
+            QtCore.SIGNAL(u'pressed()'),
+            self.onFontFooterColorPushButtonClicked)
+        QtCore.QObject.connect(self.OutlineColorPushButton,
+            QtCore.SIGNAL(u'pressed()'), self.onOutlineColorPushButtonClicked)
+        QtCore.QObject.connect(self.ShadowColorPushButton,
+            QtCore.SIGNAL(u'pressed()'), self.onShadowColorPushButtonClicked)
+        QtCore.QObject.connect(self.ImageToolButton,
+            QtCore.SIGNAL(u'pressed()'), self.onImageToolButtonClicked)
+        #Combo boxes
+        QtCore.QObject.connect(self.BackgroundComboBox,
+            QtCore.SIGNAL(u'activated(int)'), self.onBackgroundComboBoxSelected)
+        QtCore.QObject.connect(self.BackgroundTypeComboBox,
+            QtCore.SIGNAL(u'activated(int)'),
+            self.onBackgroundTypeComboBoxSelected)
+        QtCore.QObject.connect(self.GradientComboBox,
+            QtCore.SIGNAL(u'activated(int)'), self.onGradientComboBoxSelected)
+        QtCore.QObject.connect(self.FontMainComboBox,
+            QtCore.SIGNAL(u'activated(int)'), self.onFontMainComboBoxSelected)
+        QtCore.QObject.connect(self.FontMainWeightComboBox,
+            QtCore.SIGNAL(u'activated(int)'),
+            self.onFontMainWeightComboBoxSelected)
+        QtCore.QObject.connect(self.FontFooterComboBox,
+            QtCore.SIGNAL(u'activated(int)'), self.onFontFooterComboBoxSelected)
+        QtCore.QObject.connect(self.FontFooterWeightComboBox,
+            QtCore.SIGNAL(u'activated(int)'),
+            self.onFontFooterWeightComboBoxSelected)
+        QtCore.QObject.connect(self.HorizontalComboBox,
+            QtCore.SIGNAL(u'activated(int)'), self.onHorizontalComboBoxSelected)
+        QtCore.QObject.connect(self.VerticalComboBox,
+            QtCore.SIGNAL(u'activated(int)'), self.onVerticalComboBoxSelected)
+        #Spin boxes
+        QtCore.QObject.connect(self.FontMainSizeSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'),
+            self.onFontMainSizeSpinBoxChanged)
+        QtCore.QObject.connect(self.FontFooterSizeSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'),
+            self.onFontFooterSizeSpinBoxChanged)
+        QtCore.QObject.connect(self.FontMainDefaultCheckBox,
+            QtCore.SIGNAL(u'stateChanged(int)'),
+            self.onFontMainDefaultCheckBoxChanged)
+        QtCore.QObject.connect(self.FontMainXSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'), self.onFontMainXSpinBoxChanged)
+        QtCore.QObject.connect(self.FontMainYSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'), self.onFontMainYSpinBoxChanged)
+        QtCore.QObject.connect(self.FontMainWidthSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'),
+            self.onFontMainWidthSpinBoxChanged)
+        QtCore.QObject.connect(self.FontMainHeightSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'),
+            self.onFontMainHeightSpinBoxChanged)
+        QtCore.QObject.connect(self.FontFooterDefaultCheckBox,
+            QtCore.SIGNAL(u'stateChanged(int)'),
+            self.onFontFooterDefaultCheckBoxChanged)
+        QtCore.QObject.connect(self.FontFooterXSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'),
+            self.onFontFooterXSpinBoxChanged)
+        QtCore.QObject.connect(self.FontFooterYSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'),
+            self.onFontFooterYSpinBoxChanged)
+        QtCore.QObject.connect(self.FontFooterWidthSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'),
+            self.onFontFooterWidthSpinBoxChanged)
+        QtCore.QObject.connect(self.FontFooterHeightSpinBox,
+            QtCore.SIGNAL(u'editingFinished()'),
+            self.onFontFooterHeightSpinBoxChanged)
+        QtCore.QObject.connect(self.OutlineCheckBox,
+            QtCore.SIGNAL(u'stateChanged(int)'), self.onOutlineCheckBoxChanged)
+        QtCore.QObject.connect(self.ShadowCheckBox,
+            QtCore.SIGNAL(u'stateChanged(int)'), self.onShadowCheckBoxChanged)
+
+    def accept(self):
+        new_theme = ThemeXML()
+        theme_name = unicode(self.ThemeNameEdit.displayText())
+        new_theme.new_document(theme_name)
+        save_from = None
+        save_to = None
+        if self.theme.background_mode == u'transparent':
+            new_theme.add_background_transparent()
+        else:
+            if self.theme.background_type == u'solid':
+                new_theme.add_background_solid(
+                    unicode(self.theme.background_color))
+            elif self.theme.background_type == u'gradient':
+                new_theme.add_background_gradient(
+                    unicode(self.theme.background_startColor),
+                    unicode(self.theme.background_endColor),
+                    self.theme.background_direction)
+            else:
+                (path, filename) = \
+                    os.path.split(unicode(self.theme.background_filename))
+                new_theme.add_background_image(filename)
+                save_to= os.path.join(self.path, theme_name, filename )
+                save_from = self.theme.background_filename
+
+        new_theme.add_font(unicode(self.theme.font_main_name),
+                unicode(self.theme.font_main_color),
+                unicode(self.theme.font_main_proportion),
+                unicode(self.theme.font_main_override), u'main',
+                unicode(self.theme.font_main_weight),
+                unicode(self.theme.font_main_italics),
+                unicode(self.theme.font_main_x),
+                unicode(self.theme.font_main_y),
+                unicode(self.theme.font_main_width),
+                unicode(self.theme.font_main_height))
+        new_theme.add_font(unicode(self.theme.font_footer_name),
+                unicode(self.theme.font_footer_color),
+                unicode(self.theme.font_footer_proportion),
+                unicode(self.theme.font_footer_override), u'footer',
+                unicode(self.theme.font_footer_weight),
+                unicode(self.theme.font_footer_italics),
+                unicode(self.theme.font_footer_x),
+                unicode(self.theme.font_footer_y),
+                unicode(self.theme.font_footer_width),
+                unicode(self.theme.font_footer_height) )
+        new_theme.add_display(unicode(self.theme.display_shadow),
+                unicode(self.theme.display_shadow_color),
+                unicode(self.theme.display_outline),
+                unicode(self.theme.display_outline_color),
+                unicode(self.theme.display_horizontalAlign),
+                unicode(self.theme.display_verticalAlign),
+                unicode(self.theme.display_wrapStyle))
+        theme = new_theme.extract_xml()
+        pretty_theme = new_theme.extract_formatted_xml()
+        if self.thememanager.saveTheme(theme_name, theme, pretty_theme,
+            save_from, save_to) is not False:
+            return QtGui.QDialog.accept(self)
+
+    def loadTheme(self, theme):
+        log.debug(u'LoadTheme %s', theme)
+        if theme == None:
+            self.theme.parse(self.baseTheme())
+        else:
+            xml_file = os.path.join(self.path, theme, theme + u'.xml')
+            xml = file_to_xml(xml_file)
+            self.theme.parse(xml)
+            self.theme.extend_image_filename(self.path)
+        self.thememanager.cleanTheme(self.theme)
+        self.allowPreview = False
+        self.paintUi(self.theme)
+        self.allowPreview = True
+        self.previewTheme(self.theme)
+
+    def onImageToolButtonClicked(self):
+        filename = QtGui.QFileDialog.getOpenFileName(self, 'Open file')
+        if filename != "":
+            self.ImageLineEdit.setText(filename)
+            self.theme.background_filename = filename
+            self.previewTheme(self.theme)
+    #
+    #Main Font Tab
+    #
+    def onFontMainComboBoxSelected(self):
+        self.theme.font_main_name = self.FontMainComboBox.currentFont().family()
+        self.previewTheme(self.theme)
+
+    def onFontMainWeightComboBoxSelected(self, value):
+        if value == 0:
+            self.theme.font_main_weight = u'Normal'
+            self.theme.font_main_italics = False
+        elif value == 1:
+            self.theme.font_main_weight = u'Bold'
+            self.theme.font_main_italics = False
+        elif value == 2:
+            self.theme.font_main_weight = u'Normal'
+            self.theme.font_main_italics = True
+        else:
+            self.theme.font_main_weight = u'Bold'
+            self.theme.font_main_italics = True
+        self.previewTheme(self.theme)
+
+    def onFontMainColorPushButtonClicked(self):
+        self.theme.font_main_color = QtGui.QColorDialog.getColor(
+            QtGui.QColor(self.theme.font_main_color), self).name()
+
+        self.FontMainColorPushButton.setStyleSheet(
+            u'background-color: %s' % unicode(self.theme.font_main_color))
+        self.previewTheme(self.theme)
+
+    def onFontMainSizeSpinBoxChanged(self):
+        if self.theme.font_main_proportion != self.FontMainSizeSpinBox.value():
+            self.theme.font_main_proportion = self.FontMainSizeSpinBox.value()
+            self.previewTheme(self.theme)
+
+    def onFontMainDefaultCheckBoxChanged(self, value):
+        if value == 2:  # checked
+            self.theme.font_main_override = False
+        else:
+            self.theme.font_main_override = True
+
+        if int(self.theme.font_main_x) == 0 and \
+            int(self.theme.font_main_y) == 0 and \
+            int(self.theme.font_main_width) == 0 and \
+            int(self.theme.font_main_height) == 0:
+            self.theme.font_main_x = u'10'
+            self.theme.font_main_y = u'10'
+            self.theme.font_main_width = u'1024'
+            self.theme.font_main_height = u'730'
+            self.FontMainXSpinBox.setValue(int(self.theme.font_main_x))
+            self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))
+            self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))
+            self.FontMainHeightSpinBox.setValue(int(
+                self.theme.font_main_height))
+        self.stateChanging(self.theme)
+        self.previewTheme(self.theme)
+
+    def onFontMainXSpinBoxChanged(self):
+        if self.theme.font_main_x != self.FontMainXSpinBox.value():
+            self.theme.font_main_x = self.FontMainXSpinBox.value()
+            self.previewTheme(self.theme)
+
+    def onFontMainYSpinBoxChanged(self):
+        if self.theme.font_main_y != self.FontMainYSpinBox.value():
+            self.theme.font_main_y = self.FontMainYSpinBox.value()
+            self.previewTheme(self.theme)
+
+    def onFontMainWidthSpinBoxChanged(self):
+        if self.theme.font_main_width != self.FontMainWidthSpinBox.value():
+            self.theme.font_main_width = self.FontMainWidthSpinBox.value()
+            self.previewTheme(self.theme)
+
+    def onFontMainHeightSpinBoxChanged(self):
+        if self.theme.font_main_height != self.FontMainHeightSpinBox.value():
+            self.theme.font_main_height = self.FontMainHeightSpinBox.value()
+            self.previewTheme(self.theme)
+    #
+    #Footer Font Tab
+    #
+    def onFontFooterComboBoxSelected(self):
+        self.theme.font_footer_name = \
+            self.FontFooterComboBox.currentFont().family()
+        self.previewTheme(self.theme)
+
+    def onFontFooterWeightComboBoxSelected(self, value):
+        if value  == 0:
+            self.theme.font_footer_weight = u'Normal'
+            self.theme.font_footer_italics = False
+        elif value  == 1:
+            self.theme.font_footer_weight = u'Bold'
+            self.theme.font_footer_italics = False
+        elif value  == 2:
+            self.theme.font_footer_weight = u'Normal'
+            self.theme.font_footer_italics = True
+        else:
+            self.theme.font_footer_weight = u'Bold'
+            self.theme.font_footer_italics = True
+        self.previewTheme(self.theme)
+
+    def onFontFooterColorPushButtonClicked(self):
+        self.theme.font_footer_color = QtGui.QColorDialog.getColor(
+            QtGui.QColor(self.theme.font_footer_color), self).name()
+
+        self.FontFooterColorPushButton.setStyleSheet(
+            'background-color: %s' % unicode(self.theme.font_footer_color))
+        self.previewTheme(self.theme)
+
+    def onFontFooterSizeSpinBoxChanged(self):
+        if self.theme.font_footer_proportion != \
+            self.FontFooterSizeSpinBox.value():
+            self.theme.font_footer_proportion = \
+                self.FontFooterSizeSpinBox.value()
+            self.previewTheme(self.theme)
+
+    def onFontFooterDefaultCheckBoxChanged(self, value):
+        if value == 2:  # checked
+            self.theme.font_footer_override = False
+        else:
+            self.theme.font_footer_override = True
+
+        if int(self.theme.font_footer_x) == 0 and \
+            int(self.theme.font_footer_y) == 0 and \
+            int(self.theme.font_footer_width) == 0 and \
+            int(self.theme.font_footer_height) == 0:
+            self.theme.font_footer_x = u'10'
+            self.theme.font_footer_y = u'730'
+            self.theme.font_footer_width = u'1024'
+            self.theme.font_footer_height = u'38'
+
+            self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))
+            self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))
+            self.FontFooterWidthSpinBox.setValue(int(
+                self.theme.font_footer_width))
+            self.FontFooterHeightSpinBox.setValue(int(
+                self.theme.font_footer_height))
+
+        self.stateChanging(self.theme)
+        self.previewTheme(self.theme)
+
+    def onFontFooterXSpinBoxChanged(self):
+        if self.theme.font_footer_x != self.FontFooterXSpinBox.value():
+            self.theme.font_footer_x = self.FontFooterXSpinBox.value()
+            self.previewTheme(self.theme)
+
+    def onFontFooterYSpinBoxChanged(self):
+        if self.theme.font_footer_y != self.FontFooterYSpinBox.value():
+            self.theme.font_footer_y = self.FontFooterYSpinBox.value()
+            self.previewTheme(self.theme)
+
+    def onFontFooterWidthSpinBoxChanged(self):
+        if self.theme.font_footer_width != self.FontFooterWidthSpinBox.value():
+            self.theme.font_footer_width = self.FontFooterWidthSpinBox.value()
+            self.previewTheme(self.theme)
+
+    def onFontFooterHeightSpinBoxChanged(self):
+        if self.theme.font_footer_height != \
+            self.FontFooterHeightSpinBox.value():
+            self.theme.font_footer_height = self.FontFooterHeightSpinBox.value()
+            self.previewTheme(self.theme)
+    #
+    #Background Tab
+    #
+    def onGradientComboBoxSelected(self, currentIndex):
+        self.setBackground(self.BackgroundTypeComboBox.currentIndex(),
+            currentIndex)
+
+    def onBackgroundComboBoxSelected(self, currentIndex):
+        if currentIndex == 0: # Opaque
+            self.theme.background_mode = u'opaque'
+        else:
+            self.theme.background_mode = u'transparent'
+        self.stateChanging(self.theme)
+        self.previewTheme(self.theme)
+
+    def onBackgroundTypeComboBoxSelected(self, currentIndex):
+        self.setBackground(currentIndex, self.GradientComboBox.currentIndex())
+
+    def setBackground(self, background, gradient):
+        if background == 0: # Solid
+            self.theme.background_type = u'solid'
+            if self.theme.background_color is None :
+                self.theme.background_color = u'#000000'
+        elif background == 1: # Gradient
+            self.theme.background_type = u'gradient'
+            if gradient == 0: # Horizontal
+                self.theme.background_direction = u'horizontal'
+            elif gradient == 1: # vertical
+                self.theme.background_direction = u'vertical'
+            else:
+                self.theme.background_direction = u'circular'
+            if self.theme.background_startColor is None :
+                self.theme.background_startColor = u'#000000'
+            if self.theme.background_endColor is None :
+                self.theme.background_endColor = u'#ff0000'
+        else:
+            self.theme.background_type = u'image'
+        self.stateChanging(self.theme)
+        self.previewTheme(self.theme)
+
+    def onColor1PushButtonClicked(self):
+        if self.theme.background_type == u'solid':
+            self.theme.background_color = QtGui.QColorDialog.getColor(
+                QtGui.QColor(self.theme.background_color), self).name()
+            self.Color1PushButton.setStyleSheet(
+                u'background-color: %s' % unicode(self.theme.background_color))
+        else:
+            self.theme.background_startColor = QtGui.QColorDialog.getColor(
+                QtGui.QColor(self.theme.background_startColor), self).name()
+            self.Color1PushButton.setStyleSheet(
+                u'background-color: %s' % \
+                    unicode(self.theme.background_startColor))
+
+        self.previewTheme(self.theme)
+
+    def onColor2PushButtonClicked(self):
+        self.theme.background_endColor = QtGui.QColorDialog.getColor(
+            QtGui.QColor(self.theme.background_endColor), self).name()
+        self.Color2PushButton.setStyleSheet(
+            u'background-color: %s' % unicode(self.theme.background_endColor))
+
+        self.previewTheme(self.theme)
+    #
+    #Other Tab
+    #
+    def onOutlineCheckBoxChanged(self, value):
+        if value == 2:  # checked
+            self.theme.display_outline = True
+        else:
+            self.theme.display_outline = False
+        self.stateChanging(self.theme)
+        self.previewTheme(self.theme)
+
+    def onOutlineColorPushButtonClicked(self):
+        self.theme.display_outline_color = QtGui.QColorDialog.getColor(
+            QtGui.QColor(self.theme.display_outline_color), self).name()
+        self.OutlineColorPushButton.setStyleSheet(
+            u'background-color: %s' % unicode(self.theme.display_outline_color))
+        self.previewTheme(self.theme)
+
+    def onShadowCheckBoxChanged(self, value):
+        if value == 2:  # checked
+            self.theme.display_shadow = True
+        else:
+            self.theme.display_shadow = False
+        self.stateChanging(self.theme)
+        self.previewTheme(self.theme)
+
+    def onShadowColorPushButtonClicked(self):
+        self.theme.display_shadow_color = QtGui.QColorDialog.getColor(
+            QtGui.QColor(self.theme.display_shadow_color), self).name()
+        self.ShadowColorPushButton.setStyleSheet(
+            u'background-color: %s' % unicode(self.theme.display_shadow_color))
+        self.previewTheme(self.theme)
+
+    def onHorizontalComboBoxSelected(self, currentIndex):
+        self.theme.display_horizontalAlign = currentIndex
+        self.stateChanging(self.theme)
+        self.previewTheme(self.theme)
+
+    def onVerticalComboBoxSelected(self, currentIndex):
+        self.theme.display_verticalAlign = currentIndex
+        self.stateChanging(self.theme)
+        self.previewTheme(self.theme)
+    #
+    #Local Methods
+    #
+    def baseTheme(self):
+        log.debug(u'base theme created')
+        newtheme = ThemeXML()
+        newtheme.new_document(u'New Theme')
+        newtheme.add_background_solid(unicode(u'#000000'))
+        newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
+            unicode(30), u'False')
+        newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'),
+            unicode(12), u'False', u'footer')
+        newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',
+            unicode(u'#FFFFFF'),
+            unicode(0), unicode(0), unicode(0))
+
+        return newtheme.extract_xml()
+
+    def paintUi(self, theme):
+        self.stateChanging(theme)
+        self.ThemeNameEdit.setText(self.theme.theme_name)
+        if self.theme.background_mode == u'opaque':
+            self.BackgroundComboBox.setCurrentIndex(0)
+        else:
+            self.BackgroundComboBox.setCurrentIndex(1)
+
+        if theme.background_type == u'solid':
+            self.BackgroundTypeComboBox.setCurrentIndex(0)
+        elif theme.background_type == u'gradient':
+            self.BackgroundTypeComboBox.setCurrentIndex(1)
+        else:
+            self.BackgroundTypeComboBox.setCurrentIndex(2)
+
+        if self.theme.background_direction == u'horizontal':
+            self.GradientComboBox.setCurrentIndex(0)
+        elif self.theme.background_direction == u'vertical':
+            self.GradientComboBox.setCurrentIndex(1)
+        else:
+            self.GradientComboBox.setCurrentIndex(2)
+
+        self.FontMainSizeSpinBox.setValue(int(self.theme.font_main_proportion))
+        if not self.theme.font_main_italics and \
+            self.theme.font_main_weight == u'Normal':
+            self.FontMainWeightComboBox.setCurrentIndex(0)
+        elif not self.theme.font_main_italics and \
+            self.theme.font_main_weight == u'Bold':
+            self.FontMainWeightComboBox.setCurrentIndex(1)
+        elif self.theme.font_main_italics and \
+            self.theme.font_main_weight == u'Normal':
+            self.FontMainWeightComboBox.setCurrentIndex(2)
+        else:
+            self.FontMainWeightComboBox.setCurrentIndex(3)
+
+        self.FontMainXSpinBox.setValue(int(self.theme.font_main_x))
+        self.FontMainYSpinBox.setValue(int(self.theme.font_main_y))
+        self.FontMainWidthSpinBox.setValue(int(self.theme.font_main_width))
+        self.FontMainHeightSpinBox.setValue(int(self.theme.font_main_height))
+        self.FontFooterSizeSpinBox.setValue(int(
+            self.theme.font_footer_proportion))
+        if not self.theme.font_footer_italics and \
+            self.theme.font_footer_weight == u'Normal':
+            self.FontFooterWeightComboBox.setCurrentIndex(0)
+        elif not self.theme.font_footer_italics and \
+            self.theme.font_footer_weight == u'Bold':
+            self.FontFooterWeightComboBox.setCurrentIndex(1)
+        elif self.theme.font_footer_italics and \
+            self.theme.font_footer_weight == u'Normal':
+            self.FontFooterWeightComboBox.setCurrentIndex(2)
+        else:
+            self.FontFooterWeightComboBox.setCurrentIndex(3)
+        self.FontFooterXSpinBox.setValue(int(self.theme.font_footer_x))
+        self.FontFooterYSpinBox.setValue(int(self.theme.font_footer_y))
+        self.FontFooterWidthSpinBox.setValue(int(self.theme.font_footer_width))
+        self.FontFooterHeightSpinBox.setValue(int(
+            self.theme.font_footer_height))
+        self.FontMainColorPushButton.setStyleSheet(
+            u'background-color: %s' % unicode(theme.font_main_color))
+        self.FontFooterColorPushButton.setStyleSheet(
+            u'background-color: %s' % unicode(theme.font_footer_color))
+
+        if self.theme.font_main_override == False:
+            self.FontMainDefaultCheckBox.setChecked(True)
+        else:
+            self.FontMainDefaultCheckBox.setChecked(False)
+
+        if self.theme.font_footer_override == False:
+            self.FontFooterDefaultCheckBox.setChecked(True)
+        else:
+            self.FontFooterDefaultCheckBox.setChecked(False)
+
+        self.OutlineColorPushButton.setStyleSheet(
+            u'background-color: %s' % unicode(theme.display_outline_color))
+        self.ShadowColorPushButton.setStyleSheet(
+            u'background-color: %s' % unicode(theme.display_shadow_color))
+
+        if self.theme.display_outline:
+            self.OutlineCheckBox.setChecked(True)
+            self.OutlineColorPushButton.setEnabled(True)
+        else:
+            self.OutlineCheckBox.setChecked(False)
+            self.OutlineColorPushButton.setEnabled(False)
+
+        if self.theme.display_shadow:
+            self.ShadowCheckBox.setChecked(True)
+            self.ShadowColorPushButton.setEnabled(True)
+        else:
+            self.ShadowCheckBox.setChecked(False)
+            self.ShadowColorPushButton.setEnabled(False)
+
+        self.HorizontalComboBox.setCurrentIndex(int(
+            self.theme.display_horizontalAlign))
+        self.VerticalComboBox.setCurrentIndex(int(
+            self.theme.display_verticalAlign))
+
+    def stateChanging(self, theme):
+        if theme.background_mode == u'transparent':
+                self.Color1Label.setVisible(False)
+                self.Color1PushButton.setVisible(False)
+                self.Color2Label.setVisible(False)
+                self.Color2PushButton.setVisible(False)
+                self.ImageLabel.setVisible(False)
+                self.ImageLineEdit.setVisible(False)
+                self.ImageFilenameWidget.setVisible(False)
+                self.GradientLabel.setVisible(False)
+                self.GradientComboBox.setVisible(False)
+                self.BackgroundTypeComboBox.setVisible(False)
+                self.BackgroundTypeLabel.setVisible(False)
+        else:
+            self.BackgroundTypeComboBox.setVisible(True)
+            self.BackgroundTypeLabel.setVisible(True)
+            if theme.background_type == u'solid':
+                self.Color1PushButton.setStyleSheet(
+                    u'background-color: %s' % unicode(theme.background_color))
+                self.Color1Label.setText(translate(u'ThemeManager',
+                    u'Background Color:'))
+                self.Color1Label.setVisible(True)
+                self.Color1PushButton.setVisible(True)
+                self.Color2Label.setVisible(False)
+                self.Color2PushButton.setVisible(False)
+                self.ImageLabel.setVisible(False)
+                self.ImageLineEdit.setVisible(False)
+                self.ImageFilenameWidget.setVisible(False)
+                self.GradientLabel.setVisible(False)
+                self.GradientComboBox.setVisible(False)
+            elif theme.background_type == u'gradient':
+                self.Color1PushButton.setStyleSheet(u'background-color: %s' \
+                    % unicode(theme.background_startColor))
+                self.Color2PushButton.setStyleSheet(u'background-color: %s' \
+                    % unicode(theme.background_endColor))
+                self.Color1Label.setText(translate(u'ThemeManager',
+                    u'First  Color:'))
+                self.Color2Label.setText(translate(u'ThemeManager',
+                    u'Second Color:'))
+                self.Color1Label.setVisible(True)
+                self.Color1PushButton.setVisible(True)
+                self.Color2Label.setVisible(True)
+                self.Color2PushButton.setVisible(True)
+                self.ImageLabel.setVisible(False)
+                self.ImageLineEdit.setVisible(False)
+                self.ImageFilenameWidget.setVisible(False)
+                self.GradientLabel.setVisible(True)
+                self.GradientComboBox.setVisible(True)
+            else: # must be image
+                self.Color1Label.setVisible(False)
+                self.Color1PushButton.setVisible(False)
+                self.Color2Label.setVisible(False)
+                self.Color2PushButton.setVisible(False)
+                self.ImageLabel.setVisible(True)
+                self.ImageLineEdit.setVisible(True)
+                self.ImageFilenameWidget.setVisible(True)
+                self.GradientLabel.setVisible(False)
+                self.GradientComboBox.setVisible(False)
+
+        if theme.font_main_override == False:
+            self.FontMainXSpinBox.setEnabled(False)
+            self.FontMainYSpinBox.setEnabled(False)
+            self.FontMainWidthSpinBox.setEnabled(False)
+            self.FontMainHeightSpinBox.setEnabled(False)
+        else:
+            self.FontMainXSpinBox.setEnabled(True)
+            self.FontMainYSpinBox.setEnabled(True)
+            self.FontMainWidthSpinBox.setEnabled(True)
+            self.FontMainHeightSpinBox.setEnabled(True)
+
+        if theme.font_footer_override == False:
+            self.FontFooterXSpinBox.setEnabled(False)
+            self.FontFooterYSpinBox.setEnabled(False)
+            self.FontFooterWidthSpinBox.setEnabled(False)
+            self.FontFooterHeightSpinBox.setEnabled(False)
+        else:
+            self.FontFooterXSpinBox.setEnabled(True)
+            self.FontFooterYSpinBox.setEnabled(True)
+            self.FontFooterWidthSpinBox.setEnabled(True)
+            self.FontFooterHeightSpinBox.setEnabled(True)
+
+        if self.theme.display_outline:
+            self.OutlineColorPushButton.setEnabled(True)
+        else:
+            self.OutlineColorPushButton.setEnabled(False)
+
+        if self.theme.display_shadow:
+            self.ShadowColorPushButton.setEnabled(True)
+        else:
+            self.ShadowColorPushButton.setEnabled(False)
+
+    def previewTheme(self, theme):
+        if self.allowPreview:
+            frame = self.thememanager.generateImage(theme)
+            self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame))

=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py	2009-09-01 19:39:49 +0000
+++ openlp/core/ui/mainwindow.py	2009-09-06 23:11:08 +0000
@@ -26,16 +26,19 @@
     ServiceManager, ThemeManager, MainDisplay, SlideController,  \
     PluginForm
 from openlp.core.lib import translate, Plugin, MediaManagerItem, \
-    SettingsTab, RenderManager, PluginConfig, \
+    SettingsTab, RenderManager, PluginConfig, str_to_bool, \
     SettingsManager, PluginManager, Receiver
 
+from openlp.core.utils import ConfigHelper
+
 class Ui_MainWindow(object):
     def setupUi(self, MainWindow):
         """
         Set up the user interface
         """
         MainWindow.setObjectName(u'MainWindow')
-        MainWindow.resize(self.settingsmanager.width, self.settingsmanager.height)
+        MainWindow.resize(self.settingsmanager.width,
+            self.settingsmanager.height)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
             QtGui.QSizePolicy.Expanding)
         sizePolicy.setHorizontalStretch(0)
@@ -149,15 +152,18 @@
         # Create the menu items
         self.FileNewItem = QtGui.QAction(MainWindow)
         self.FileNewItem.setIcon(
-            self.ServiceManagerContents.Toolbar.getIconFromTitle(u'New Service'))
+            self.ServiceManagerContents.Toolbar.getIconFromTitle(
+            u'New Service'))
         self.FileNewItem.setObjectName(u'FileNewItem')
         self.FileOpenItem = QtGui.QAction(MainWindow)
         self.FileOpenItem.setIcon(
-            self.ServiceManagerContents.Toolbar.getIconFromTitle(u'Open Service'))
+            self.ServiceManagerContents.Toolbar.getIconFromTitle(
+            u'Open Service'))
         self.FileOpenItem.setObjectName(u'FileOpenItem')
         self.FileSaveItem = QtGui.QAction(MainWindow)
         self.FileSaveItem.setIcon(
-            self.ServiceManagerContents.Toolbar.getIconFromTitle(u'Save Service'))
+            self.ServiceManagerContents.Toolbar.getIconFromTitle(
+            u'Save Service'))
         self.FileSaveItem.setObjectName(u'FileSaveItem')
         self.FileSaveAsItem = QtGui.QAction(MainWindow)
         self.FileSaveAsItem.setObjectName(u'FileSaveAsItem')
@@ -212,7 +218,8 @@
         self.PluginItem.setObjectName(u'PluginItem')
         self.HelpDocumentationItem = QtGui.QAction(MainWindow)
         ContentsIcon = QtGui.QIcon()
-        ContentsIcon.addPixmap(QtGui.QPixmap(u':/system/system_help_contents.png'),
+        ContentsIcon.addPixmap(QtGui.QPixmap(
+            u':/system/system_help_contents.png'),
             QtGui.QIcon.Normal, QtGui.QIcon.Off)
         self.HelpDocumentationItem.setIcon(ContentsIcon)
         self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem')
@@ -296,7 +303,8 @@
         Set up the translation system
         """
         MainWindow.mainTitle = translate(u'mainWindow', u'OpenLP 2.0')
-        MainWindow.defaultThemeText = translate(u'mainWindow', 'Default Theme: ')
+        MainWindow.defaultThemeText = translate(u'mainWindow',
+            'Default Theme: ')
         MainWindow.setWindowTitle(MainWindow.mainTitle)
         self.FileMenu.setTitle(translate(u'mainWindow', u'&File'))
         self.FileImportMenu.setTitle(translate(u'mainWindow', u'&Import'))
@@ -304,7 +312,8 @@
         self.OptionsMenu.setTitle(translate(u'mainWindow', u'&Options'))
         self.OptionsViewMenu.setTitle(translate(u'mainWindow', u'&View'))
         self.ViewModeMenu.setTitle(translate(u'mainWindow', u'M&ode'))
-        self.OptionsLanguageMenu.setTitle(translate(u'mainWindow', u'&Language'))
+        self.OptionsLanguageMenu.setTitle(translate(u'mainWindow',
+            u'&Language'))
         self.ToolsMenu.setTitle(translate(u'mainWindow', u'&Tools'))
         self.HelpMenu.setTitle(translate(u'mainWindow', u'&Help'))
         self.MediaManagerDock.setWindowTitle(
@@ -364,6 +373,13 @@
         self.ViewServiceManagerItem.setStatusTip(translate(u'mainWindow',
             u'Toggle the visibility of the Service Manager'))
         self.ViewServiceManagerItem.setShortcut(translate(u'mainWindow', u'F9'))
+        self.action_Preview_Panel.setText(
+            translate(u'mainWindow', u'&Preview Panel'))
+        self.action_Preview_Panel.setToolTip(
+            translate(u'mainWindow', u'Toggle Preview Panel'))
+        self.action_Preview_Panel.setStatusTip(translate(u'mainWindow',
+            u'Toggle the visibility of the Preview Panel'))
+        self.action_Preview_Panel.setShortcut(translate(u'mainWindow', u'F11'))
         self.ToolsAlertItem.setText(translate(u'mainWindow', u'&Alert'))
         self.ToolsAlertItem.setStatusTip(
             translate(u'mainWindow', u'Show an alert message'))
@@ -430,23 +446,32 @@
         self.setupUi(self)
         # Set up signals and slots
         QtCore.QObject.connect(self.ImportThemeItem,
-            QtCore.SIGNAL(u'triggered()'), self.ThemeManagerContents.onImportTheme)
+            QtCore.SIGNAL(u'triggered()'),
+            self.ThemeManagerContents.onImportTheme)
         QtCore.QObject.connect(self.ExportThemeItem,
-            QtCore.SIGNAL(u'triggered()'), self.ThemeManagerContents.onExportTheme)
+            QtCore.SIGNAL(u'triggered()'),
+            self.ThemeManagerContents.onExportTheme)
         QtCore.QObject.connect(self.ViewMediaManagerItem,
-            QtCore.SIGNAL(u'triggered(bool)'), self.MediaManagerDock.setVisible)
+            QtCore.SIGNAL(u'triggered(bool)'),
+            self.MediaManagerDock.setVisible)
         QtCore.QObject.connect(self.ViewServiceManagerItem,
-            QtCore.SIGNAL(u'triggered(bool)'), self.ServiceManagerDock.setVisible)
+            QtCore.SIGNAL(u'triggered(bool)'),
+            self.ServiceManagerDock.setVisible)
         QtCore.QObject.connect(self.ViewThemeManagerItem,
-            QtCore.SIGNAL(u'triggered(bool)'), self.ThemeManagerDock.setVisible)
+            QtCore.SIGNAL(u'triggered(bool)'),
+            self.ThemeManagerDock.setVisible)
         QtCore.QObject.connect(self.action_Preview_Panel,
-            QtCore.SIGNAL(u'toggled(bool)'), self.PreviewController.Panel.setVisible)
+            QtCore.SIGNAL(u'toggled(bool)'),
+            self.PreviewController.Panel.setVisible)
         QtCore.QObject.connect(self.MediaManagerDock,
-            QtCore.SIGNAL(u'visibilityChanged(bool)'), self.ViewMediaManagerItem.setChecked)
+            QtCore.SIGNAL(u'visibilityChanged(bool)'),
+            self.ViewMediaManagerItem.setChecked)
         QtCore.QObject.connect(self.ServiceManagerDock,
-            QtCore.SIGNAL(u'visibilityChanged(bool)'), self.ViewServiceManagerItem.setChecked)
+            QtCore.SIGNAL(u'visibilityChanged(bool)'),
+            self.ViewServiceManagerItem.setChecked)
         QtCore.QObject.connect(self.ThemeManagerDock,
-            QtCore.SIGNAL(u'visibilityChanged(bool)'), self.ViewThemeManagerItem.setChecked)
+            QtCore.SIGNAL(u'visibilityChanged(bool)'),
+            self.ViewThemeManagerItem.setChecked)
         QtCore.QObject.connect(self.HelpAboutItem,
             QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked)
         QtCore.QObject.connect(self.ToolsAlertItem,
@@ -472,7 +497,6 @@
         self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers)
         # hook methods have to happen after find_plugins. Find plugins needs the
         # controllers hence the hooks have moved from setupUI() to here
-
         # Find and insert settings tabs
         log.info(u'hook settings')
         self.plugin_manager.hook_settings_tabs(self.settingsForm)
@@ -492,6 +516,8 @@
         self.ThemeManagerContents.loadThemes()
         log.info(u'Load data from Settings')
         self.settingsForm.postSetUp()
+        # Load saved UI settings
+        self.loadUi()
 
     def getMonitorNumber(self):
         """
@@ -555,21 +581,27 @@
             ret = QtGui.QMessageBox.question(None,
                 translate(u'mainWindow', u'Save Changes to Service?'),
                 translate(u'mainWindow', u'Your service has been changed, do you want to save those changes?'),
-                QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Save),
+                QtGui.QMessageBox.StandardButtons(
+                    QtGui.QMessageBox.Cancel | \
+                    QtGui.QMessageBox.Discard | \
+                    QtGui.QMessageBox.Save),
                 QtGui.QMessageBox.Save)
             if ret == QtGui.QMessageBox.Save:
                 self.ServiceManagerContents.onSaveService()
                 self.mainDisplay.close()
+                self.saveUi()
                 self.cleanUp()
                 event.accept()
             elif ret == QtGui.QMessageBox.Discard:
                 self.mainDisplay.close()
+                self.saveUi()
                 self.cleanUp()
                 event.accept()
             else:
                 event.ignore()
         else:
             self.mainDisplay.close()
+            self.saveUi()
             self.cleanUp()
             event.accept()
 
@@ -578,6 +610,30 @@
         log.info(u'cleanup plugins')
         self.plugin_manager.finalise_plugins()
 
+    def loadUi(self):
+        # Loads UI settings from openlp.conf
+        log.info(u'Load UI settings')
+        self.MediaManagerDock.setVisible(str_to_bool(
+            ConfigHelper.get_config(u'ui', u'display mediamanager', True)))
+        self.ServiceManagerDock.setVisible(str_to_bool(
+            ConfigHelper.get_config(u'ui', u'display servicemanager', True)))
+        self.ThemeManagerDock.setVisible(str_to_bool(
+            ConfigHelper.get_config(u'ui', u'display thememanager', True)))
+        self.action_Preview_Panel.setChecked(str_to_bool(
+            ConfigHelper.get_config(u'ui', u'display previewpanel', True)))
+
+    def saveUi(self):
+        # Saves UI settings to openlp.conf
+        log.info(u'Save UI settings')
+        ConfigHelper.set_config(u'ui', u'display mediamanager',
+            self.MediaManagerDock.isVisible())
+        ConfigHelper.set_config(u'ui', u'display servicemanager',
+            self.ServiceManagerDock.isVisible())
+        ConfigHelper.set_config(u'ui', u'display thememanager',
+            self.ThemeManagerDock.isVisible())
+        ConfigHelper.set_config(u'ui', u'display previewpanel',
+            self.PreviewController.Panel.isVisible())
+
     def OosChanged(self, reset=False, oosName=None):
         """
         Hook to change the title if the OOS has been changed

=== modified file 'openlp/core/ui/test/test_service_manager.py'
--- openlp/core/ui/test/test_service_manager.py	2009-09-03 15:19:30 +0000
+++ openlp/core/ui/test/test_service_manager.py	2009-09-06 13:57:32 +0000
@@ -136,7 +136,8 @@
     #  new and save as
     #  deleting items
 
-if __name__=="__main__":
+
+if __name__ == "__main__":
 
     t=TestServiceManager_base()
     t.setup_class()

=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py	2009-09-04 22:27:53 +0000
+++ openlp/core/ui/thememanager.py	2009-09-07 02:17:36 +0000
@@ -1,380 +1,443 @@
-# -*- coding: utf-8 -*-
-# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
-"""
-OpenLP - Open Source Lyrics Projection
-Copyright (c) 2009 Raoul Snyman
-Portions copyright (c) 2009 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 sys
-import zipfile
-import shutil
-import logging
-
-from xml.etree.ElementTree import ElementTree, XML
-from PyQt4 import QtCore, QtGui
-
-from openlp.core.ui import AmendThemeForm, ServiceManager
-from openlp.core.theme import Theme
-from openlp.core.lib import PluginConfig,  \
-    OpenLPToolbar, ThemeXML, Renderer, translate, \
-    file_to_xml, buildIcon,  Receiver
-from openlp.core.utils import ConfigHelper
-
-class ThemeManager(QtGui.QWidget):
-    """
-    Manages the orders of Theme.
-    """
-    global log
-    log = logging.getLogger(u'ThemeManager')
-
-    def __init__(self, parent):
-        QtGui.QWidget.__init__(self, parent)
-        self.parent = parent
-        self.Layout = QtGui.QVBoxLayout(self)
-        self.Layout.setSpacing(0)
-        self.Layout.setMargin(0)
-        self.amendThemeForm = AmendThemeForm(self)
-        self.Toolbar = OpenLPToolbar(self)
-        self.Toolbar.addToolbarButton(
-            translate(u'ThemeManager', u'New Theme'), u':/themes/theme_new.png',
-            translate(u'ThemeManager', u'Create a new theme'), self.onAddTheme)
-        self.Toolbar.addToolbarButton(
-            translate(u'ThemeManager', u'Edit Theme'), u':/themes/theme_edit.png',
-            translate(u'ThemeManager', u'Edit a theme'), self.onEditTheme)
-        self.Toolbar.addToolbarButton(
-            translate(u'ThemeManager', u'Delete Theme'), u':/themes/theme_delete.png',
-            translate(u'ThemeManager', u'Delete a theme'), self.onDeleteTheme)
-        self.Toolbar.addSeparator()
-        self.Toolbar.addToolbarButton(
-            translate(u'ThemeManager', u'Import Theme'), u':/themes/theme_import.png',
-            translate(u'ThemeManager', u'Import a theme'), self.onImportTheme)
-        self.Toolbar.addToolbarButton(
-            translate(u'ThemeManager', u'Export Theme'), u':/themes/theme_export.png',
-            translate(u'ThemeManager', u'Export a theme'), self.onExportTheme)
-        self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
-        self.Layout.addWidget(self.Toolbar)
-        self.ThemeListWidget = QtGui.QListWidget(self)
-        self.ThemeListWidget.setAlternatingRowColors(True)
-        self.ThemeListWidget.setIconSize(QtCore.QSize(88,50))
-        self.Layout.addWidget(self.ThemeListWidget)
-        #Signals
-        QtCore.QObject.connect(self.ThemeListWidget,
-           QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.changeGlobalFromScreen)
-        QtCore.QObject.connect(Receiver.get_receiver(),
-            QtCore.SIGNAL(u'update_global_theme'), self.changeGlobalFromTab)
-        #Variables
-        self.themelist = []
-        self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')
-        self.checkThemesExists(self.path)
-        self.amendThemeForm.path = self.path
-        # Last little bits of setting up
-        self.config = PluginConfig(u'themes')
-        self.servicePath = self.config.get_data_path()
-        self.global_theme = unicode(self.config.get_config(u'theme global theme', u''))
-
-    def changeGlobalFromTab(self, themeName):
-        log.debug(u'changeGlobalFromTab %s', themeName)
-        for count in range (0,  self.ThemeListWidget.count()):
-            #reset the old name
-            item = self.ThemeListWidget.item(count)
-            oldName =  item.text()
-            newName = unicode(item.data(QtCore.Qt.UserRole).toString())
-            if oldName != newName:
-                self.ThemeListWidget.item(count).setText(newName)
-            #Set the new name
-            if themeName  == newName:
-                name = u'%s (%s)' % (newName, translate(u'ThemeManager', u'default'))
-                self.ThemeListWidget.item(count).setText(name)
-
-    def changeGlobalFromScreen(self, index):
-        log.debug(u'changeGlobalFromScreen %s', index)
-        for count in range (0,  self.ThemeListWidget.count()):
-            item = self.ThemeListWidget.item(count)
-            oldName =  item.text()
-            #reset the old name
-            if oldName != unicode(item.data(QtCore.Qt.UserRole).toString()):
-                self.ThemeListWidget.item(count).setText(unicode(item.data(QtCore.Qt.UserRole).toString()))
-            #Set the new name
-            if count  == index.row():
-                self.global_theme = unicode(self.ThemeListWidget.item(count).text())
-                name = u'%s (%s)' % (self.global_theme, translate(u'ThemeManager', u'default'))
-                self.ThemeListWidget.item(count).setText(name)
-                self.config.set_config(u'theme global theme', self.global_theme)
-                Receiver().send_message(u'update_global_theme',  self.global_theme )
-                self.pushThemes()
-
-    def onAddTheme(self):
-        self.amendThemeForm.loadTheme(None)
-        self.amendThemeForm.exec_()
-
-    def onEditTheme(self):
-        item = self.ThemeListWidget.currentItem()
-        if item is not None:
-            self.amendThemeForm.loadTheme(unicode(item.data(QtCore.Qt.UserRole).toString()))
-            self.amendThemeForm.exec_()
-
-    def onDeleteTheme(self):
-        self.global_theme = unicode(self.config.get_config(u'theme global theme', u''))
-        item = self.ThemeListWidget.currentItem()
-        if item is not None:
-            theme = unicode(item.text())
-            # should be the same unless default
-            if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
-                QtGui.QMessageBox.critical(self,
-                    translate(u'ThemeManager', u'Error'),
-                    translate(u'ThemeManager', u'You are unable to delete the default theme!'),
-                    QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
-            else:
-                self.themelist.remove(theme)
-                th = theme +  u'.png'
-                row = self.ThemeListWidget.row(item)
-                self.ThemeListWidget.takeItem(row)
-                try:
-                    os.remove(os.path.join(self.path, th))
-                except:
-                    #if not present do not worry
-                    pass
-                try:
-                    shutil.rmtree(os.path.join(self.path, theme))
-                except:
-                    #if not present do not worry
-                    pass
-                #As we do not reload the themes push out the change
-                #Reaload the list as the internal lists and events need to be triggered
-                self.pushThemes()
-
-    def onExportTheme(self):
-        pass
-
-    def onImportTheme(self):
-        files = QtGui.QFileDialog.getOpenFileNames(None,
-            translate(u'ThemeManager', u'Select Theme Import File'),
-            self.path, u'Theme (*.*)')
-        log.info(u'New Themes %s', unicode(files))
-        if len(files) > 0:
-            for file in files:
-                self.unzipTheme(file, self.path)
-        self.loadThemes()
-
-    def loadThemes(self):
-        """
-        Loads the theme lists and triggers updates accross
-        the whole system using direct calls or core functions
-        and events for the plugins.
-        The plugins will call back in to get the real list if they want it.
-        """
-        log.debug(u'Load themes from dir')
-        self.themelist = []
-        self.ThemeListWidget.clear()
-        for root, dirs, files in os.walk(self.path):
-            for name in files:
-                if name.endswith(u'.png'):
-                    #check to see file is in theme root directory
-                    theme =  os.path.join(self.path, name)
-                    if os.path.exists(theme):
-                        (path, filename) = os.path.split(unicode(file))
-                        textName = os.path.splitext(name)[0]
-                        if textName == self.global_theme:
-                            name = u'%s (%s)' % (textName, translate(u'ThemeManager', u'default'))
-                        else:
-                            name = textName
-                        item_name = QtGui.QListWidgetItem(name)
-                        item_name.setIcon(buildIcon(theme))
-                        item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(textName))
-                        self.ThemeListWidget.addItem(item_name)
-                        self.themelist.append(textName)
-        self.pushThemes()
-
-    def pushThemes(self):
-        Receiver().send_message(u'update_themes',  self.getThemes() )
-
-    def getThemes(self):
-        return self.themelist
-
-    def getThemeData(self, themename):
-        log.debug(u'getthemedata for theme %s', themename)
-        xml_file = os.path.join(self.path, unicode(themename), unicode(themename) + u'.xml')
-        try:
-            xml = file_to_xml(xml_file)
-        except:
-            newtheme = ThemeXML()
-            newtheme.new_document(u'New Theme')
-            newtheme.add_background_solid(unicode(u'#000000'))
-            newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'), unicode(30), u'False')
-            newtheme.add_font(unicode(QtGui.QFont().family()), unicode(u'#FFFFFF'), unicode(12), u'False', u'footer')
-            newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False', unicode(u'#FFFFFF'),
-                unicode(0), unicode(0), unicode(0))
-            xml = newtheme.extract_xml()
-        theme = ThemeXML()
-        theme.parse(xml)
-        theme.extend_image_filename(self.path)
-        return theme
-
-    def checkThemesExists(self, dir):
-        log.debug(u'check themes')
-        if os.path.exists(dir) == False:
-            os.mkdir(dir)
-
-    def unzipTheme(self, filename, dir):
-        """
-        Unzip the theme, remove the preview file if stored
-        Generate a new preview fileCheck the XML theme version and upgrade if
-        necessary.
-        """
-        log.debug(u'Unzipping theme %s', filename)
-        zip = zipfile.ZipFile(unicode(filename))
-        filexml = None
-        themename = None
-        for file in zip.namelist():
-            if file.endswith(os.path.sep):
-                theme_dir = os.path.join(dir, file)
-                if os.path.exists(theme_dir) == False:
-                    os.mkdir(os.path.join(dir, file))
-            else:
-                fullpath = os.path.join(dir, file)
-                names = file.split(os.path.sep)
-                if len(names) > 1:
-                    # not preview file
-                    if themename is None:
-                        themename = names[0]
-                    xml_data = zip.read(file)
-                    if os.path.splitext(file)[1].lower() in [u'.xml']:
-                        if self.checkVersion1(xml_data):
-                            # upgrade theme xml
-                            filexml = self.migrateVersion122(filename, fullpath, xml_data)
-                        else:
-                            filexml = xml_data
-                        outfile = open(fullpath, u'w')
-                        outfile.write(filexml)
-                        outfile.close()
-                    else:
-                        outfile = open(fullpath, u'w')
-                        outfile.write(zip.read(file))
-                        outfile.close()
-        self.generateAndSaveImage(dir, themename, filexml)
-
-    def checkVersion1(self, xmlfile):
-        """
-        Am I a version 1 theme
-        """
-        log.debug(u'checkVersion1 ')
-        theme = xmlfile
-        tree = ElementTree(element=XML(theme)).getroot()
-        if tree.find(u'BackgroundType') is None:
-            return False
-        else:
-            return True
-
-    def migrateVersion122(self, filename, fullpath, xml_data):
-        """
-        Called by convert the xml data from version 1 format
-        to the current format.
-        New fields are defaulted but the new theme is useable
-        """
-        log.debug(u'migrateVersion122 %s %s', filename, fullpath)
-        theme = Theme(xml_data)
-        newtheme = ThemeXML()
-        newtheme.new_document(theme.Name)
-        if theme.BackgroundType == 0:
-            newtheme.add_background_solid(unicode(theme.BackgroundParameter1.name()))
-        elif theme.BackgroundType == 1:
-            direction = u'vertical'
-            if theme.BackgroundParameter3.name() == 1:
-                direction = u'horizontal'
-            newtheme.add_background_gradient(
-                unicode(theme.BackgroundParameter1.name()),
-                unicode(theme.BackgroundParameter2.name()), direction)
-        else:
-            newtheme.add_background_image(unicode(theme.BackgroundParameter1))
-
-        newtheme.add_font(unicode(theme.FontName),
-            unicode(theme.FontColor.name()),
-            unicode(theme.FontProportion * 2), u'False')
-        newtheme.add_font(unicode(theme.FontName),
-            unicode(theme.FontColor.name()),
-            unicode(12), u'False', u'footer')
-        outline = False
-        shadow = False
-        if theme.Shadow == 1:
-            shadow = True
-        if theme.Outline == 1:
-            outline = True
-        newtheme.add_display(unicode(shadow), unicode(theme.ShadowColor.name()),
-            unicode(outline), unicode(theme.OutlineColor.name()),
-            unicode(theme.HorizontalAlign), unicode(theme.VerticalAlign),
-            unicode(theme.WrapStyle))
-        return newtheme.extract_xml()
-
-    def saveTheme(self, name, theme_xml, theme_pretty_xml, image_from,
-        image_to) :
-        """
-        Called by thememaintenance Dialog to save the theme
-        and to trigger the reload of the theme list
-        """
-        log.debug(u'saveTheme %s %s', name, theme_xml)
-        theme_dir = os.path.join(self.path, name)
-        if os.path.exists(theme_dir) == False:
-            os.mkdir(os.path.join(self.path, name))
-        theme_file = os.path.join(theme_dir, name + u'.xml')
-        log.debug(theme_file)
- 
-        result = QtGui.QMessageBox.Yes
-        if os.path.exists(theme_file):
-            result = QtGui.QMessageBox.question(
-                self,
-                translate(u'ThemeManager',u'Theme Exists'),
-                translate(u'ThemeManager',u'A theme with this name already exists, would you like to overwrite it?'),
-                (QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
-                QtGui.QMessageBox.No)
-        if result == QtGui.QMessageBox.Yes:
-            # Save the theme, overwriting the existing theme if necessary.
-            outfile = open(theme_file, u'w')
-            outfile.write(theme_pretty_xml)
-            outfile.close()
-            if image_from is not None and image_from != image_to:
-                shutil.copyfile(image_from, image_to)
-            
-            self.generateAndSaveImage(self.path, name, theme_xml)
-            self.loadThemes()
-        else:
-            # Don't close the dialog - allow the user to change the name of
-            # the theme or to cancel the theme dialog completely.
-            return False
-
-    def generateAndSaveImage(self, dir, name, theme_xml):
-        log.debug(u'generateAndSaveImage %s %s %s', dir, name, theme_xml)
-        theme = ThemeXML()
-        theme.parse(theme_xml)
-        theme.extend_image_filename(dir)
-        frame = self.generateImage(theme)
-        samplepathname = os.path.join(self.path, name + u'.png')
-        if os.path.exists(samplepathname):
-            os.unlink(samplepathname)
-        frame.save(samplepathname, u'png')
-        log.debug(u'Theme image written to %s', samplepathname)
-
-    def generateImage(self, themedata):
-        """
-        Call the RenderManager to build a Sample Image
-        """
-        log.debug(u'generateImage %s ', themedata)
-        frame = self.parent.RenderManager.generate_preview(themedata)
-        return frame
-
-    def getPreviewImage(self, theme):
-        log.debug(u'getPreviewImage %s ', theme)
-        image = os.path.join(self.path, theme + u'.png')
-        return image
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+"""
+OpenLP - Open Source Lyrics Projection
+Copyright (c) 2009 Raoul Snyman
+Portions copyright (c) 2009 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 sys
+import zipfile
+import shutil
+import logging
+
+from xml.etree.ElementTree import ElementTree, XML
+from PyQt4 import QtCore, QtGui
+
+from openlp.core.ui import AmendThemeForm, ServiceManager
+from openlp.core.theme import Theme
+from openlp.core.lib import PluginConfig, OpenLPToolbar, ThemeXML, Renderer, \
+    translate, str_to_bool, file_to_xml, buildIcon,  Receiver
+from openlp.core.utils import ConfigHelper
+
+class ThemeManager(QtGui.QWidget):
+    """
+    Manages the orders of Theme.
+    """
+    global log
+    log = logging.getLogger(u'ThemeManager')
+
+    def __init__(self, parent):
+        QtGui.QWidget.__init__(self, parent)
+        self.parent = parent
+        self.Layout = QtGui.QVBoxLayout(self)
+        self.Layout.setSpacing(0)
+        self.Layout.setMargin(0)
+        self.amendThemeForm = AmendThemeForm(self)
+        self.Toolbar = OpenLPToolbar(self)
+        self.Toolbar.addToolbarButton(
+            translate(u'ThemeManager', u'New Theme'), u':/themes/theme_new.png',
+            translate(u'ThemeManager', u'Create a new theme'), self.onAddTheme)
+        self.Toolbar.addToolbarButton(
+            translate(u'ThemeManager', u'Edit Theme'),
+            u':/themes/theme_edit.png',
+            translate(u'ThemeManager', u'Edit a theme'), self.onEditTheme)
+        self.Toolbar.addToolbarButton(
+            translate(u'ThemeManager', u'Delete Theme'),
+            u':/themes/theme_delete.png',
+            translate(u'ThemeManager', u'Delete a theme'), self.onDeleteTheme)
+        self.Toolbar.addSeparator()
+        self.Toolbar.addToolbarButton(
+            translate(u'ThemeManager', u'Import Theme'),
+            u':/themes/theme_import.png',
+            translate(u'ThemeManager', u'Import a theme'), self.onImportTheme)
+        self.Toolbar.addToolbarButton(
+            translate(u'ThemeManager', u'Export Theme'),
+            u':/themes/theme_export.png',
+            translate(u'ThemeManager', u'Export a theme'), self.onExportTheme)
+        self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
+        self.Layout.addWidget(self.Toolbar)
+        self.ThemeListWidget = QtGui.QListWidget(self)
+        self.ThemeListWidget.setAlternatingRowColors(True)
+        self.ThemeListWidget.setIconSize(QtCore.QSize(88,50))
+        self.Layout.addWidget(self.ThemeListWidget)
+        #Signals
+        QtCore.QObject.connect(self.ThemeListWidget,
+            QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
+            self.changeGlobalFromScreen)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'update_global_theme'), self.changeGlobalFromTab)
+        #Variables
+        self.themelist = []
+        self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')
+        self.checkThemesExists(self.path)
+        self.amendThemeForm.path = self.path
+        # Last little bits of setting up
+        self.config = PluginConfig(u'themes')
+        self.servicePath = self.config.get_data_path()
+        self.global_theme = unicode(
+            self.config.get_config(u'theme global theme', u''))
+
+    def changeGlobalFromTab(self, themeName):
+        log.debug(u'changeGlobalFromTab %s', themeName)
+        for count in range (0,  self.ThemeListWidget.count()):
+            #reset the old name
+            item = self.ThemeListWidget.item(count)
+            oldName =  item.text()
+            newName = unicode(item.data(QtCore.Qt.UserRole).toString())
+            if oldName != newName:
+                self.ThemeListWidget.item(count).setText(newName)
+            #Set the new name
+            if themeName  == newName:
+                name = u'%s (%s)' % (newName, translate(u'ThemeManager',
+                    u'default'))
+                self.ThemeListWidget.item(count).setText(name)
+
+    def changeGlobalFromScreen(self, index):
+        log.debug(u'changeGlobalFromScreen %s', index)
+        for count in range (0,  self.ThemeListWidget.count()):
+            item = self.ThemeListWidget.item(count)
+            oldName =  item.text()
+            #reset the old name
+            if oldName != unicode(item.data(QtCore.Qt.UserRole).toString()):
+                self.ThemeListWidget.item(count).setText(
+                    unicode(item.data(QtCore.Qt.UserRole).toString()))
+            #Set the new name
+            if count  == index.row():
+                self.global_theme = unicode(
+                    self.ThemeListWidget.item(count).text())
+                name = u'%s (%s)' % (self.global_theme,
+                    translate(u'ThemeManager', u'default'))
+                self.ThemeListWidget.item(count).setText(name)
+                self.config.set_config(u'theme global theme', self.global_theme)
+                Receiver().send_message(u'update_global_theme',
+                    self.global_theme)
+                self.pushThemes()
+
+    def onAddTheme(self):
+        self.amendThemeForm.loadTheme(None)
+        self.amendThemeForm.exec_()
+
+    def onEditTheme(self):
+        item = self.ThemeListWidget.currentItem()
+        if item is not None:
+            self.amendThemeForm.loadTheme(
+                unicode(item.data(QtCore.Qt.UserRole).toString()))
+            self.amendThemeForm.exec_()
+
+    def onDeleteTheme(self):
+        self.global_theme = unicode(
+            self.config.get_config(u'theme global theme', u''))
+        item = self.ThemeListWidget.currentItem()
+        if item is not None:
+            theme = unicode(item.text())
+            # should be the same unless default
+            if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
+                QtGui.QMessageBox.critical(self,
+                    translate(u'ThemeManager', u'Error'),
+                    translate(u'ThemeManager',
+                        u'You are unable to delete the default theme!'),
+                    QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
+            else:
+                self.themelist.remove(theme)
+                th = theme +  u'.png'
+                row = self.ThemeListWidget.row(item)
+                self.ThemeListWidget.takeItem(row)
+                try:
+                    os.remove(os.path.join(self.path, th))
+                except:
+                    #if not present do not worry
+                    pass
+                try:
+                    shutil.rmtree(os.path.join(self.path, theme))
+                except:
+                    #if not present do not worry
+                    pass
+                # As we do not reload the themes push out the change
+                # Reaload the list as the internal lists and events need
+                # to be triggered
+                self.pushThemes()
+
+    def onExportTheme(self):
+        pass
+
+    def onImportTheme(self):
+        files = QtGui.QFileDialog.getOpenFileNames(None,
+            translate(u'ThemeManager', u'Select Theme Import File'),
+            self.path, u'Theme (*.*)')
+        log.info(u'New Themes %s', unicode(files))
+        if len(files) > 0:
+            for file in files:
+                self.unzipTheme(file, self.path)
+        self.loadThemes()
+
+    def loadThemes(self):
+        """
+        Loads the theme lists and triggers updates accross
+        the whole system using direct calls or core functions
+        and events for the plugins.
+        The plugins will call back in to get the real list if they want it.
+        """
+        log.debug(u'Load themes from dir')
+        self.themelist = []
+        self.ThemeListWidget.clear()
+        for root, dirs, files in os.walk(self.path):
+            for name in files:
+                if name.endswith(u'.png'):
+                    #check to see file is in theme root directory
+                    theme =  os.path.join(self.path, name)
+                    if os.path.exists(theme):
+                        (path, filename) = os.path.split(unicode(file))
+                        textName = os.path.splitext(name)[0]
+                        if textName == self.global_theme:
+                            name = u'%s (%s)' % (textName,
+                                translate(u'ThemeManager', u'default'))
+                        else:
+                            name = textName
+                        item_name = QtGui.QListWidgetItem(name)
+                        item_name.setIcon(buildIcon(theme))
+                        item_name.setData(QtCore.Qt.UserRole,
+                            QtCore.QVariant(textName))
+                        self.ThemeListWidget.addItem(item_name)
+                        self.themelist.append(textName)
+        self.pushThemes()
+
+    def pushThemes(self):
+        Receiver().send_message(u'update_themes',  self.getThemes() )
+
+    def getThemes(self):
+        return self.themelist
+
+    def getThemeData(self, themename):
+        log.debug(u'getthemedata for theme %s', themename)
+        xml_file = os.path.join(self.path, unicode(themename),
+            unicode(themename) + u'.xml')
+        try:
+            xml = file_to_xml(xml_file)
+        except:
+            newtheme = ThemeXML()
+            newtheme.new_document(u'New Theme')
+            newtheme.add_background_solid(unicode(u'#000000'))
+            newtheme.add_font(unicode(QtGui.QFont().family()),
+                unicode(u'#FFFFFF'), unicode(30), u'False')
+            newtheme.add_font(unicode(QtGui.QFont().family()),
+                unicode(u'#FFFFFF'), unicode(12), u'False', u'footer')
+            newtheme.add_display(u'False', unicode(u'#FFFFFF'), u'False',
+                unicode(u'#FFFFFF'), unicode(0), unicode(0), unicode(0))
+            xml = newtheme.extract_xml()
+        theme = ThemeXML()
+        theme.parse(xml)
+        theme.extend_image_filename(self.path)
+        self.cleanTheme(theme)
+        return theme
+
+    def checkThemesExists(self, dir):
+        log.debug(u'check themes')
+        if os.path.exists(dir) == False:
+            os.mkdir(dir)
+
+    def unzipTheme(self, filename, dir):
+        """
+        Unzip the theme, remove the preview file if stored
+        Generate a new preview fileCheck the XML theme version and upgrade if
+        necessary.
+        """
+        log.debug(u'Unzipping theme %s', filename)
+        zip = zipfile.ZipFile(unicode(filename))
+        filexml = None
+        themename = None
+        for file in zip.namelist():
+            if file.endswith(os.path.sep):
+                theme_dir = os.path.join(dir, file)
+                if os.path.exists(theme_dir) == False:
+                    os.mkdir(os.path.join(dir, file))
+            else:
+                fullpath = os.path.join(dir, file)
+                names = file.split(os.path.sep)
+                if len(names) > 1:
+                    # not preview file
+                    if themename is None:
+                        themename = names[0]
+                    xml_data = zip.read(file)
+                    if os.path.splitext(file)[1].lower() in [u'.xml']:
+                        if self.checkVersion1(xml_data):
+                            # upgrade theme xml
+                            filexml = self.migrateVersion122(filename,
+                                fullpath, xml_data)
+                        else:
+                            filexml = xml_data
+                        outfile = open(fullpath, u'w')
+                        outfile.write(filexml)
+                        outfile.close()
+                    else:
+                        outfile = open(fullpath, u'w')
+                        outfile.write(zip.read(file))
+                        outfile.close()
+        self.generateAndSaveImage(dir, themename, filexml)
+
+    def checkVersion1(self, xmlfile):
+        """
+        Am I a version 1 theme
+        """
+        log.debug(u'checkVersion1 ')
+        theme = xmlfile
+        tree = ElementTree(element=XML(theme)).getroot()
+        if tree.find(u'BackgroundType') is None:
+            return False
+        else:
+            return True
+
+    def migrateVersion122(self, filename, fullpath, xml_data):
+        """
+        Called by convert the xml data from version 1 format
+        to the current format.
+        New fields are defaulted but the new theme is useable
+        """
+        log.debug(u'migrateVersion122 %s %s', filename, fullpath)
+        theme = Theme(xml_data)
+        newtheme = ThemeXML()
+        newtheme.new_document(theme.Name)
+        if theme.BackgroundType == 0:
+            newtheme.add_background_solid(unicode(
+                theme.BackgroundParameter1.name()))
+        elif theme.BackgroundType == 1:
+            direction = u'vertical'
+            if theme.BackgroundParameter3.name() == 1:
+                direction = u'horizontal'
+            newtheme.add_background_gradient(
+                unicode(theme.BackgroundParameter1.name()),
+                unicode(theme.BackgroundParameter2.name()), direction)
+        else:
+            newtheme.add_background_image(unicode(theme.BackgroundParameter1))
+
+        newtheme.add_font(unicode(theme.FontName),
+            unicode(theme.FontColor.name()),
+            unicode(theme.FontProportion * 2), u'False')
+        newtheme.add_font(unicode(theme.FontName),
+            unicode(theme.FontColor.name()),
+            unicode(12), u'False', u'footer')
+        outline = False
+        shadow = False
+        if theme.Shadow == 1:
+            shadow = True
+        if theme.Outline == 1:
+            outline = True
+        newtheme.add_display(unicode(shadow), unicode(theme.ShadowColor.name()),
+            unicode(outline), unicode(theme.OutlineColor.name()),
+            unicode(theme.HorizontalAlign), unicode(theme.VerticalAlign),
+            unicode(theme.WrapStyle))
+        return newtheme.extract_xml()
+
+    def saveTheme(self, name, theme_xml, theme_pretty_xml, image_from,
+        image_to) :
+        """
+        Called by thememaintenance Dialog to save the theme
+        and to trigger the reload of the theme list
+        """
+        log.debug(u'saveTheme %s %s', name, theme_xml)
+        theme_dir = os.path.join(self.path, name)
+        if os.path.exists(theme_dir) == False:
+            os.mkdir(os.path.join(self.path, name))
+        theme_file = os.path.join(theme_dir, name + u'.xml')
+        log.debug(theme_file)
+ 
+        result = QtGui.QMessageBox.Yes
+        if os.path.exists(theme_file):
+            result = QtGui.QMessageBox.question(
+                self,
+                translate(u'ThemeManager', u'Theme Exists'),
+                translate(u'ThemeManager', u'A theme with this name already exists, would you like to overwrite it?'),
+                (QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
+                QtGui.QMessageBox.No)
+        if result == QtGui.QMessageBox.Yes:
+            # Save the theme, overwriting the existing theme if necessary.
+            outfile = open(theme_file, u'w')
+            outfile.write(theme_pretty_xml)
+            outfile.close()
+            if image_from is not None and image_from != image_to:
+                shutil.copyfile(image_from, image_to)
+            
+            self.generateAndSaveImage(self.path, name, theme_xml)
+            self.loadThemes()
+        else:
+            # Don't close the dialog - allow the user to change the name of
+            # the theme or to cancel the theme dialog completely.
+            return False
+
+    def generateAndSaveImage(self, dir, name, theme_xml):
+        log.debug(u'generateAndSaveImage %s %s %s', dir, name, theme_xml)
+        theme = ThemeXML()
+        theme.parse(theme_xml)
+        theme.extend_image_filename(dir)
+        frame = self.generateImage(theme)
+        samplepathname = os.path.join(self.path, name + u'.png')
+        if os.path.exists(samplepathname):
+            os.unlink(samplepathname)
+        frame.save(samplepathname, u'png')
+        log.debug(u'Theme image written to %s', samplepathname)
+
+    def generateImage(self, themedata):
+        """
+        Call the RenderManager to build a Sample Image
+        """
+        log.debug(u'generateImage %s ', themedata)
+        frame = self.parent.RenderManager.generate_preview(themedata)
+        return frame
+
+    def getPreviewImage(self, theme):
+        log.debug(u'getPreviewImage %s ', theme)
+        image = os.path.join(self.path, theme + u'.png')
+        return image
+
+    def cleanTheme(self, theme):
+        theme.background_color = theme.background_color.strip()
+        theme.background_direction = theme.background_direction.strip()
+        theme.background_endColor = theme.background_endColor.strip()
+        if theme.background_filename:
+            theme.background_filename = theme.background_filename.strip()
+        #theme.background_mode
+        theme.background_startColor = theme.background_startColor.strip()
+        #theme.background_type
+        if theme.display_display:
+            theme.display_display = theme.display_display.strip()
+        theme.display_horizontalAlign = theme.display_horizontalAlign.strip()
+        theme.display_outline = str_to_bool(theme.display_outline)
+        #theme.display_outline_color
+        theme.display_shadow = str_to_bool(theme.display_shadow)
+        #theme.display_shadow_color
+        theme.display_verticalAlign = theme.display_verticalAlign.strip()
+        theme.display_wrapStyle = theme.display_wrapStyle.strip()
+        theme.font_footer_color = theme.font_footer_color.strip()
+        theme.font_footer_height = theme.font_footer_height.strip()
+        theme.font_footer_italics = str_to_bool(theme.font_footer_italics)
+        theme.font_footer_name = theme.font_footer_name.strip()
+        #theme.font_footer_override
+        theme.font_footer_proportion = theme.font_footer_proportion.strip()
+        theme.font_footer_weight = theme.font_footer_weight.strip()
+        theme.font_footer_width = theme.font_footer_width.strip()
+        theme.font_footer_x = theme.font_footer_x.strip()
+        theme.font_footer_y = theme.font_footer_y.strip()
+        theme.font_main_color = theme.font_main_color.strip()
+        theme.font_main_height = theme.font_main_height.strip()
+        theme.font_main_italics = str_to_bool(theme.font_main_italics)
+        theme.font_main_name = theme.font_main_name.strip()
+        #theme.font_main_override
+        theme.font_main_proportion = theme.font_main_proportion.strip()
+        theme.font_main_weight = theme.font_main_weight.strip()
+        theme.font_main_x = theme.font_main_x.strip()
+        theme.font_main_y = theme.font_main_y.strip()
+        #theme.theme_mode
+        theme.theme_name = theme.theme_name.strip()
+        #theme.theme_version

=== modified file 'openlp/plugins/bibles/lib/bibleDBimpl.py'
--- openlp/plugins/bibles/lib/bibleDBimpl.py	2009-07-18 05:43:50 +0000
+++ openlp/plugins/bibles/lib/bibleDBimpl.py	2009-09-06 13:57:32 +0000
@@ -28,7 +28,7 @@
 
 class BibleDBImpl(BibleCommon):
     global log
-    log=logging.getLogger(u'BibleDBImpl')
+    log = logging.getLogger(u'BibleDBImpl')
     log.info(u'BibleDBimpl loaded')
 
     def __init__(self, biblepath, biblename, config):
@@ -122,34 +122,45 @@
 
     def get_max_bible_book_verses(self, bookname, chapter):
         log.debug(u'get_max_bible_book_verses %s, %s', bookname, chapter)
-        verse = self.session.query(Verse).join(Book).filter(Book.name==bookname).filter(Verse.chapter==chapter).order_by(Verse.verse.desc()).first()
+        verse = self.session.query(Verse).join(Book).filter(
+            Book.name == bookname).filter(
+            Verse.chapter == chapter).order_by(Verse.verse.desc()).first()
         return verse.verse
 
     def get_max_bible_book_chapter(self, bookname):
         log.debug(u'get_max_bible_book_chapter %s', bookname)
-        verse = self.session.query(Verse).join(Book).filter(Book.name==bookname).order_by(Verse.chapter.desc()).first()
+        verse = self.session.query(Verse).join(Book).filter(
+            Book.name == bookname).order_by(Verse.chapter.desc()).first()
         return verse.chapter
 
     def get_bible_book(self, bookname):
         log.debug(u'get_bible_book %s', bookname)
-        bk = self.session.query(Book).filter(Book.name.like(bookname + u'%')).first()
+        bk = self.session.query(Book).filter(
+            Book.name.like(bookname + u'%')).first()
         if bk == None:
-            bk = self.session.query(Book).filter(Book.abbreviation.like(bookname + u'%')).first()
+            bk = self.session.query(Book).filter(
+                Book.abbreviation.like(bookname + u'%')).first()
         return bk
 
     def get_bible_chapter(self, id, chapter):
         log.debug(u'get_bible_chapter %s, %s', id, chapter)
-        return self.session.query(Verse).filter_by(chapter=chapter).filter_by(book_id=id).first()
+        return self.session.query(Verse).filter_by(chapter=chapter).filter_by(
+            book_id=id).first()
 
     def get_bible_text(self, bookname, chapter, sverse, everse):
-        log.debug(u'get_bible_text %s, %s, %s, %s', bookname, chapter, sverse, everse)
-        verses = self.session.query(Verse).join(Book).filter(Book.name==bookname).filter(Verse.chapter==chapter).filter(Verse.verse>=sverse).filter(Verse.verse<=everse).order_by(Verse.verse).all()
+        log.debug(u'get_bible_text %s, %s, %s, %s', bookname, chapter, sverse,
+            everse)
+        verses = self.session.query(Verse).join(Book).filter(
+            Book.name == bookname).filter(Verse.chapter == chapter).filter(
+            Verse.verse>=sverse).filter(Verse.verse<=everse).order_by(
+            Verse.verse).all()
         return verses
 
     def get_verses_from_text(self, versetext):
         log.debug(u'get_verses_from_text %s',versetext)
         versetext = u'%%%s%%' % versetext
-        verses = self.session.query(Verse).filter(Verse.text.like(versetext)).all()
+        verses = self.session.query(Verse).filter(
+            Verse.text.like(versetext)).all()
         return verses
 
     def dump_bible(self):

=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py	2009-09-01 05:17:32 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py	2009-09-06 13:57:32 +0000
@@ -321,7 +321,8 @@
         cf = self.AdvancedFromChapter.currentText()
         self.adjustComboBox(cf, self.chapters_from, self.AdvancedToChapter)
         # get the verse count for new chapter
-        vse = self.parent.biblemanager.get_book_verse_count(bible, book, int(cf))[0]
+        vse = self.parent.biblemanager.get_book_verse_count(bible, book,
+            int(cf))[0]
         self.adjustComboBox(1, vse, self.AdvancedFromVerse)
         self.adjustComboBox(1, vse, self.AdvancedToVerse)
 
@@ -332,7 +333,8 @@
         if self.ClearQuickSearchComboBox.currentIndex() == 0:
             self.ListView.clear()
         if self.QuickSearchComboBox.currentIndex() == 1:
-            self.search_results = self.parent.biblemanager.get_verse_from_text(bible, text)
+            self.search_results = self.parent.biblemanager.get_verse_from_text(
+                bible, text)
         else:
             self.searchByReference(bible, text)
         if self.search_results is not None:
@@ -341,7 +343,7 @@
     def generateSlideData(self, service_item):
         log.debug(u'generating slide data')
         items = self.ListView.selectedIndexes()
-        if len(items) ==0:
+        if len(items) == 0:
             return False
         old_chapter = u''
         raw_slides = []
@@ -421,8 +423,10 @@
 
     def initialiseChapterVerse(self, bible, book):
         log.debug(u'initialiseChapterVerse %s , %s', bible, book)
-        self.chapters_from = self.parent.biblemanager.get_book_chapter_count(bible, book)
-        self.verses = self.parent.biblemanager.get_book_verse_count(bible, book, 1)
+        self.chapters_from = self.parent.biblemanager.get_book_chapter_count(
+            bible, book)
+        self.verses = self.parent.biblemanager.get_book_verse_count(bible,
+            book, 1)
         self.adjustComboBox(1, self.chapters_from, self.AdvancedFromChapter)
         self.adjustComboBox(1, self.chapters_from, self.AdvancedToChapter)
         self.adjustComboBox(1, self.verses, self.AdvancedFromVerse)
@@ -517,15 +521,19 @@
         if start_chapter == u'':
             message = u'No chapter found for search criteria'
         log.debug(u'results = %s @ %s : %s @ %s : %s'% \
-                  (unicode(book), unicode(start_chapter), unicode(end_chapter),  unicode(start_verse),  unicode(end_verse)))
+            (unicode(book), unicode(start_chapter), unicode(end_chapter),
+            unicode(start_verse), unicode(end_verse)))
         if message == None:
             self.search_results = None
-            self.search_results = self.parent.biblemanager.get_verse_text(bible, book,
-                int(start_chapter), int(end_chapter), int(start_verse),
-                int(end_verse))
-            self.copyright = unicode(self.parent.biblemanager.get_meta_data(bible, u'Copyright').value)
-            self.permissions = unicode(self.parent.biblemanager.get_meta_data(bible, u'Permissions').value)
-            self.version = unicode(self.parent.biblemanager.get_meta_data(bible, u'Version').value)
+            self.search_results = self.parent.biblemanager.get_verse_text(
+                bible, book, int(start_chapter), int(end_chapter),
+                int(start_verse), int(end_verse))
+            self.copyright = unicode(self.parent.biblemanager.get_meta_data(
+                bible, u'Copyright').value)
+            self.permissions = unicode(self.parent.biblemanager.get_meta_data(
+                bible, u'Permissions').value)
+            self.version = unicode(self.parent.biblemanager.get_meta_data(
+                bible, u'Version').value)
         else:
             reply = QtGui.QMessageBox.information(self,
                 translate(u'BibleMediaItem', u'Information'),

=== modified file 'openlp/plugins/media/lib/filelistdata.py'
--- openlp/plugins/media/lib/filelistdata.py	2009-06-16 18:21:24 +0000
+++ openlp/plugins/media/lib/filelistdata.py	2009-09-06 13:57:32 +0000
@@ -32,7 +32,7 @@
 
     def __init__(self):
         QAbstractListModel.__init__(self)
-        self.items=[] # will be a list of (full filename shortname) tuples
+        self.items = [] # will be a list of (full filename shortname) tuples
 
     def rowCount(self, parent):
         return len(self.items)
@@ -56,10 +56,10 @@
         self.insertRow(len(self.items), filename)
 
     def data(self, index, role):
-        row=index.row()
+        row = index.row()
         if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
             return QVariant()
-        if role==Qt.DisplayRole:
+        if role == Qt.DisplayRole:
             retval= self.items[row][1]
 #        elif role == Qt.DecorationRole:
 #            retval= self.items[row][1]


Follow ups