diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index bb3e28e93..9fb823c06 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -312,7 +312,7 @@ class Renderer(object): 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: diff --git a/openlp/core/lib/settingsmanager.py b/openlp/core/lib/settingsmanager.py index ac53e652b..1a8ea98b5 100644 --- a/openlp/core/lib/settingsmanager.py +++ b/openlp/core/lib/settingsmanager.py @@ -20,6 +20,9 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ +from openlp.core.lib import str_to_bool +from openlp.core.utils import ConfigHelper + class SettingsManager(object): """ Class to control the size of the UI components so they size correctly. @@ -31,9 +34,30 @@ class SettingsManager(object): self.width = self.screen[u'size'].width() self.height = self.screen[u'size'].height() self.mainwindow_height = self.height * 0.8 - self.mainwindow_docbars = self.width / 5 - if self.mainwindow_docbars > 300: - self.mainwindow_docbars = 300 - self.slidecontroller = ((self.width - (self.mainwindow_docbars * 3 ) / 2) / 2) -100 - self.slidecontroller_image = self.slidecontroller - 50 - print self.width, self.mainwindow_docbars, self.slidecontroller, self.slidecontroller_image + self.mainwindow_docbars = self.width / 3 + self.mainwindow_slidecontroller = self.width / 6 + self.showMediaManager = str_to_bool( ConfigHelper.get_config( + u'user interface', u'display mediamanager', True)) + self.showServiceManager = str_to_bool(ConfigHelper.get_config( + u'user interface', u'display servicemanager', True)) + self.showThemeManager = str_to_bool(ConfigHelper.get_config( + u'user interface', u'display thememanager', True)) + self.showPreviewPanel = str_to_bool(ConfigHelper.get_config( + u'user interface', u'display previewpanel', True)) + + def toggleMediaManager(self, isVisible): + ConfigHelper.set_config(u'user interface', u'display mediamanager', + isVisible) + + def toggleServiceManager(self, isVisible): + ConfigHelper.set_config(u'user interface', u'display servicemanager', + isVisible) + + def toggleThemeManager(self, isVisible): + ConfigHelper.set_config(u'user interface', u'display thememanager', + isVisible) + + def togglePreviewPanel(self, isVisible): + ConfigHelper.set_config(u'user interface', u'display previewpanel', + isVisible) + diff --git a/openlp/core/test/test_plugin_manager.py b/openlp/core/test/test_plugin_manager.py index 815523067..d8dac432e 100644 --- a/openlp/core/test/test_plugin_manager.py +++ b/openlp/core/test/test_plugin_manager.py @@ -24,23 +24,24 @@ sys.path.insert(0,(os.path.join(mypath, '..' ,'..', '..'))) # 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: diff --git a/openlp/core/test/test_render.py b/openlp/core/test/test_render.py index 9b8003b85..e7955316a 100644 --- a/openlp/core/test/test_render.py +++ b/openlp/core/test/test_render.py @@ -21,10 +21,12 @@ import sys 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 @@ class TstFrame: 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 @@ class TestRender_base: 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 @@ class TestRender_base: 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 @@ class TestRender_base: # 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 @@ class TestRender(TestRender_base): 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 @@ Line 2 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 @@ Line 2 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 @@ Line 3""" 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() diff --git a/openlp/core/test/test_render_theme.py b/openlp/core/test/test_render_theme.py index 44f209e67..f0f9e9933 100644 --- a/openlp/core/test/test_render_theme.py +++ b/openlp/core/test/test_render_theme.py @@ -15,17 +15,18 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ - -from 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 openlp.core.theme import Theme -from openlp.core import Renderer from PyQt4 import QtGui, QtCore +from openlp.core.theme import Theme +from openlp.core import Renderer +from test_render import TestRender_base, whoami + +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 if goldenim == testim: @@ -53,22 +54,24 @@ class TestRenderTheme(TestRender_base): 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 @@ And drives away his fear. 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 @@ And drives away his fear. 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.BackgroundType = 2 - 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" - self.r.set_theme(t) - print "render" - self.answer=self.r.render_screen(0) - print "whoami" - self.bmpname=whoami() - print "fone" - def test_bg_shrink_y(self): - 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.BackgroundParameter3 = 0 - t.Name="shrink y" - self.r.set_theme(t) - 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); + 'snowsmall.jpg') + t.BackgroundParameter2 = QtGui.QColor(0,0,64) + t.BackgroundParameter3 = 0 + t.Name = "stretch y" + self.r.set_theme(t) + print "render" + self.answer = self.r.render_screen(0) + print "whoami" + self.bmpname = whoami() + print "fone" + + def test_bg_shrink_y(self): + 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.BackgroundParameter3 = 0 + t.Name = "shrink y" + self.r.set_theme(t) + self.answer = self.r.render_screen(0) + self.bmpname = whoami() + + def test_bg_stretch_x(self): + 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) 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() diff --git a/openlp/core/theme/test/test_theme.py b/openlp/core/theme/test/test_theme.py index f63f5401d..211d23be9 100644 --- a/openlp/core/theme/test/test_theme.py +++ b/openlp/core/theme/test/test_theme.py @@ -50,6 +50,6 @@ def test_theme(): print "Tests passed" -if __name__=="__main__": +if __name__ == "__main__": test_read_theme() test_theme() diff --git a/openlp/core/ui/amendthemeform.py b/openlp/core/ui/amendthemeform.py index a25aff950..254888965 100644 --- a/openlp/core/ui/amendthemeform.py +++ b/openlp/core/ui/amendthemeform.py @@ -1,710 +1,646 @@ -# -*- 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 setTheme(self, theme): + self.theme = theme + + def loadTheme(self): + log.debug(u'LoadTheme %s', 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 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)) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 16494a560..0ed7b6710 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -26,16 +26,19 @@ from openlp.core.ui import AboutForm, SettingsForm, AlertForm, \ 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) @@ -118,6 +121,7 @@ class Ui_MainWindow(object): self.MediaManagerDock.setWidget(self.MediaManagerContents) MainWindow.addDockWidget( QtCore.Qt.DockWidgetArea(1), self.MediaManagerDock) + self.MediaManagerDock.setVisible(self.settingsmanager.showMediaManager) # Create the service manager self.ServiceManagerDock = QtGui.QDockWidget(MainWindow) ServiceManagerIcon = QtGui.QIcon() @@ -133,6 +137,8 @@ class Ui_MainWindow(object): self.ServiceManagerDock.setWidget(self.ServiceManagerContents) MainWindow.addDockWidget( QtCore.Qt.DockWidgetArea(2), self.ServiceManagerDock) + self.ServiceManagerDock.setVisible( + self.settingsmanager.showServiceManager) # Create the theme manager self.ThemeManagerDock = QtGui.QDockWidget(MainWindow) ThemeManagerIcon = QtGui.QIcon() @@ -146,18 +152,22 @@ class Ui_MainWindow(object): self.ThemeManagerDock.setWidget(self.ThemeManagerContents) MainWindow.addDockWidget( QtCore.Qt.DockWidgetArea(2), self.ThemeManagerDock) + self.ThemeManagerDock.setVisible(self.settingsmanager.showThemeManager) # 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') @@ -185,17 +195,20 @@ class Ui_MainWindow(object): self.OptionsSettingsItem.setObjectName(u'OptionsSettingsItem') self.ViewMediaManagerItem = QtGui.QAction(MainWindow) self.ViewMediaManagerItem.setCheckable(True) - self.ViewMediaManagerItem.setChecked(True) + self.ViewMediaManagerItem.setChecked( + self.settingsmanager.showMediaManager) self.ViewMediaManagerItem.setIcon(icon) self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem') self.ViewThemeManagerItem = QtGui.QAction(MainWindow) self.ViewThemeManagerItem.setCheckable(True) - self.ViewThemeManagerItem.setChecked(True) + self.ViewThemeManagerItem.setChecked( + self.settingsmanager.showThemeManager) self.ViewThemeManagerItem.setIcon(ThemeManagerIcon) self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem') self.ViewServiceManagerItem = QtGui.QAction(MainWindow) self.ViewServiceManagerItem.setCheckable(True) - self.ViewServiceManagerItem.setChecked(True) + self.ViewServiceManagerItem.setChecked( + self.settingsmanager.showServiceManager) self.ViewServiceManagerItem.setIcon(ServiceManagerIcon) self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem') self.ToolsAlertItem = QtGui.QAction(MainWindow) @@ -212,7 +225,8 @@ class Ui_MainWindow(object): 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') @@ -238,8 +252,11 @@ class Ui_MainWindow(object): self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem') self.action_Preview_Panel = QtGui.QAction(MainWindow) self.action_Preview_Panel.setCheckable(True) - self.action_Preview_Panel.setChecked(True) + self.action_Preview_Panel.setChecked( + self.settingsmanager.showPreviewPanel) self.action_Preview_Panel.setObjectName(u'action_Preview_Panel') + self.PreviewController.Panel.setVisible( + self.settingsmanager.showPreviewPanel) self.ModeLiveItem = QtGui.QAction(MainWindow) self.ModeLiveItem.setObjectName(u'ModeLiveItem') self.FileImportMenu.addAction(self.ImportThemeItem) @@ -296,7 +313,8 @@ class Ui_MainWindow(object): 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 +322,8 @@ class Ui_MainWindow(object): 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 +383,13 @@ class Ui_MainWindow(object): 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 +456,35 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): 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.toggleMediaManager) QtCore.QObject.connect(self.ViewServiceManagerItem, - QtCore.SIGNAL(u'triggered(bool)'), self.ServiceManagerDock.setVisible) + QtCore.SIGNAL(u'triggered(bool)'), + self.toggleServiceManager) QtCore.QObject.connect(self.ViewThemeManagerItem, - QtCore.SIGNAL(u'triggered(bool)'), self.ThemeManagerDock.setVisible) + QtCore.SIGNAL(u'triggered(bool)'), + self.toggleThemeManager) QtCore.QObject.connect(self.action_Preview_Panel, - QtCore.SIGNAL(u'toggled(bool)'), self.PreviewController.Panel.setVisible) + QtCore.SIGNAL(u'toggled(bool)'), + self.togglePreviewPanel) 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.PreviewController.Panel, + QtCore.SIGNAL(u'visibilityChanged(bool)'), + self.action_Preview_Panel.setChecked) QtCore.QObject.connect(self.HelpAboutItem, QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked) QtCore.QObject.connect(self.ToolsAlertItem, @@ -472,7 +510,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): 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) @@ -555,7 +592,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): 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() @@ -598,3 +638,23 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def defaultThemeChanged(self, theme): self.DefaultThemeLabel.setText(self.defaultThemeText + theme) + + def toggleMediaManager(self): + mediaBool = self.MediaManagerDock.isVisible() + self.MediaManagerDock.setVisible(not mediaBool) + self.settingsmanager.toggleMediaManager(not mediaBool) + + def toggleServiceManager(self): + serviceBool = self.ServiceManagerDock.isVisible() + self.ServiceManagerDock.setVisible(not serviceBool) + self.settingsmanager.toggleServiceManager(not serviceBool) + + def toggleThemeManager(self): + themeBool = self.ThemeManagerDock.isVisible() + self.ThemeManagerDock.setVisible(not themeBool) + self.settingsmanager.toggleThemeManager(not themeBool) + + def togglePreviewPanel(self): + previewBool = self.PreviewController.Panel.isVisible() + self.PreviewController.Panel.setVisible(not previewBool) + self.settingsmanager.togglePreviewPanel(not previewBool) diff --git a/openlp/core/ui/test/test_service_manager.py b/openlp/core/ui/test/test_service_manager.py index ac76a678e..feb7834a5 100644 --- a/openlp/core/ui/test/test_service_manager.py +++ b/openlp/core/ui/test/test_service_manager.py @@ -136,7 +136,8 @@ class TestServiceManager_base: # new and save as # deleting items -if __name__=="__main__": + +if __name__ == "__main__": t=TestServiceManager_base() t.setup_class() diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 001ab94b0..17797de5a 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -1,380 +1,449 @@ -# -*- 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.theme.parse(self.baseTheme()) + self.amendThemeForm.loadTheme() + self.amendThemeForm.exec_() + + def onEditTheme(self): + item = self.ThemeListWidget.currentItem() + if item is not None: + self.amendThemeForm.setTheme(self.getThemeData( + item.data(QtCore.Qt.UserRole).toString())) + self.amendThemeForm.loadTheme() + 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: + xml = self.baseTheme() + 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 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 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 diff --git a/openlp/plugins/bibles/lib/bibleDBimpl.py b/openlp/plugins/bibles/lib/bibleDBimpl.py index 0c7fcaa8c..2378f3c11 100644 --- a/openlp/plugins/bibles/lib/bibleDBimpl.py +++ b/openlp/plugins/bibles/lib/bibleDBimpl.py @@ -28,7 +28,7 @@ from openlp.plugins.bibles.lib.models import * 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 @@ class BibleDBImpl(BibleCommon): 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): diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index bd5b057f5..bb879174d 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -321,7 +321,8 @@ class BibleMediaItem(MediaManagerItem): 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 @@ class BibleMediaItem(MediaManagerItem): 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 @@ class BibleMediaItem(MediaManagerItem): 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 @@ class BibleMediaItem(MediaManagerItem): 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 @@ class BibleMediaItem(MediaManagerItem): 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'), diff --git a/openlp/plugins/media/lib/filelistdata.py b/openlp/plugins/media/lib/filelistdata.py index 80e0544f9..59730e1cd 100644 --- a/openlp/plugins/media/lib/filelistdata.py +++ b/openlp/plugins/media/lib/filelistdata.py @@ -32,7 +32,7 @@ class FileListData(QAbstractListModel): 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 @@ class FileListData(QAbstractListModel): 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]