From 0e7dfb9fc4035472569963a7373ef030de3128e4 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 6 Apr 2009 19:45:45 +0100 Subject: [PATCH] Combine patch from previous tree which I messed up. Here is a summary of the changes. 444. By Tim Bentley 23 hours ago Add new event for Theme Loading 443. By Tim Bentley 23 hours ago Add Eventing after Themes loaded to tell plugins the themes have changed 442. By Tim Bentley on 2009-04-04 Store Theme name in list for correct display 441. By Tim Bentley on 2009-04-04 Add ThemeManagerDialog More Rendering improvements 440. By Tim Bentley on 2009-04-04 Add Themes to Bible Tab and default values 439. By Tim Bentley on 2009-04-04 Add rendering for Circles and amend XML schema accordingly 438. By Tim Bentley on 2009-04-04 Renderer now supports linear gradients correctly Update XML to include direction Add Booleans instead of 0/1 to XML schema 437. By Tim Bentley on 2009-04-03 More ThemeManager changes Fix Rendering and theme handling Generate PNG theme on conversion 436. By Tim Bentley on 2009-04-01 Fix up Theme XML code to work with strings and files. Fix Render.py to work with new XML schema 435. By Tim Bentley on 2009-04-01 Import version 2 xml and build object. --- openlp/core/__init__.py | 9 +- openlp/core/lib/event.py | 4 +- openlp/core/lib/eventmanager.py | 12 +- openlp/core/lib/songxmlhandler.py | 49 ++++-- openlp/core/lib/themexmlhandler.py | 166 ++++++++++++------ openlp/core/render.py | 173 ++++++++++--------- openlp/core/theme/theme.py | 8 +- openlp/core/ui/__init__.py | 3 +- openlp/core/ui/mainwindow.py | 59 ++----- openlp/core/ui/thememanager.py | 222 ++++++++++++++++--------- openlp/plugins/bibles/lib/biblestab.py | 28 +++- 11 files changed, 451 insertions(+), 282 deletions(-) diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index a149b42d8..f795b6040 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -23,7 +23,14 @@ from render import Renderer from settingsmanager import SettingsManager from pluginmanager import PluginManager -__all__ = ['Renderer', 'SettingsManager', 'PluginManager', 'translate'] +__all__ = ['Renderer', 'SettingsManager', 'PluginManager', 'translate', 'fileToXML'] def translate(context, text): return QtGui.QApplication.translate(context, text, None, QtGui.QApplication.UnicodeUTF8) + +def fileToXML(xmlfile): + file=open(xmlfile) + xml =''.join(file.readlines()) # read the file and change list to a string + file.close() + return xml + diff --git a/openlp/core/lib/event.py b/openlp/core/lib/event.py index d6c390c62..94095d169 100644 --- a/openlp/core/lib/event.py +++ b/openlp/core/lib/event.py @@ -41,6 +41,8 @@ class EventType(object): PreviewBeforeShow = 13 PreviewAfterShow = 14 + ThemeListChanged = 15 + class Event(object): """ @@ -49,6 +51,6 @@ class Event(object): def __init__(self, event_type=EventType.Default, payload=None): self.event_type = event_type self.payload = payload - + def get_type(self): return self.event_type diff --git a/openlp/core/lib/eventmanager.py b/openlp/core/lib/eventmanager.py index 12dfd2ac1..cfa810f68 100644 --- a/openlp/core/lib/eventmanager.py +++ b/openlp/core/lib/eventmanager.py @@ -26,21 +26,21 @@ class EventManager(object): A mechanism to send events to all registered endpoints the endpoints are registered and listen with a handle_event method the endpoint will decide whether to do somthing with the event or ignore it - + """ global log log=logging.getLogger(u'EventManager') - + def __init__(self): self.endpoints=[] log.info(u'Initialising') - + def register(self, plugin): - log.debug(u'plugin %s registered with EventManager'%plugin) + log.debug(u'plugin %s registered with EventManager', plugin) self.endpoints.append(plugin) - + def post_event(self, event): - log.debug(u'post event called for event %s'%event.get_type) + log.debug(u'post event called for event %s', event.get_type) for point in self.endpoints: point.handle_event(event) diff --git a/openlp/core/lib/songxmlhandler.py b/openlp/core/lib/songxmlhandler.py index a8210d0e7..54da479d3 100644 --- a/openlp/core/lib/songxmlhandler.py +++ b/openlp/core/lib/songxmlhandler.py @@ -1,6 +1,24 @@ +# -*- 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-2009 Martin Thompson, Tim Bentley, Carsten Tinggaard + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA from xml.dom.minidom import Document from xml.etree.ElementTree import ElementTree, XML, dump -""" + @@ -11,24 +29,27 @@ from xml.etree.ElementTree import ElementTree, XML, dump """ +from xml.dom.minidom import Document +from xml.etree.ElementTree import ElementTree, XML, dump + class SongXMLBuilder(): def __init__(self): - # Create the minidom document + # Create the minidom document self.song_xml = Document() - + def new_document(self): # Create the base element self.song = self.song_xml.createElement(u'song') self.song_xml.appendChild(self.song) self.song.setAttribute(u'version', u'1.0') - + def add_lyrics_to_song(self): # Create the main element self.lyrics = self.song_xml.createElement(u'lyrics') self.lyrics.setAttribute(u'language', u'en') self.song.appendChild(self.lyrics) - - def add_verse_to_lyrics(self, type, number, content): + + def add_verse_to_lyrics(self, type, number, content): """ type - type of verse (Chorus, Verse , Bridge, Custom etc number - number of item eg verse 1 @@ -36,34 +57,34 @@ class SongXMLBuilder(): """ verse = self.song_xml.createElement(u'verse') verse.setAttribute(u'type', type) - verse.setAttribute(u'label', number) + verse.setAttribute(u'label', number) self.lyrics.appendChild(verse) - + # add data as a CDATA section cds = self.song_xml.createCDATASection(content) verse.appendChild(cds) - + def dump_xml(self): # Debugging aid to see what we have print self.song_xml.toprettyxml(indent=" ") - + def extract_xml(self): # Print our newly created XML return self.song_xml.toxml() - + class SongXMLParser(): def __init__(self, xml): self.song_xml = ElementTree(element=XML(xml)) - + def get_verses(self): #return a list of verse's and attributes iter=self.song_xml.getiterator() verse_list = [] - for element in iter: + for element in iter: if element.tag == u'verse': verse_list.append([element.attrib, element.text]) return verse_list - + def dump_xml(self): # Debugging aid to see what we have print dump(self.song_xml) diff --git a/openlp/core/lib/themexmlhandler.py b/openlp/core/lib/themexmlhandler.py index 573047f04..f57c77718 100644 --- a/openlp/core/lib/themexmlhandler.py +++ b/openlp/core/lib/themexmlhandler.py @@ -1,16 +1,29 @@ +# -*- 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-2009 Martin Thompson, Tim Bentley, Carsten Tinggaard + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA from xml.dom.minidom import Document from xml.etree.ElementTree import ElementTree, XML, dump -""" - - - - - - - - +For XML Schema see wiki.openlp.org """ +from xml.dom.minidom import Document +from xml.etree.ElementTree import ElementTree, XML, dump + class ThemeXMLBuilder(): def __init__(self): # Create the minidom document @@ -29,12 +42,12 @@ class ThemeXMLBuilder(): def add_background_transparent(self): # Create the main element - background = self.theme_xml.createElement(u'Background') + background = self.theme_xml.createElement(u'background') background.setAttribute(u'mode', u'transparent') self.theme.appendChild(background) def add_background_solid(self, bkcolor): - background = self.theme_xml.createElement(u'Background') + background = self.theme_xml.createElement(u'background') background.setAttribute(u'mode', u'opaque') background.setAttribute(u'type', u'solid') self.theme.appendChild(background) @@ -44,24 +57,29 @@ class ThemeXMLBuilder(): color.appendChild(bkc) background.appendChild(color) - def add_background_gradient(self, startcolor, endcolor): - background = self.theme_xml.createElement(u'Background') + def add_background_gradient(self, startcolor, endcolor, direction): + background = self.theme_xml.createElement(u'background') background.setAttribute(u'mode', u'opaque') - background.setAttribute(u'type', u'gradient') + background.setAttribute(u'type', u'Gradient') self.theme.appendChild(background) - color = self.theme_xml.createElement(u'startcolor') + color = self.theme_xml.createElement(u'startColor') bkc = self.theme_xml.createTextNode(startcolor) color.appendChild(bkc) background.appendChild(color) - color = self.theme_xml.createElement(u'endcolor') + color = self.theme_xml.createElement(u'endColor') bkc = self.theme_xml.createTextNode(endcolor) color.appendChild(bkc) background.appendChild(color) - def add_background_image(self, filename, bordercolor): - background = self.theme_xml.createElement(u'Background') + color = self.theme_xml.createElement(u'direction') + bkc = self.theme_xml.createTextNode(direction) + color.appendChild(bkc) + background.appendChild(color) + + def add_background_image(self, filename): + background = self.theme_xml.createElement(u'background') background.setAttribute(u'mode', u'opaque') background.setAttribute(u'type', u'image') self.theme.appendChild(background) @@ -71,26 +89,62 @@ class ThemeXMLBuilder(): color.appendChild(bkc) background.appendChild(color) - color = self.theme_xml.createElement(u'bordercolor') - bkc = self.theme_xml.createTextNode(bordercolor) - color.appendChild(bkc) - background.appendChild(color) + def add_font(self, fontname, fontcolor, fontproportion, fonttype=u'main'): + background = self.theme_xml.createElement(u'font') + background.setAttribute(u'type',fonttype) + self.theme.appendChild(background) + name = self.theme_xml.createElement(u'name') + fn = self.theme_xml.createTextNode(fontname) + name.appendChild(fn) + background.appendChild(name) - def add_verse_to_lyrics(self, type, number, content): - """ - type - type of verse (Chorus, Verse , Bridge, Custom etc - number - number of item eg verse 1 - content - the text to be stored - """ - verse = self.theme_xml.createElement(u'verse') - verse.setAttribute(u'type', type) - verse.setAttribute(u'label', number) - self.lyrics.appendChild(verse) + name = self.theme_xml.createElement(u'color') + fn = self.theme_xml.createTextNode(fontcolor) + name.appendChild(fn) + background.appendChild(name) - # add data as a CDATA section - cds = self.theme_xml.createCDATASection(content) - verse.appendChild(cds) + name = self.theme_xml.createElement(u'proportion') + fn = self.theme_xml.createTextNode(fontproportion) + name.appendChild(fn) + background.appendChild(name) + + def add_display(self, shadow, shadowColor, outline, outlineColor, horizontal, vertical, wrap): + background = self.theme_xml.createElement(u'display') + self.theme.appendChild(background) + + tagElement = self.theme_xml.createElement(u'shadow') + tagElement.setAttribute(u'color',shadowColor) + tagValue = self.theme_xml.createTextNode(shadow) + tagElement.appendChild(tagValue) + background.appendChild(tagElement) + + tagElement = self.theme_xml.createElement(u'outline') + tagElement.setAttribute(u'color',outlineColor) + tagValue = self.theme_xml.createTextNode(outline) + tagElement.appendChild(tagValue) + background.appendChild(tagElement) + + tagElement = self.theme_xml.createElement(u'horizontalAlign') + tagValue = self.theme_xml.createTextNode(horizontal) + tagElement.appendChild(tagValue) + background.appendChild(tagElement) + + tagElement = self.theme_xml.createElement(u'verticalAlign') + tagValue = self.theme_xml.createTextNode(vertical) + tagElement.appendChild(tagValue) + background.appendChild(tagElement) + + tagElement = self.theme_xml.createElement(u'wrapStyle') + tagValue = self.theme_xml.createTextNode(wrap) + tagElement.appendChild(tagValue) + background.appendChild(tagElement) + + def child_element(self, tag, value): + tagElement = self.theme_xml.createElement(tag) + tagValue = self.theme_xml.createTextNode(value) + tagElement.appendChild(ftagValue) + self.background.appendChild(tagElement) def dump_xml(self): # Debugging aid to see what we have @@ -102,17 +156,35 @@ class ThemeXMLBuilder(): class ThemeXMLParser(): def __init__(self, xml): - self.theme_xml = ElementTree(element=XML(xml)) - - def get_verses(self): - #return a list of verse's and attributes - iter=self.theme_xml.getiterator() - verse_list = [] + theme_xml = ElementTree(element=XML(xml)) + iter=theme_xml.getiterator() + master = u'' for element in iter: - if element.tag == u'verse': - verse_list.append([element.attrib, element.text]) - return verse_list + #print element.tag, element.text + if len(element.getchildren()) > 0: + master= element.tag + u'_' + if len(element.attrib) > 0: + #print "D", element.tag , element.attrib + for e in element.attrib.iteritems(): + #print "A", master, e[0], e[1] + if master == u'font_' and e[0] == u'type': + master += e[1] + u'_' + elif master == u'display_' and (element.tag == u'shadow' or element.tag == u'outline'): + #print "b", master, element.tag, element.text, e[0], e[1] + setattr(self, master + element.tag , element.text) + setattr(self, master + element.tag +u'_'+ e[0], e[1]) + else: + field = master + e[0] + setattr(self, field, e[1]) + else: + #print "c", element.tag + if element.tag is not None : + field = master + element.tag + setattr(self, field, element.text) - def dump_xml(self): - # Debugging aid to see what we have - print dump(self.theme_xml) + def __str__(self): + s = u'' + for k in dir(self): + if k[0:1] != u'_': + s+= u'%30s : %s\n' %(k,getattr(self,k)) + return s diff --git a/openlp/core/render.py b/openlp/core/render.py index cc0b23436..dfa49c2c3 100644 --- a/openlp/core/render.py +++ b/openlp/core/render.py @@ -56,11 +56,11 @@ class Renderer: def set_theme(self, theme): self._theme=theme - if theme.BackgroundType == 2: - self.set_bg_image(theme.BackgroundParameter1) + if theme.background_type == u'image': + self.set_bg_image(theme.background_filename) def set_bg_image(self, filename): - log.debug(u"set bg image %s", filename) + log.debug(u'set bg image %s', filename) self._bg_image_filename=filename if self._paint is not None: self.scale_bg_image() @@ -69,11 +69,13 @@ class Renderer: assert self._paint i=QtGui.QImage(self._bg_image_filename) # rescale and offset - imw=i.width();imh=i.height() - dcw=self._paint.width()+1;dch=self._paint.height() + imw=i.width() + imh=i.height() + dcw=self._paint.width()+1 + dch=self._paint.height() imratio=imw/float(imh) dcratio=dcw/float(dch) - log.debug(u"Image scaling params %s %s %s %s %s %s", imw, imh, imratio, dcw, dch, dcratio) + log.debug(u'Image scaling params %s %s %s %s %s %s', imw, imh, imratio, dcw, dch, dcratio) if imratio > dcratio: scale=dcw/float(imw) elif imratio < dcratio: @@ -94,20 +96,20 @@ class Renderer: def set_words_openlp(self, words): # log.debug(u" "set words openlp", words verses=[] - words=words.replace("\r\n", "\n") - verses_text=words.split('\n\n') + words=words.replace(u'\r\n', u'\n') + verses_text=words.split(u'\n\n') for v in verses_text: - lines=v.split('\n') + lines=v.split(u'\n') verses.append(self.split_set_of_lines(lines)[0]) self.words=verses verses_text=[] for v in verses: - verses_text.append('\n'.join(v).lstrip()) # remove first \n + verses_text.append(u'\n'.join(v).lstrip()) # remove first \n return verses_text def render_screen(self, screennum): - log.debug(u"render screen\n %s %s ", screennum, self.words[screennum]) + log.debug(u'render screen\n %s %s ', screennum, self.words[screennum]) import time t=0.0 words=self.words[screennum] @@ -121,40 +123,49 @@ class Renderer: def _render_background(self): assert(self._theme) assert(self._paint) - log.debug(u"render background %s %s", self._theme.BackgroundType) + log.debug(u'render background %s ', self._theme.background_type) p=QtGui.QPainter() p.begin(self._paint) - if self._theme.BackgroundType == 0: - p.fillRect(self._paint.rect(), self._theme.BackgroundParameter1) - elif self._theme.BackgroundType == 1: # gradient - #TODO Add Theme code and fix direction + if self._theme.background_type == u'solid': + p.fillRect(self._paint.rect(), QtGui.QColor(self._theme.background_color)) + elif self._theme.background_type == u'Gradient' : # gradient + gradient = None + if self._theme.background_direction == u'vertical': + w = int(self._paint.width())/2 + gradient = QtGui.QLinearGradient(w, 0, w, self._paint.height()) # vertical + elif self._theme.background_direction == u'horizontal': + h = int(self._paint.height())/2 + gradient = QtGui.QLinearGradient(0, h, self._paint.width(), h) # Horizontal + else: + w = int(self._paint.width())/2 + h = int(self._paint.height())/2 + gradient = QtGui.QRadialGradient(w, h, w) # Circular + + gradient.setColorAt(0, QtGui.QColor(self._theme.background_startColor)) + gradient.setColorAt(1, QtGui.QColor(self._theme.background_endColor)) - gradient = QtGui.QLinearGradient(0, 0, self._paint.width(), self._paint.height()) - gradient.setColorAt(0, QtGui.QColor(255, 0, 0)) - gradient.setColorAt(0.5, QtGui.QColor(0, 255, 0)) - gradient.setColorAt(1, QtGui.QColor(0, 0, 255)) p.setBrush(QtGui.QBrush(gradient)) rectPath = QtGui.QPainterPath() - MAX_X = self._paint.width() - MAX_Y = self._paint.height() - + max_x = self._paint.width() + max_y = self._paint.height() rectPath.moveTo(0, 0) - rectPath.lineTo(0, MAX_Y) - rectPath.lineTo(MAX_X, MAX_Y) - rectPath.lineTo(MAX_X, 0) + rectPath.lineTo(0, max_y) + rectPath.lineTo(max_x, max_y) + rectPath.lineTo(max_x, 0) + rectPath.closeSubpath() p.drawPath(rectPath) - elif self._theme.BackgroundType == 2: # image + elif self._theme.background_type== u'image': # image r=self._paint.rect() - log.debug(r.x(), r.y(), r.width(),r.height()) - log.debug(self._theme.BackgroundParameter2) - if self._theme.BackgroundParameter2 is not None: - p.fillRect(self._paint.rect(), self._theme.BackgroundParameter2) + log.debug(u'Image size details %d %d %d %d ', r.x(), r.y(), r.width(),r.height()) + log.debug(u' Background Parameter %d ', self._theme.background_borderColor) + if self._theme.Bbackground_borderColor is not None: + p.fillRect(self._paint.rect(), self._theme.background_borderColor) p.drawPixmap(self.background_offsetx,self.background_offsety, self.img) p.end() - log.debug(u"render background done") + log.debug(u'render background done') def split_set_of_lines(self, lines): @@ -221,24 +232,23 @@ class Renderer: def _render_lines(self, lines): """render a set of lines according to the theme, return bounding box""" - log.debug(u"_render_lines %s", lines) + #log.debug(u'_render_lines %s', lines) bbox=self._render_lines_unaligned(lines) - print bbox t=self._theme x=self._rect.left() - if t.VerticalAlign==0: # top align + if int(t.display_verticalAlign) == 0: # top align y = self._rect.top() - elif t.VerticalAlign==1: # bottom align + elif int(t.display_verticalAlign) == 1: # bottom align y=self._rect.bottom()-bbox.height() - elif t.VerticalAlign==2: # centre align + elif int(t.display_verticalAlign) == 2: # centre align y=self._rect.top()+(self._rect.height()-bbox.height())/2 else: - assert(0, "Invalid value for theme.VerticalAlign:%d" % t.VerticalAlign) + assert(0, u'Invalid value for theme.VerticalAlign:%s' % t.display_verticalAlign) self._render_background() bbox=self._render_lines_unaligned(lines, (x,y)) - log.debug(u"render lines DONE") + log.debug(u'render lines DONE') return bbox @@ -250,7 +260,7 @@ class Renderer: than a screenful (eg. by using split_set_of_lines) Returns the bounding box of the text as QRect""" - log.debug(u"render unaligned %s", lines) + log.debug(u'render unaligned %s', lines) x,y=tlcorner brx=x bry=y @@ -269,7 +279,7 @@ class Renderer: p.setPen(QtGui.QPen(QtGui.QColor(0,0,255))) p.drawRect(retval) p.end() - log.debug(u"render unaligned DONE") + log.debug(u'render unaligned DONE') return retval @@ -283,7 +293,7 @@ class Renderer: Returns the bottom-right corner (of what was rendered) as a tuple(x,y). """ - log.debug(u"Render single line '%s' @ %s "%( line, tlcorner)) + #log.debug(u'Render single line %s @ %s '%( line, tlcorner)) x,y=tlcorner # We draw the text to see how big it is and then iterate to make it fit # when we line wrap we do in in the "lyrics" style, so the second line is @@ -291,8 +301,8 @@ class Renderer: # get the words # log.debug(u" "Getting the words split right" - words=line.split(" ") - thisline=' '.join(words) + words=line.split(u' ') + thisline=u' '.join(words) lastword=len(words) lines=[] maxx=self._rect.width(); maxy=self._rect.height(); @@ -307,25 +317,22 @@ class Renderer: else: lastword-=1 thisline=' '.join(words[:lastword]) - -# log.debug(u" "This is how they split", lines -# log.debug(u" "Now render them" startx=x starty=y rightextent=None t=self._theme - align=t.HorizontalAlign - wrapstyle=t.WrapStyle + align=t.display_horizontalAlign + wrapstyle=t.display_wrapStyle for linenum in range(len(lines)): line=lines[linenum] #find out how wide line is - w,h=self._get_extent_and_render(line, tlcorner=(x,y), dodraw=False) + w,h=self._get_extent_and_render(line, tlcorner=(x,y), draw=False) - if t.Shadow: + if t.display_shadow: w+=self._shadow_offset h+=self._shadow_offset - if t.Outline: + if t.display_outline: w+=2*self._outline_offset # pixels either side h+=2*self._outline_offset # pixels top/bottom if align==0: # left align @@ -343,21 +350,22 @@ class Renderer: x=(maxx-w)/2; rightextent=x+w # now draw the text, and any outlines/shadows - if t.Shadow: - self._get_extent_and_render(line, tlcorner=(x+self._shadow_offset,y+self._shadow_offset), dodraw=True, color = t.ShadowColor) - if t.Outline: - self._get_extent_and_render(line, (x+self._outline_offset,y), dodraw=True, color = t.OutlineColor) - self._get_extent_and_render(line, (x,y+self._outline_offset), dodraw=True, color = t.OutlineColor) - self._get_extent_and_render(line, (x,y-self._outline_offset), dodraw=True, color = t.OutlineColor) - self._get_extent_and_render(line, (x-self._outline_offset,y), dodraw=True, color = t.OutlineColor) + if t.display_shadow: + self._get_extent_and_render(line, tlcorner=(x+self._shadow_offset,y+self._shadow_offset), + draw=True, color = t.display_shadow_color) + if t.display_outline: + self._get_extent_and_render(line, (x+self._outline_offset,y), draw=True, color = t.display_outline_color) + self._get_extent_and_render(line, (x,y+self._outline_offset), draw=True, color = t.display_outline_color) + self._get_extent_and_render(line, (x,y-self._outline_offset), draw=True, color = t.display_outline_color) + self._get_extent_and_render(line, (x-self._outline_offset,y), draw=True, color = t.display_outline_color) if self._outline_offset > 1: - self._get_extent_and_render(line, (x+self._outline_offset,y+self._outline_offset), dodraw=True, color = t.OutlineColor) - self._get_extent_and_render(line, (x-self._outline_offset,y+self._outline_offset), dodraw=True, color = t.OutlineColor) - self._get_extent_and_render(line, (x+self._outline_offset,y-self._outline_offset), dodraw=True, color = t.OutlineColor) - self._get_extent_and_render(line, (x-self._outline_offset,y-self._outline_offset), dodraw=True, color = t.OutlineColor) + self._get_extent_and_render(line, (x+self._outline_offset,y+self._outline_offset), draw=True, color = t.display_outline_color) + self._get_extent_and_render(line, (x-self._outline_offset,y+self._outline_offset), draw=True, color = t.display_outline_color) + self._get_extent_and_render(line, (x+self._outline_offset,y-self._outline_offset), draw=True, color = t.display_outline_color) + self._get_extent_and_render(line, (x-self._outline_offset,y-self._outline_offset), draw=True, color = t.display_outline_color) - self._get_extent_and_render(line, tlcorner=(x,y), dodraw=True) -# log.debug(u" "Line %2d: Render '%s' at (%d, %d) wh=(%d,%d)"%( linenum, line, x, y,w,h) + self._get_extent_and_render(line, tlcorner=(x,y), draw=True) +# log.debug(u'Line %2d: Render '%s' at (%d, %d) wh=(%d,%d)' % ( linenum, line, x, y,w,h) y += h if linenum == 0: self._first_line_right_extent=rightextent @@ -373,47 +381,48 @@ class Renderer: return brcorner # xxx this is what to override for an SDL version - def _get_extent_and_render(self, line, tlcorner=(0,0), dodraw=False, color=None, footer = False): + def _get_extent_and_render(self, line, tlcorner=(0,0), draw=False, color=None, footer=False): """Find bounding box of text - as render_single_line. - If dodraw is set, actually draw the text to the current DC as well + If draw is set, actually draw the text to the current DC as well return width and height of text as a tuple (w,h)""" # setup defaults - log.debug(u"_get_extent_and_render %s %s %s ", [line], tlcorner, dodraw) + #log.debug(u"_get_extent_and_render %s %s %s ", [line], tlcorner, draw) p=QtGui.QPainter() p.begin(self._paint) # 'twould be more efficient to set this once when theme changes # or p changes if footer : - font=QtGui.QFont(self._theme.FontName, - 12, # size + font=QtGui.QFont(self._theme.font_footer_name, + int(self._theme.font_footer_proportion), # size QtGui.QFont.Normal, # weight 0)# italic else: - font=QtGui.QFont(self._theme.FontName, - self._theme.FontProportion, # size + font=QtGui.QFont(self._theme.font_main_name, + int(self._theme.font_main_proportion), # size QtGui.QFont.Normal, # weight 0)# italic # to make the unit tests monitor independent, we have to be able to # specify whether a font proportion is in pixels or points - if self._theme.FontUnits.lower() == "pixels": - log.debug(u"pixels") - if footer: - font.setPixelSize(12) - else: - font.setPixelSize(self._theme.FontProportion) - log.debug(u'Font details %s %s %s %s', self._theme.FontName, self._theme.FontProportion, font.family(), font.pointSize()) + if footer: + font.setPixelSize(int(self._theme.font_footer_proportion)) + else: + font.setPixelSize(int(self._theme.font_main_proportion)) + #log.debug(u'Font details %s %s %s %d', self._theme.font_main_name, self._theme.font_main_proportion, font.family(), font.pointSize()) p.setFont(font) if color == None: - p.setPen(self._theme.FontColor) + if footer: + p.setPen(QtGui.QColor(self._theme.font_footer_color)) + else: + p.setPen(QtGui.QColor(self._theme.font_main_color)) else: - p.setPen(color) + p.setPen(QtGui.QColor(color)) x,y=tlcorner metrics=QtGui.QFontMetrics(font) # xxx some fudges to make it exactly like wx! Take 'em out later w=metrics.width(line) h=metrics.height()-2 - if dodraw: + if draw: p.drawText(x,y+metrics.height()-metrics.descent()-1, line) p.end() return (w, h) diff --git a/openlp/core/theme/theme.py b/openlp/core/theme/theme.py index 27a31c41e..2dc9d701b 100644 --- a/openlp/core/theme/theme.py +++ b/openlp/core/theme/theme.py @@ -35,7 +35,7 @@ blankstylexml=\ ''' class Theme: - def __init__(self, xmlfile=None): + def __init__(self, xml): """ stores the info about a theme attributes: name : theme name @@ -77,11 +77,7 @@ class Theme: """ # init to defaults self._set_from_XML(blankstylexml) - if xmlfile != None: - # init from xmlfile - file=open(xmlfile) - t=''.join(file.readlines()) # read the file and change list to a string - self._set_from_XML(t) + self._set_from_XML(xml) def _get_as_string(self): s="" diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index f4662afb1..6c101a230 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -18,6 +18,7 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ +from amendthemeform import AmendThemeForm from slidecontroller import SlideController from splashscreen import SplashScreen from alertstab import AlertsTab @@ -31,4 +32,4 @@ from thememanager import ThemeManager from mainwindow import MainWindow __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', - 'MainWindow', 'SlideController', 'ServiceManager', 'ThemeManager'] + 'MainWindow', 'SlideController', 'ServiceManager', 'ThemeManager', 'AmendThemeForm'] diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 56904343f..a23f02886 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -39,16 +39,16 @@ class MainWindow(object): def __init__(self): self.main_window = QtGui.QMainWindow() - self.EventManager = EventManager() + self.EventManager = EventManager() self.alert_form = AlertForm() self.about_form = AboutForm() self.settings_form = SettingsForm() - + pluginpath = os.path.split(os.path.abspath(__file__))[0] pluginpath = os.path.abspath(os.path.join(pluginpath, '..', '..','plugins')) self.plugin_manager = PluginManager(pluginpath) self.plugin_helpers = {} - + self.setupUi() log.info(u'Load Plugins') @@ -56,7 +56,7 @@ class MainWindow(object): self.plugin_helpers[u'live'] = self.LiveController self.plugin_helpers[u'event'] = self.EventManager self.plugin_helpers[u'theme'] = self.ThemeManagerContents # Theme manger - + self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers, self.EventManager) # hook methods have to happen after find_plugins. Find plugins needs the controllers # hence the hooks have moved from setupUI() to here @@ -77,9 +77,14 @@ class MainWindow(object): self.plugin_manager.hook_export_menu(self.FileExportMenu) # Call the initialise method to setup plugins. - log.info(u'initialise plugins') + log.info(u'initialise plugins') self.plugin_manager.initialise_plugins() - + + # Once all components are initialised load the Themes + log.info(u'Load Themes') + self.ThemeManagerContents.setEventManager(self.EventManager) + self.ThemeManagerContents.loadThemes() + def setupUi(self): self.main_window.setObjectName("main_window") self.main_window.resize(1087, 847) @@ -176,7 +181,7 @@ class MainWindow(object): self.ServiceManagerContents = ServiceManager(self) self.ServiceManagerDock.setWidget(self.ServiceManagerContents) self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.ServiceManagerDock) - #Theme Manager Defined + #Theme Manager Defined self.ThemeManagerDock = QtGui.QDockWidget(self.main_window) ThemeManagerIcon = QtGui.QIcon() ThemeManagerIcon.addPixmap(QtGui.QPixmap(":/system/system_thememanager.png"), @@ -184,46 +189,12 @@ class MainWindow(object): self.ThemeManagerDock.setWindowIcon(ThemeManagerIcon) self.ThemeManagerDock.setFloating(False) self.ThemeManagerDock.setObjectName("ThemeManagerDock") - - self.ThemeManagerContents = ThemeManager(self) - -# self.ThemeManagerContents = QtGui.QWidget() -# self.ThemeManagerContents.setObjectName("ThemeManagerContents") -# self.ThemeManagerLayout = QtGui.QVBoxLayout(self.ThemeManagerContents) -# self.ThemeManagerLayout.setSpacing(0) -# self.ThemeManagerLayout.setMargin(0) -# self.ThemeManagerLayout.setObjectName("ThemeManagerLayout") -# self.ThemeManagerToolbar = QtGui.QToolBar(self.ThemeManagerContents) -# self.ThemeManagerToolbar.setObjectName("ThemeManagerToolbar") -# NewThemeIcon = QtGui.QIcon() -# NewThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_new.png"), -# QtGui.QIcon.Normal, QtGui.QIcon.Off) -# self.ThemeNewItem = self.ThemeManagerToolbar.addAction(NewThemeIcon, 'New theme') -# EditThemeIcon = QtGui.QIcon() -# EditThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_edit.png"), -# QtGui.QIcon.Normal, QtGui.QIcon.Off) -# self.ThemeEditItem = self.ThemeManagerToolbar.addAction(EditThemeIcon, 'Edit theme') -# DeleteThemeIcon = QtGui.QIcon() -# DeleteThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_delete.png"), -# QtGui.QIcon.Normal, QtGui.QIcon.Off) -# self.ThemeDeleteButton = self.ThemeManagerToolbar.addAction(DeleteThemeIcon, 'Delete theme') -# self.ThemeManagerToolbar.addSeparator() -# ImportThemeIcon = QtGui.QIcon() -# ImportThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_import.png"), -# QtGui.QIcon.Normal, QtGui.QIcon.Off) -# self.ThemeImportButton = self.ThemeManagerToolbar.addAction(ImportThemeIcon, 'Import theme') -# ExportThemeIcon = QtGui.QIcon() -# ExportThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_export.png"), -# QtGui.QIcon.Normal, QtGui.QIcon.Off) -# self.ThemeExportButton = self.ThemeManagerToolbar.addAction(ExportThemeIcon, 'Export theme') -# self.ThemeManagerLayout.addWidget(self.ThemeManagerToolbar) -# self.ThemeManagerListView = QtGui.QListView(self.ThemeManagerContents) -# self.ThemeManagerListView.setObjectName("ThemeManagerListView") -# self.ThemeManagerLayout.addWidget(self.ThemeManagerListView) + + self.ThemeManagerContents = ThemeManager(self) self.ThemeManagerDock.setWidget(self.ThemeManagerContents) self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.ThemeManagerDock) - + self.FileNewItem = QtGui.QAction(self.main_window) self.FileNewItem.setIcon(self.ServiceManagerContents.Toolbar.getIconFromTitle("New Service")) self.FileNewItem.setObjectName("FileNewItem") diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index cc2b7cc58..46638e819 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -28,14 +28,20 @@ from PyQt4 import * from PyQt4 import QtCore, QtGui from PyQt4.QtCore import * from PyQt4.QtGui import * -# from openlp.core.resources import * -# from openlp.core.ui import AboutForm, AlertForm, SettingsForm, SlideController -from openlp.core import translate -from openlp.core.lib import OpenLPToolbar -from openlp.core.utils import ConfigHelper -#from openlp.core.lib import ThemeItem -# from openlp.core import PluginManager +from openlp.core.ui import AmendThemeForm +from openlp.core import translate +from openlp.core import Renderer +from openlp.core.theme import Theme +from openlp.core.lib import Event +from openlp.core.lib import EventType +from openlp.core.lib import EventManager +from openlp.core.lib import OpenLPToolbar +from openlp.core.lib import ThemeXMLBuilder +from openlp.core.lib import ThemeXMLParser +from openlp.core.utils import ConfigHelper + + import logging class ThemeData(QAbstractItemModel): @@ -51,7 +57,7 @@ class ThemeData(QAbstractItemModel): self.items=[] self.rowheight=50 self.maximagewidth=self.rowheight*16/9.0; - log.info("Starting") + log.info(u'Starting') def clearItems(self): self.items=[] @@ -64,9 +70,10 @@ class ThemeData(QAbstractItemModel): def insertRow(self, row, filename): self.beginInsertRows(QModelIndex(),row,row) - log.info("insert row %d:%s"%(row,filename)) + log.info(u'insert row %d:%s'%(row,filename)) (prefix, shortfilename) = os.path.split(str(filename)) - log.info("shortfilename=%s"%(shortfilename)) + log.info(u'shortfilename=%s'%(shortfilename)) + theme = shortfilename.split(u'.') # create a preview image if os.path.exists(filename): preview = QPixmap(str(filename)) @@ -83,8 +90,8 @@ class ThemeData(QAbstractItemModel): p=QPixmap(w,h) p.fill(Qt.transparent) # finally create the row - self.items.insert(row,(filename, p, shortfilename)) - log.info("Items: %s" % self.items) + self.items.insert(row,(filename, p, shortfilename, theme[0])) + log.info(u'Items: %s' % self.items) self.endInsertRows() def removeRow(self, row): @@ -106,7 +113,7 @@ class ThemeData(QAbstractItemModel): 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: - retval= self.items[row][2] + retval= self.items[row][3] elif role == Qt.DecorationRole: retval= self.items[row][1] else: @@ -122,7 +129,7 @@ class ThemeData(QAbstractItemModel): yield i def item(self, row): - log.info("Get Item:%d -> %s" %(row, str(self.items))) + log.info(u'Get Item:%d -> %s' %(row, str(self.items))) return self.items[row] class ThemeManager(QWidget): @@ -138,14 +145,19 @@ class ThemeManager(QWidget): self.Layout = QtGui.QVBoxLayout(self) self.Layout.setSpacing(0) self.Layout.setMargin(0) + self.amendThemeForm = AmendThemeForm() self.Toolbar = OpenLPToolbar(self) - self.Toolbar.addToolbarButton("New Theme", ":/themes/theme_new.png") - self.Toolbar.addToolbarButton("Edit Theme", ":/themes/theme_edit.png") - self.Toolbar.addToolbarButton("Delete Theme", ":/themes/theme_delete.png") + self.Toolbar.addToolbarButton(translate('ThemeManager',u'New Theme'), ":/themes/theme_new.png", + translate('ThemeManager',u'Allows a Theme to be created'), self.onAddTheme) + self.Toolbar.addToolbarButton(translate('ThemeManager',u'Edit Theme'), ":/themes/theme_edit.png", + translate('ThemeManager',u'Allows a Theme to be amended'), self.onEditTheme) + self.Toolbar.addToolbarButton(translate('ThemeManager',u'Delete Theme'), ":/themes/theme_delete.png", + translate('ThemeManager',u'Allows a Theme to be deleted'), self.onDeleteTheme) self.Toolbar.addSeparator() - self.Toolbar.addToolbarButton("Import Theme", ":/themes/theme_import.png", - u'Allows Themes to be imported', self.onImportTheme) - self.Toolbar.addToolbarButton("Export Theme", ":/themes/theme_export.png") + self.Toolbar.addToolbarButton(translate('ThemeManager',u'Import Theme'), ":/themes/theme_import.png", + translate('ThemeManager',u'Allows Themes to be imported'), self.onImportTheme) + self.Toolbar.addToolbarButton(translate('ThemeManager',u'Export Theme'), ":/themes/theme_export.png", + translate('ThemeManager',u'Allows Themes to be exported'), self.onExportTheme) self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar) self.Toolbar.addAction(self.ThemeWidget) @@ -161,62 +173,29 @@ class ThemeManager(QWidget): self.themelist= [] self.path = os.path.join(ConfigHelper.get_data_path(), u'themes') self.checkThemesExists(self.path) - self.loadThemes() # load the themes -# def addThemeItem(self, item): -# """Adds Theme item""" -# log.info("addThemeItem") -# indexes=self.TreeView.selectedIndexes() -# assert len(indexes) <= 1 # can only have one selected index in this view -# if indexes == []: -# log.info("No row") -# row = None -# selected_item = None -# else: -# row=indexes[0].row() -# # if currently selected is of correct type, add it to it -# log.info("row:%d"%row) -# selected_item=self.Theme_data.item(row) -# if type(selected_item) == type(item): -# log.info("Add to existing item") -# selected_item.add(item) -# else: -# log.info("Create new item") -# if row is None: -# self.Theme_data.addRow(item) -# else: -# self.Theme_data.insertRow(row+1, item) -# -# def removeThemeItem(self): -# """Remove currently selected item""" -# pass -# -# def oos_as_text(self): -# text=[] -# log.info( "oos as text") -# log.info("Data:"+str(self.Theme_data)) -# for i in self.Theme_data: -# text.append("# " + str(i)) -# text.append(i.get_oos_text()) -# return '\n'.join(text) -# -# def write_oos(self, filename): -# """ -# Write a full OOS file out - iterate over plugins and call their respective methods -# This format is totally arbitrary testing purposes - something sensible needs to go in here! -# """ -# oosfile=open(filename, "w") -# oosfile.write("# BEGIN OOS\n") -# oosfile.write(self.oos_as_text) -# oosfile.write("# END OOS\n") -# oosfile.close() + def setEventManager(self, eventManager): + self.eventManager = eventManager + + def onAddTheme(self): + self.amendThemeForm.exec_() + + def onEditTheme(self): + self.amendThemeForm.loadTheme(theme) + self.amendThemeForm.exec_() + + def onDeleteTheme(self): + pass + + def onExportTheme(self): + pass def onImportTheme(self): files = QtGui.QFileDialog.getOpenFileNames(None, translate('ThemeManager', u'Select Import File'), self.path, u'Theme (*.theme)') - log.info(u'New Themes) %s', str(files)) + log.info(u'New Themes %s', str(files)) if len(files) > 0: for file in files: self.unzipTheme(file, self.path) @@ -228,9 +207,11 @@ class ThemeManager(QWidget): # self.themelist = [u'African Sunset', u'Snowy Mountains', u'Wilderness', u'Wet and Windy London'] for root, dirs, files in os.walk(self.path): for name in files: - if name.endswith(u'.bmp'): + if name.endswith(u'.png'): self.Theme_data.addRow(os.path.join(self.path, name)) + self.eventManager.post_event(Event(EventType.ThemeListChanged)) + def getThemes(self): return self.themelist @@ -249,16 +230,99 @@ class ThemeManager(QWidget): os.mkdir(os.path.join(dir, file)) else: fullpath = os.path.join(dir, file) + names = file.split(u'/') + xml_data = zip.read(file) if file.endswith(u'.xml'): - self.checkVersion1(fullpath) - outfile = open(fullpath, 'w') - outfile.write(zip.read(file)) - outfile.close() + if self.checkVersion1(xml_data): + filexml = self.migrateVersion122(filename, fullpath, xml_data) + outfile = open(fullpath, 'w') + outfile.write(filexml) + outfile.close() + self.generateImage(dir,names[0], filexml) + else: + if file.endswith(u'.bmp'): + if fullpath is not os.path.join(dir, file): + outfile = open(fullpath, 'w') + outfile.write(zip.read(file)) + outfile.close() def checkVersion1(self, xmlfile): - file=open(xmlfile) - t=''.join(file.readlines()) # read the file and change list to a string + log.debug(u'checkVersion1 ') + t = xmlfile tree = ElementTree(element=XML(t)).getroot() - print "AA" - print tree.find('BackgroundType') - print "AAA" + if tree.find(u'BackgroundType') is None : + return False + else: + return True + + def migrateVersion122(self, filename , fullpath, xml_data): + log.debug(u'migrateVersion122 %s %s', filename , fullpath) + t=Theme(xml_data) + + newtheme = ThemeXMLBuilder() + newtheme.new_document(t.Name) + if t.BackgroundType == 0: + newtheme.add_background_solid(str(t.BackgroundParameter1.name())) + elif t.BackgroundType == 1: + direction = "vertical" + if t.BackgroundParameter1.name() == 1: + direction = "horizontal" + newtheme.add_background_gradient(str(t.BackgroundParameter1.name()), str(t.BackgroundParameter2.name()), direction) + else: + newtheme.add_background_image(str(t.BackgroundParameter1)) + + newtheme.add_font(str(t.FontName), str(t.FontColor.name()), str(t.FontProportion * 2)) + newtheme.add_font(str(t.FontName), str(t.FontColor.name()), str(12), u'footer') + outline = False + shadow = False + if t.Shadow == 1: + shadow = True + if t.Outline == 1: + outline = True + newtheme.add_display(str(shadow), str(t.ShadowColor.name()), str(outline), str(t.OutlineColor.name()), + str(t.HorizontalAlign), str(t.VerticalAlign), str(t.WrapStyle)) + return newtheme.extract_xml() + + def generateImage(self, dir, name, theme_xml): + log.debug(u'generateImage %s %s ', dir, theme_xml) + theme = ThemeXMLParser(theme_xml) + #print theme + size=QtCore.QSize(800,600) + frame=TstFrame(size) + frame=frame + paintdest=frame.GetPixmap() + r=Renderer() + r.set_paint_dest(paintdest) + + r.set_theme(theme) # set default theme + r._render_background() + r.set_text_rectangle(QtCore.QRect(0,0, size.width()-1, size.height()-1)) + + lines=[] + lines.append(u'Amazing Grace!') + lines.append(u'How sweet the sound') + lines.append(u'To save a wretch like me;') + lines.append(u'I once was lost but now am found,') + lines.append(u'Was blind, but now I see.') + + answer=r._render_lines(lines) + r._get_extent_and_render(u'Amazing Grace (John Newton) ', (10, 560), True, None, True) + r._get_extent_and_render(u'CCLI xxx (c)Openlp.org', (10, 580), True, None, True) + + im=frame.GetPixmap().toImage() + testpathname=os.path.join(dir, name+u'.png') + if os.path.exists(testpathname): + os.unlink(testpathname) + im.save(testpathname, u'png') + log.debug(u'Theme image written to %s',testpathname) + + +class TstFrame: + def __init__(self, size): + """Create the DemoPanel.""" + 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): + return self._Buffer diff --git a/openlp/plugins/bibles/lib/biblestab.py b/openlp/plugins/bibles/lib/biblestab.py index 0e3daf476..0f9b3fe03 100644 --- a/openlp/plugins/bibles/lib/biblestab.py +++ b/openlp/plugins/bibles/lib/biblestab.py @@ -68,12 +68,14 @@ class BiblesTab(SettingsTab): self.NewChaptersCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox) self.NewChaptersCheckBox.setObjectName("NewChaptersCheckBox") self.VerseDisplayLayout.addWidget(self.NewChaptersCheckBox, 1, 0, 1, 1) + self.DisplayStyleWidget = QtGui.QWidget(self.VerseDisplayGroupBox) self.DisplayStyleWidget.setObjectName(u'DisplayStyleWidget') self.DisplayStyleLayout = QtGui.QHBoxLayout(self.DisplayStyleWidget) self.DisplayStyleLayout.setSpacing(8) self.DisplayStyleLayout.setMargin(0) self.DisplayStyleLayout.setObjectName(u'DisplayStyleLayout') + self.DisplayStyleLabel = QtGui.QLabel(self.DisplayStyleWidget) self.DisplayStyleLabel.setObjectName(u'DisplayStyleLabel') self.DisplayStyleLayout.addWidget(self.DisplayStyleLabel) @@ -85,9 +87,26 @@ class BiblesTab(SettingsTab): self.DisplayStyleComboBox.addItem(QtCore.QString()) self.DisplayStyleLayout.addWidget(self.DisplayStyleComboBox) self.VerseDisplayLayout.addWidget(self.DisplayStyleWidget, 2, 0, 1, 1) + + self.BibleThemeWidget = QtGui.QWidget(self.VerseDisplayGroupBox) + self.BibleThemeWidget.setObjectName(u'BibleThemeWidget') + self.BibleThemeLayout = QtGui.QHBoxLayout(self.BibleThemeWidget) + self.BibleThemeLayout.setSpacing(8) + self.BibleThemeLayout.setMargin(0) + self.BibleThemeLayout.setObjectName(u'BibleThemeLayout') + + self.BibleThemeLabel = QtGui.QLabel(self.BibleThemeWidget) + self.BibleThemeLabel.setObjectName(u'BibleThemeLabel') + self.BibleThemeLayout.addWidget(self.BibleThemeLabel) + self.BibleThemeComboBox = QtGui.QComboBox(self.BibleThemeWidget) + self.BibleThemeComboBox.setObjectName(u'BibleThemeComboBox') + self.BibleThemeComboBox.addItem(QtCore.QString()) + self.BibleThemeLayout.addWidget(self.BibleThemeComboBox) + self.VerseDisplayLayout.addWidget(self.BibleThemeWidget, 3, 0, 1, 1) + self.ChangeNoteLabel = QtGui.QLabel(self.VerseDisplayGroupBox) self.ChangeNoteLabel.setObjectName(u'ChangeNoteLabel') - self.VerseDisplayLayout.addWidget(self.ChangeNoteLabel, 3, 0, 1, 1) + self.VerseDisplayLayout.addWidget(self.ChangeNoteLabel, 4, 0, 1, 1) self.BibleLeftLayout.addWidget(self.VerseDisplayGroupBox) self.BibleLeftSpacer = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) @@ -132,6 +151,7 @@ class BiblesTab(SettingsTab): self.ParagraphRadioButton.setText(translate('SettingsForm','Paragraph style')) self.NewChaptersCheckBox.setText(translate('SettingsForm', 'Only show new chapter numbers')) self.DisplayStyleLabel.setText(translate('SettingsForm', 'Display Style:')) + self.BibleThemeLabel.setText(translate('SettingsForm', 'Bible Theme:')) self.DisplayStyleComboBox.setItemText(0, translate('SettingsForm', 'No brackets')) self.DisplayStyleComboBox.setItemText(1, translate('SettingsForm', '( and )')) self.DisplayStyleComboBox.setItemText(2, translate('SettingsForm', '{ and }')) @@ -165,6 +185,7 @@ class BiblesTab(SettingsTab): self.paragraph_style = self.convertStringToBoolean(self.config.get_config('paragraph style', u'True')) self.show_new_chapters = self.convertStringToBoolean(self.config.get_config('display new chapter', u"False")) self.display_style = int(self.config.get_config('display brackets', '0')) + self.bible_theme = int(self.config.get_config('bible theme', '0')) self.bible_search = self.convertStringToBoolean(self.config.get_config('search as type', u'True')) if self.paragraph_style: self.ParagraphRadioButton.setChecked(True) @@ -173,9 +194,14 @@ class BiblesTab(SettingsTab): self.NewChaptersCheckBox.setChecked(self.show_new_chapters) self.DisplayStyleComboBox.setCurrentIndex(self.display_style) self.BibleSearchCheckBox.setChecked(self.bible_search) + if self.bible_theme == 0: # must be new set to first + self.BibleThemeComboBox.setCurrentIndex(self.bible_theme) + else: + pass # TODO need to code def save(self): self.config.set_config("paragraph style", str(self.paragraph_style)) self.config.set_config("display new chapter", str(self.show_new_chapters)) self.config.set_config("display brackets", str(self.display_style)) self.config.set_config("search as type", str(self.bible_search)) + self.config.set_config("bible theme", str(self.bible_theme))