Merge lp:~trb143/openlp/ThemeManager into lp:openlp

Proposed by Tim Bentley
Status: Merged
Merge reported by: Tim Bentley
Merged at revision: not available
Proposed branch: lp:~trb143/openlp/ThemeManager
Merge into: lp:openlp
Diff against target: None lines
To merge this branch: bzr merge lp:~trb143/openlp/ThemeManager
Reviewer Review Type Date Requested Status
Tim Bentley Approve
Raoul Snyman Approve
Michael Gorven (community) Needs Fixing
Review via email: mp+5233@code.launchpad.net

This proposal supersedes a proposal from 2009-04-05.

To post a comment you must log in.
Revision history for this message
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

443. By Tim Bentley 3 minutes ago
    Add Eventing after Themes loaded to tell plugins the themes have changed
442. By Tim Bentley 21 hours ago

    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.
434. By Tim Bentley on 2009-03-31

    Finish Import conversions take 1
    Add copyright information

433. By Tim Bentley on 2009-03-29
    Clean Up code style
    Add Theme migration code
    Fixes to Renderer

Revision history for this message
Michael Gorven (mgorven) wrote :

+ file=open(xmlfile)
+ xml =''.join(file.readlines()) # read the file and change list to a
string
+ file.close()
+ return xml

return open(xmlfile).read()

+ #print element.tag, element.text
(and others)

My preference is for debugging prints to either be removed completely, or
logged (possibly at a lower level than DEBUG).

+ words=words.replace(u'\r\n', u'\n')

I don't think this is the right way to deal with line endings. Did this
content come from a file?

+ verses_text=words.split(u'\n\n')

words.splitlines()

+ verses_text.append(u'\n'.join(v).lstrip()) # remove first \n

Why is the lstrip() needed? The join won't put a \n at the front.

+ #log.debug(u'_render_lines %s', lines)
(and others)

Again, either log or remove is my preference.

+ log.info(u'Items: %s' % self.items)
(and others)

log.info('Items: %s', self.items)

+ if file.endswith(u'.bmp'):

That will be case sensitive, which is probably not what we want.

 review needs_fixing

review: Needs Fixing
Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

If you can compress the opening and reading of a file into "open(filename).read()" what is the need for the "fileToXML" method?

What's the need for two theme XML classes? I would suggest having a single ThemeXML class which has a "build()" and a "parse()" method.

Also just remember that when you're passing named parameters in a method, you don't need spaces between the parameter name and the value:
e.g.

  self.do_method(parameter=value)

review: Approve
Revision history for this message
Tim Bentley (trb143) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/__init__.py'
2--- openlp/core/__init__.py 2009-02-28 23:19:45 +0000
3+++ openlp/core/__init__.py 2009-04-03 19:32:00 +0000
4@@ -23,7 +23,14 @@
5 from settingsmanager import SettingsManager
6 from pluginmanager import PluginManager
7
8-__all__ = ['Renderer', 'SettingsManager', 'PluginManager', 'translate']
9+__all__ = ['Renderer', 'SettingsManager', 'PluginManager', 'translate', 'fileToXML']
10
11 def translate(context, text):
12 return QtGui.QApplication.translate(context, text, None, QtGui.QApplication.UnicodeUTF8)
13+
14+def fileToXML(xmlfile):
15+ file=open(xmlfile)
16+ xml =''.join(file.readlines()) # read the file and change list to a string
17+ file.close()
18+ return xml
19+
20
21=== modified file 'openlp/core/lib/event.py' (properties changed: -x to +x)
22--- openlp/core/lib/event.py 2009-03-23 20:18:06 +0000
23+++ openlp/core/lib/event.py 2009-04-05 18:46:42 +0000
24@@ -41,6 +41,8 @@
25 PreviewBeforeShow = 13
26 PreviewAfterShow = 14
27
28+ ThemeListChanged = 15
29+
30
31 class Event(object):
32 """
33@@ -49,6 +51,6 @@
34 def __init__(self, event_type=EventType.Default, payload=None):
35 self.event_type = event_type
36 self.payload = payload
37-
38+
39 def get_type(self):
40 return self.event_type
41
42=== modified file 'openlp/core/lib/eventmanager.py'
43--- openlp/core/lib/eventmanager.py 2009-03-25 20:30:48 +0000
44+++ openlp/core/lib/eventmanager.py 2009-03-30 19:58:34 +0000
45@@ -26,21 +26,21 @@
46 A mechanism to send events to all registered endpoints
47 the endpoints are registered and listen with a handle_event method
48 the endpoint will decide whether to do somthing with the event or ignore it
49-
50+
51 """
52 global log
53 log=logging.getLogger(u'EventManager')
54-
55+
56 def __init__(self):
57 self.endpoints=[]
58 log.info(u'Initialising')
59-
60+
61 def register(self, plugin):
62- log.debug(u'plugin %s registered with EventManager'%plugin)
63+ log.debug(u'plugin %s registered with EventManager', plugin)
64 self.endpoints.append(plugin)
65-
66+
67 def post_event(self, event):
68- log.debug(u'post event called for event %s'%event.get_type)
69+ log.debug(u'post event called for event %s', event.get_type)
70 for point in self.endpoints:
71 point.handle_event(event)
72
73
74=== modified file 'openlp/core/lib/songxmlhandler.py'
75--- openlp/core/lib/songxmlhandler.py 2009-03-14 07:08:15 +0000
76+++ openlp/core/lib/songxmlhandler.py 2009-03-31 20:16:54 +0000
77@@ -1,6 +1,24 @@
78+# -*- coding: utf-8 -*-
79+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
80+"""
81+OpenLP - Open Source Lyrics Projection
82+Copyright (c) 2008 Raoul Snyman
83+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten Tinggaard
84+
85+This program is free software; you can redistribute it and/or modify it under
86+the terms of the GNU General Public License as published by the Free Software
87+Foundation; version 2 of the License.
88+
89+This program is distributed in the hope that it will be useful, but WITHOUT ANY
90+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
91+PARTICULAR PURPOSE. See the GNU General Public License for more details.
92+
93+You should have received a copy of the GNU General Public License along with
94+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
95+Place, Suite 330, Boston, MA 02111-1307 USA
96 from xml.dom.minidom import Document
97 from xml.etree.ElementTree import ElementTree, XML, dump
98-"""
99+
100 <?xml version="1.0" encoding="UTF-8"?>
101 <song version="1.0">
102 <lyrics language="en">
103@@ -11,24 +29,27 @@
104 </song>
105
106 """
107+from xml.dom.minidom import Document
108+from xml.etree.ElementTree import ElementTree, XML, dump
109+
110 class SongXMLBuilder():
111 def __init__(self):
112- # Create the minidom document
113+ # Create the minidom document
114 self.song_xml = Document()
115-
116+
117 def new_document(self):
118 # Create the <song> base element
119 self.song = self.song_xml.createElement(u'song')
120 self.song_xml.appendChild(self.song)
121 self.song.setAttribute(u'version', u'1.0')
122-
123+
124 def add_lyrics_to_song(self):
125 # Create the main <lyrics> element
126 self.lyrics = self.song_xml.createElement(u'lyrics')
127 self.lyrics.setAttribute(u'language', u'en')
128 self.song.appendChild(self.lyrics)
129-
130- def add_verse_to_lyrics(self, type, number, content):
131+
132+ def add_verse_to_lyrics(self, type, number, content):
133 """
134 type - type of verse (Chorus, Verse , Bridge, Custom etc
135 number - number of item eg verse 1
136@@ -36,34 +57,34 @@
137 """
138 verse = self.song_xml.createElement(u'verse')
139 verse.setAttribute(u'type', type)
140- verse.setAttribute(u'label', number)
141+ verse.setAttribute(u'label', number)
142 self.lyrics.appendChild(verse)
143-
144+
145 # add data as a CDATA section
146 cds = self.song_xml.createCDATASection(content)
147 verse.appendChild(cds)
148-
149+
150 def dump_xml(self):
151 # Debugging aid to see what we have
152 print self.song_xml.toprettyxml(indent=" ")
153-
154+
155 def extract_xml(self):
156 # Print our newly created XML
157 return self.song_xml.toxml()
158-
159+
160 class SongXMLParser():
161 def __init__(self, xml):
162 self.song_xml = ElementTree(element=XML(xml))
163-
164+
165 def get_verses(self):
166 #return a list of verse's and attributes
167 iter=self.song_xml.getiterator()
168 verse_list = []
169- for element in iter:
170+ for element in iter:
171 if element.tag == u'verse':
172 verse_list.append([element.attrib, element.text])
173 return verse_list
174-
175+
176 def dump_xml(self):
177 # Debugging aid to see what we have
178 print dump(self.song_xml)
179
180=== modified file 'openlp/core/lib/themexmlhandler.py'
181--- openlp/core/lib/themexmlhandler.py 2009-03-28 20:12:22 +0000
182+++ openlp/core/lib/themexmlhandler.py 2009-04-04 17:36:15 +0000
183@@ -1,16 +1,29 @@
184-from xml.dom.minidom import Document
185-from xml.etree.ElementTree import ElementTree, XML, dump
186-"""
187-<?xml version="1.0" encoding="UTF-8"?>
188-<song version="1.0">
189- <lyrics language="en">
190- <verse type="chorus" label="1">
191- <![CDATA[ ... ]]>
192- </verse>
193- </lyrics>
194-</song>
195-
196-"""
197+# -*- coding: utf-8 -*-
198+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
199+"""
200+OpenLP - Open Source Lyrics Projection
201+Copyright (c) 2008 Raoul Snyman
202+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten Tinggaard
203+
204+This program is free software; you can redistribute it and/or modify it under
205+the terms of the GNU General Public License as published by the Free Software
206+Foundation; version 2 of the License.
207+
208+This program is distributed in the hope that it will be useful, but WITHOUT ANY
209+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
210+PARTICULAR PURPOSE. See the GNU General Public License for more details.
211+
212+You should have received a copy of the GNU General Public License along with
213+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
214+Place, Suite 330, Boston, MA 02111-1307 USA
215+from xml.dom.minidom import Document
216+from xml.etree.ElementTree import ElementTree, XML, dump
217+
218+For XML Schema see wiki.openlp.org
219+"""
220+from xml.dom.minidom import Document
221+from xml.etree.ElementTree import ElementTree, XML, dump
222+
223 class ThemeXMLBuilder():
224 def __init__(self):
225 # Create the minidom document
226@@ -29,12 +42,12 @@
227
228 def add_background_transparent(self):
229 # Create the main <lyrics> element
230- background = self.theme_xml.createElement(u'Background')
231+ background = self.theme_xml.createElement(u'background')
232 background.setAttribute(u'mode', u'transparent')
233 self.theme.appendChild(background)
234
235 def add_background_solid(self, bkcolor):
236- background = self.theme_xml.createElement(u'Background')
237+ background = self.theme_xml.createElement(u'background')
238 background.setAttribute(u'mode', u'opaque')
239 background.setAttribute(u'type', u'solid')
240 self.theme.appendChild(background)
241@@ -44,24 +57,29 @@
242 color.appendChild(bkc)
243 background.appendChild(color)
244
245- def add_background_gradient(self, startcolor, endcolor):
246- background = self.theme_xml.createElement(u'Background')
247+ def add_background_gradient(self, startcolor, endcolor, direction):
248+ background = self.theme_xml.createElement(u'background')
249 background.setAttribute(u'mode', u'opaque')
250- background.setAttribute(u'type', u'gradient')
251+ background.setAttribute(u'type', u'Gradient')
252 self.theme.appendChild(background)
253
254- color = self.theme_xml.createElement(u'startcolor')
255+ color = self.theme_xml.createElement(u'startColor')
256 bkc = self.theme_xml.createTextNode(startcolor)
257 color.appendChild(bkc)
258 background.appendChild(color)
259
260- color = self.theme_xml.createElement(u'endcolor')
261+ color = self.theme_xml.createElement(u'endColor')
262 bkc = self.theme_xml.createTextNode(endcolor)
263 color.appendChild(bkc)
264 background.appendChild(color)
265
266- def add_background_image(self, filename, bordercolor):
267- background = self.theme_xml.createElement(u'Background')
268+ color = self.theme_xml.createElement(u'direction')
269+ bkc = self.theme_xml.createTextNode(direction)
270+ color.appendChild(bkc)
271+ background.appendChild(color)
272+
273+ def add_background_image(self, filename):
274+ background = self.theme_xml.createElement(u'background')
275 background.setAttribute(u'mode', u'opaque')
276 background.setAttribute(u'type', u'image')
277 self.theme.appendChild(background)
278@@ -71,26 +89,62 @@
279 color.appendChild(bkc)
280 background.appendChild(color)
281
282- color = self.theme_xml.createElement(u'bordercolor')
283- bkc = self.theme_xml.createTextNode(bordercolor)
284- color.appendChild(bkc)
285- background.appendChild(color)
286-
287-
288- def add_verse_to_lyrics(self, type, number, content):
289- """
290- type - type of verse (Chorus, Verse , Bridge, Custom etc
291- number - number of item eg verse 1
292- content - the text to be stored
293- """
294- verse = self.theme_xml.createElement(u'verse')
295- verse.setAttribute(u'type', type)
296- verse.setAttribute(u'label', number)
297- self.lyrics.appendChild(verse)
298-
299- # add data as a CDATA section
300- cds = self.theme_xml.createCDATASection(content)
301- verse.appendChild(cds)
302+ def add_font(self, fontname, fontcolor, fontproportion, fonttype=u'main'):
303+ background = self.theme_xml.createElement(u'font')
304+ background.setAttribute(u'type',fonttype)
305+ self.theme.appendChild(background)
306+
307+ name = self.theme_xml.createElement(u'name')
308+ fn = self.theme_xml.createTextNode(fontname)
309+ name.appendChild(fn)
310+ background.appendChild(name)
311+
312+ name = self.theme_xml.createElement(u'color')
313+ fn = self.theme_xml.createTextNode(fontcolor)
314+ name.appendChild(fn)
315+ background.appendChild(name)
316+
317+ name = self.theme_xml.createElement(u'proportion')
318+ fn = self.theme_xml.createTextNode(fontproportion)
319+ name.appendChild(fn)
320+ background.appendChild(name)
321+
322+ def add_display(self, shadow, shadowColor, outline, outlineColor, horizontal, vertical, wrap):
323+ background = self.theme_xml.createElement(u'display')
324+ self.theme.appendChild(background)
325+
326+ tagElement = self.theme_xml.createElement(u'shadow')
327+ tagElement.setAttribute(u'color',shadowColor)
328+ tagValue = self.theme_xml.createTextNode(shadow)
329+ tagElement.appendChild(tagValue)
330+ background.appendChild(tagElement)
331+
332+ tagElement = self.theme_xml.createElement(u'outline')
333+ tagElement.setAttribute(u'color',outlineColor)
334+ tagValue = self.theme_xml.createTextNode(outline)
335+ tagElement.appendChild(tagValue)
336+ background.appendChild(tagElement)
337+
338+ tagElement = self.theme_xml.createElement(u'horizontalAlign')
339+ tagValue = self.theme_xml.createTextNode(horizontal)
340+ tagElement.appendChild(tagValue)
341+ background.appendChild(tagElement)
342+
343+ tagElement = self.theme_xml.createElement(u'verticalAlign')
344+ tagValue = self.theme_xml.createTextNode(vertical)
345+ tagElement.appendChild(tagValue)
346+ background.appendChild(tagElement)
347+
348+ tagElement = self.theme_xml.createElement(u'wrapStyle')
349+ tagValue = self.theme_xml.createTextNode(wrap)
350+ tagElement.appendChild(tagValue)
351+ background.appendChild(tagElement)
352+
353+ def child_element(self, tag, value):
354+ tagElement = self.theme_xml.createElement(tag)
355+ tagValue = self.theme_xml.createTextNode(value)
356+ tagElement.appendChild(ftagValue)
357+ self.background.appendChild(tagElement)
358
359 def dump_xml(self):
360 # Debugging aid to see what we have
361@@ -102,17 +156,35 @@
362
363 class ThemeXMLParser():
364 def __init__(self, xml):
365- self.theme_xml = ElementTree(element=XML(xml))
366-
367- def get_verses(self):
368- #return a list of verse's and attributes
369- iter=self.theme_xml.getiterator()
370- verse_list = []
371+ theme_xml = ElementTree(element=XML(xml))
372+ iter=theme_xml.getiterator()
373+ master = u''
374 for element in iter:
375- if element.tag == u'verse':
376- verse_list.append([element.attrib, element.text])
377- return verse_list
378+ #print element.tag, element.text
379+ if len(element.getchildren()) > 0:
380+ master= element.tag + u'_'
381+ if len(element.attrib) > 0:
382+ #print "D", element.tag , element.attrib
383+ for e in element.attrib.iteritems():
384+ #print "A", master, e[0], e[1]
385+ if master == u'font_' and e[0] == u'type':
386+ master += e[1] + u'_'
387+ elif master == u'display_' and (element.tag == u'shadow' or element.tag == u'outline'):
388+ #print "b", master, element.tag, element.text, e[0], e[1]
389+ setattr(self, master + element.tag , element.text)
390+ setattr(self, master + element.tag +u'_'+ e[0], e[1])
391+ else:
392+ field = master + e[0]
393+ setattr(self, field, e[1])
394+ else:
395+ #print "c", element.tag
396+ if element.tag is not None :
397+ field = master + element.tag
398+ setattr(self, field, element.text)
399
400- def dump_xml(self):
401- # Debugging aid to see what we have
402- print dump(self.theme_xml)
403+ def __str__(self):
404+ s = u''
405+ for k in dir(self):
406+ if k[0:1] != u'_':
407+ s+= u'%30s : %s\n' %(k,getattr(self,k))
408+ return s
409
410=== modified file 'openlp/core/render.py'
411--- openlp/core/render.py 2009-03-29 16:51:42 +0000
412+++ openlp/core/render.py 2009-04-04 17:36:15 +0000
413@@ -56,11 +56,11 @@
414
415 def set_theme(self, theme):
416 self._theme=theme
417- if theme.BackgroundType == 2:
418- self.set_bg_image(theme.BackgroundParameter1)
419+ if theme.background_type == u'image':
420+ self.set_bg_image(theme.background_filename)
421
422 def set_bg_image(self, filename):
423- log.debug(u"set bg image %s", filename)
424+ log.debug(u'set bg image %s', filename)
425 self._bg_image_filename=filename
426 if self._paint is not None:
427 self.scale_bg_image()
428@@ -69,11 +69,13 @@
429 assert self._paint
430 i=QtGui.QImage(self._bg_image_filename)
431 # rescale and offset
432- imw=i.width();imh=i.height()
433- dcw=self._paint.width()+1;dch=self._paint.height()
434+ imw=i.width()
435+ imh=i.height()
436+ dcw=self._paint.width()+1
437+ dch=self._paint.height()
438 imratio=imw/float(imh)
439 dcratio=dcw/float(dch)
440- log.debug(u"Image scaling params %s %s %s %s %s %s", imw, imh, imratio, dcw, dch, dcratio)
441+ log.debug(u'Image scaling params %s %s %s %s %s %s', imw, imh, imratio, dcw, dch, dcratio)
442 if imratio > dcratio:
443 scale=dcw/float(imw)
444 elif imratio < dcratio:
445@@ -94,20 +96,20 @@
446 def set_words_openlp(self, words):
447 # log.debug(u" "set words openlp", words
448 verses=[]
449- words=words.replace("\r\n", "\n")
450- verses_text=words.split('\n\n')
451+ words=words.replace(u'\r\n', u'\n')
452+ verses_text=words.split(u'\n\n')
453 for v in verses_text:
454- lines=v.split('\n')
455+ lines=v.split(u'\n')
456 verses.append(self.split_set_of_lines(lines)[0])
457 self.words=verses
458 verses_text=[]
459 for v in verses:
460- verses_text.append('\n'.join(v).lstrip()) # remove first \n
461+ verses_text.append(u'\n'.join(v).lstrip()) # remove first \n
462
463 return verses_text
464
465 def render_screen(self, screennum):
466- log.debug(u"render screen\n %s %s ", screennum, self.words[screennum])
467+ log.debug(u'render screen\n %s %s ', screennum, self.words[screennum])
468 import time
469 t=0.0
470 words=self.words[screennum]
471@@ -121,40 +123,49 @@
472 def _render_background(self):
473 assert(self._theme)
474 assert(self._paint)
475- log.debug(u"render background %s %s", self._theme.BackgroundType)
476+ log.debug(u'render background %s ', self._theme.background_type)
477 p=QtGui.QPainter()
478 p.begin(self._paint)
479- if self._theme.BackgroundType == 0:
480- p.fillRect(self._paint.rect(), self._theme.BackgroundParameter1)
481- elif self._theme.BackgroundType == 1: # gradient
482- #TODO Add Theme code and fix direction
483-
484- gradient = QtGui.QLinearGradient(0, 0, self._paint.width(), self._paint.height())
485- gradient.setColorAt(0, QtGui.QColor(255, 0, 0))
486- gradient.setColorAt(0.5, QtGui.QColor(0, 255, 0))
487- gradient.setColorAt(1, QtGui.QColor(0, 0, 255))
488+ if self._theme.background_type == u'solid':
489+ p.fillRect(self._paint.rect(), QtGui.QColor(self._theme.background_color))
490+ elif self._theme.background_type == u'Gradient' : # gradient
491+ gradient = None
492+ if self._theme.background_direction == u'vertical':
493+ w = int(self._paint.width())/2
494+ gradient = QtGui.QLinearGradient(w, 0, w, self._paint.height()) # vertical
495+ elif self._theme.background_direction == u'horizontal':
496+ h = int(self._paint.height())/2
497+ gradient = QtGui.QLinearGradient(0, h, self._paint.width(), h) # Horizontal
498+ else:
499+ w = int(self._paint.width())/2
500+ h = int(self._paint.height())/2
501+ gradient = QtGui.QRadialGradient(w, h, w) # Circular
502+
503+ gradient.setColorAt(0, QtGui.QColor(self._theme.background_startColor))
504+ gradient.setColorAt(1, QtGui.QColor(self._theme.background_endColor))
505+
506 p.setBrush(QtGui.QBrush(gradient))
507 rectPath = QtGui.QPainterPath()
508
509- MAX_X = self._paint.width()
510- MAX_Y = self._paint.height()
511-
512+ max_x = self._paint.width()
513+ max_y = self._paint.height()
514 rectPath.moveTo(0, 0)
515- rectPath.lineTo(0, MAX_Y)
516- rectPath.lineTo(MAX_X, MAX_Y)
517- rectPath.lineTo(MAX_X, 0)
518+ rectPath.lineTo(0, max_y)
519+ rectPath.lineTo(max_x, max_y)
520+ rectPath.lineTo(max_x, 0)
521+
522 rectPath.closeSubpath()
523 p.drawPath(rectPath)
524
525- elif self._theme.BackgroundType == 2: # image
526+ elif self._theme.background_type== u'image': # image
527 r=self._paint.rect()
528- log.debug(r.x(), r.y(), r.width(),r.height())
529- log.debug(self._theme.BackgroundParameter2)
530- if self._theme.BackgroundParameter2 is not None:
531- p.fillRect(self._paint.rect(), self._theme.BackgroundParameter2)
532+ log.debug(u'Image size details %d %d %d %d ', r.x(), r.y(), r.width(),r.height())
533+ log.debug(u' Background Parameter %d ', self._theme.background_borderColor)
534+ if self._theme.Bbackground_borderColor is not None:
535+ p.fillRect(self._paint.rect(), self._theme.background_borderColor)
536 p.drawPixmap(self.background_offsetx,self.background_offsety, self.img)
537 p.end()
538- log.debug(u"render background done")
539+ log.debug(u'render background done')
540
541 def split_set_of_lines(self, lines):
542
543@@ -221,24 +232,23 @@
544
545 def _render_lines(self, lines):
546 """render a set of lines according to the theme, return bounding box"""
547- log.debug(u"_render_lines %s", lines)
548+ #log.debug(u'_render_lines %s', lines)
549
550 bbox=self._render_lines_unaligned(lines)
551- print bbox
552
553 t=self._theme
554 x=self._rect.left()
555- if t.VerticalAlign==0: # top align
556+ if int(t.display_verticalAlign) == 0: # top align
557 y = self._rect.top()
558- elif t.VerticalAlign==1: # bottom align
559+ elif int(t.display_verticalAlign) == 1: # bottom align
560 y=self._rect.bottom()-bbox.height()
561- elif t.VerticalAlign==2: # centre align
562+ elif int(t.display_verticalAlign) == 2: # centre align
563 y=self._rect.top()+(self._rect.height()-bbox.height())/2
564 else:
565- assert(0, "Invalid value for theme.VerticalAlign:%d" % t.VerticalAlign)
566+ assert(0, u'Invalid value for theme.VerticalAlign:%s' % t.display_verticalAlign)
567 self._render_background()
568 bbox=self._render_lines_unaligned(lines, (x,y))
569- log.debug(u"render lines DONE")
570+ log.debug(u'render lines DONE')
571
572 return bbox
573
574@@ -250,7 +260,7 @@
575 than a screenful (eg. by using split_set_of_lines)
576
577 Returns the bounding box of the text as QRect"""
578- log.debug(u"render unaligned %s", lines)
579+ log.debug(u'render unaligned %s', lines)
580 x,y=tlcorner
581 brx=x
582 bry=y
583@@ -269,7 +279,7 @@
584 p.setPen(QtGui.QPen(QtGui.QColor(0,0,255)))
585 p.drawRect(retval)
586 p.end()
587- log.debug(u"render unaligned DONE")
588+ log.debug(u'render unaligned DONE')
589
590 return retval
591
592@@ -283,7 +293,7 @@
593
594 Returns the bottom-right corner (of what was rendered) as a tuple(x,y).
595 """
596- log.debug(u"Render single line '%s' @ %s "%( line, tlcorner))
597+ #log.debug(u'Render single line %s @ %s '%( line, tlcorner))
598 x,y=tlcorner
599 # We draw the text to see how big it is and then iterate to make it fit
600 # when we line wrap we do in in the "lyrics" style, so the second line is
601@@ -291,8 +301,8 @@
602
603 # get the words
604 # log.debug(u" "Getting the words split right"
605- words=line.split(" ")
606- thisline=' '.join(words)
607+ words=line.split(u' ')
608+ thisline=u' '.join(words)
609 lastword=len(words)
610 lines=[]
611 maxx=self._rect.width(); maxy=self._rect.height();
612@@ -307,25 +317,22 @@
613 else:
614 lastword-=1
615 thisline=' '.join(words[:lastword])
616-
617-# log.debug(u" "This is how they split", lines
618-# log.debug(u" "Now render them"
619 startx=x
620 starty=y
621 rightextent=None
622 t=self._theme
623- align=t.HorizontalAlign
624- wrapstyle=t.WrapStyle
625+ align=t.display_horizontalAlign
626+ wrapstyle=t.display_wrapStyle
627
628 for linenum in range(len(lines)):
629 line=lines[linenum]
630 #find out how wide line is
631- w,h=self._get_extent_and_render(line, tlcorner=(x,y), dodraw=False)
632+ w,h=self._get_extent_and_render(line, tlcorner=(x,y), draw=False)
633
634- if t.Shadow:
635+ if t.display_shadow:
636 w+=self._shadow_offset
637 h+=self._shadow_offset
638- if t.Outline:
639+ if t.display_outline:
640 w+=2*self._outline_offset # pixels either side
641 h+=2*self._outline_offset # pixels top/bottom
642 if align==0: # left align
643@@ -343,21 +350,22 @@
644 x=(maxx-w)/2;
645 rightextent=x+w
646 # now draw the text, and any outlines/shadows
647- if t.Shadow:
648- self._get_extent_and_render(line, tlcorner=(x+self._shadow_offset,y+self._shadow_offset), dodraw=True, color = t.ShadowColor)
649- if t.Outline:
650- self._get_extent_and_render(line, (x+self._outline_offset,y), dodraw=True, color = t.OutlineColor)
651- self._get_extent_and_render(line, (x,y+self._outline_offset), dodraw=True, color = t.OutlineColor)
652- self._get_extent_and_render(line, (x,y-self._outline_offset), dodraw=True, color = t.OutlineColor)
653- self._get_extent_and_render(line, (x-self._outline_offset,y), dodraw=True, color = t.OutlineColor)
654+ if t.display_shadow:
655+ self._get_extent_and_render(line, tlcorner=(x+self._shadow_offset,y+self._shadow_offset),
656+ draw=True, color = t.display_shadow_color)
657+ if t.display_outline:
658+ self._get_extent_and_render(line, (x+self._outline_offset,y), draw=True, color = t.display_outline_color)
659+ self._get_extent_and_render(line, (x,y+self._outline_offset), draw=True, color = t.display_outline_color)
660+ self._get_extent_and_render(line, (x,y-self._outline_offset), draw=True, color = t.display_outline_color)
661+ self._get_extent_and_render(line, (x-self._outline_offset,y), draw=True, color = t.display_outline_color)
662 if self._outline_offset > 1:
663- self._get_extent_and_render(line, (x+self._outline_offset,y+self._outline_offset), dodraw=True, color = t.OutlineColor)
664- self._get_extent_and_render(line, (x-self._outline_offset,y+self._outline_offset), dodraw=True, color = t.OutlineColor)
665- self._get_extent_and_render(line, (x+self._outline_offset,y-self._outline_offset), dodraw=True, color = t.OutlineColor)
666- self._get_extent_and_render(line, (x-self._outline_offset,y-self._outline_offset), dodraw=True, color = t.OutlineColor)
667+ self._get_extent_and_render(line, (x+self._outline_offset,y+self._outline_offset), draw=True, color = t.display_outline_color)
668+ self._get_extent_and_render(line, (x-self._outline_offset,y+self._outline_offset), draw=True, color = t.display_outline_color)
669+ self._get_extent_and_render(line, (x+self._outline_offset,y-self._outline_offset), draw=True, color = t.display_outline_color)
670+ self._get_extent_and_render(line, (x-self._outline_offset,y-self._outline_offset), draw=True, color = t.display_outline_color)
671
672- self._get_extent_and_render(line, tlcorner=(x,y), dodraw=True)
673-# log.debug(u" "Line %2d: Render '%s' at (%d, %d) wh=(%d,%d)"%( linenum, line, x, y,w,h)
674+ self._get_extent_and_render(line, tlcorner=(x,y), draw=True)
675+# log.debug(u'Line %2d: Render '%s' at (%d, %d) wh=(%d,%d)' % ( linenum, line, x, y,w,h)
676 y += h
677 if linenum == 0:
678 self._first_line_right_extent=rightextent
679@@ -373,47 +381,48 @@
680 return brcorner
681
682 # xxx this is what to override for an SDL version
683- def _get_extent_and_render(self, line, tlcorner=(0,0), dodraw=False, color=None, footer = False):
684+ def _get_extent_and_render(self, line, tlcorner=(0,0), draw=False, color=None, footer=False):
685 """Find bounding box of text - as render_single_line.
686- If dodraw is set, actually draw the text to the current DC as well
687+ If draw is set, actually draw the text to the current DC as well
688
689 return width and height of text as a tuple (w,h)"""
690 # setup defaults
691- log.debug(u"_get_extent_and_render %s %s %s ", [line], tlcorner, dodraw)
692+ #log.debug(u"_get_extent_and_render %s %s %s ", [line], tlcorner, draw)
693 p=QtGui.QPainter()
694 p.begin(self._paint)
695 # 'twould be more efficient to set this once when theme changes
696 # or p changes
697 if footer :
698- font=QtGui.QFont(self._theme.FontName,
699- 12, # size
700+ font=QtGui.QFont(self._theme.font_footer_name,
701+ int(self._theme.font_footer_proportion), # size
702 QtGui.QFont.Normal, # weight
703 0)# italic
704 else:
705- font=QtGui.QFont(self._theme.FontName,
706- self._theme.FontProportion, # size
707+ font=QtGui.QFont(self._theme.font_main_name,
708+ int(self._theme.font_main_proportion), # size
709 QtGui.QFont.Normal, # weight
710 0)# italic
711 # to make the unit tests monitor independent, we have to be able to
712 # specify whether a font proportion is in pixels or points
713- if self._theme.FontUnits.lower() == "pixels":
714- log.debug(u"pixels")
715- if footer:
716- font.setPixelSize(12)
717- else:
718- font.setPixelSize(self._theme.FontProportion)
719- log.debug(u'Font details %s %s %s %s', self._theme.FontName, self._theme.FontProportion, font.family(), font.pointSize())
720+ if footer:
721+ font.setPixelSize(int(self._theme.font_footer_proportion))
722+ else:
723+ font.setPixelSize(int(self._theme.font_main_proportion))
724+ #log.debug(u'Font details %s %s %s %d', self._theme.font_main_name, self._theme.font_main_proportion, font.family(), font.pointSize())
725 p.setFont(font)
726 if color == None:
727- p.setPen(self._theme.FontColor)
728+ if footer:
729+ p.setPen(QtGui.QColor(self._theme.font_footer_color))
730+ else:
731+ p.setPen(QtGui.QColor(self._theme.font_main_color))
732 else:
733- p.setPen(color)
734+ p.setPen(QtGui.QColor(color))
735 x,y=tlcorner
736 metrics=QtGui.QFontMetrics(font)
737 # xxx some fudges to make it exactly like wx! Take 'em out later
738 w=metrics.width(line)
739 h=metrics.height()-2
740- if dodraw:
741+ if draw:
742 p.drawText(x,y+metrics.height()-metrics.descent()-1, line)
743 p.end()
744 return (w, h)
745
746=== modified file 'openlp/core/theme/theme.py'
747--- openlp/core/theme/theme.py 2009-03-29 14:38:23 +0000
748+++ openlp/core/theme/theme.py 2009-04-03 19:32:00 +0000
749@@ -35,7 +35,7 @@
750 '''
751
752 class Theme:
753- def __init__(self, xmlfile=None):
754+ def __init__(self, xml):
755 """ stores the info about a theme
756 attributes:
757 name : theme name
758@@ -77,11 +77,7 @@
759 """
760 # init to defaults
761 self._set_from_XML(blankstylexml)
762- if xmlfile != None:
763- # init from xmlfile
764- file=open(xmlfile)
765- t=''.join(file.readlines()) # read the file and change list to a string
766- self._set_from_XML(t)
767+ self._set_from_XML(xml)
768
769 def _get_as_string(self):
770 s=""
771
772=== modified file 'openlp/core/ui/__init__.py'
773--- openlp/core/ui/__init__.py 2009-03-22 07:11:05 +0000
774+++ openlp/core/ui/__init__.py 2009-04-04 17:36:15 +0000
775@@ -18,6 +18,7 @@
776 Place, Suite 330, Boston, MA 02111-1307 USA
777 """
778
779+from amendthemeform import AmendThemeForm
780 from slidecontroller import SlideController
781 from splashscreen import SplashScreen
782 from alertstab import AlertsTab
783@@ -31,4 +32,4 @@
784 from mainwindow import MainWindow
785
786 __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm',
787- 'MainWindow', 'SlideController', 'ServiceManager', 'ThemeManager']
788+ 'MainWindow', 'SlideController', 'ServiceManager', 'ThemeManager', 'AmendThemeForm']
789
790=== added file 'openlp/core/ui/amendthemedialog.py'
791--- openlp/core/ui/amendthemedialog.py 1970-01-01 00:00:00 +0000
792+++ openlp/core/ui/amendthemedialog.py 2009-04-04 17:36:15 +0000
793@@ -0,0 +1,282 @@
794+# -*- coding: utf-8 -*-
795+
796+# Form implementation generated from reading ui file 'amendthemedialog.ui'
797+#
798+# Created: Sat Apr 4 18:09:38 2009
799+# by: PyQt4 UI code generator 4.4.4
800+#
801+# WARNING! All changes made in this file will be lost!
802+
803+from PyQt4 import QtCore, QtGui
804+
805+class Ui_AmendThemeDialog(object):
806+ def setupUi(self, AmendThemeDialog):
807+ AmendThemeDialog.setObjectName("AmendThemeDialog")
808+ AmendThemeDialog.resize(752, 533)
809+ icon = QtGui.QIcon()
810+ icon.addPixmap(QtGui.QPixmap(":/icon/openlp.org-icon-32.bmp"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
811+ AmendThemeDialog.setWindowIcon(icon)
812+ self.ThemeButtonBox = QtGui.QDialogButtonBox(AmendThemeDialog)
813+ self.ThemeButtonBox.setGeometry(QtCore.QRect(580, 500, 156, 26))
814+ self.ThemeButtonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
815+ self.ThemeButtonBox.setObjectName("ThemeButtonBox")
816+ self.layoutWidget = QtGui.QWidget(AmendThemeDialog)
817+ self.layoutWidget.setGeometry(QtCore.QRect(30, 70, 691, 401))
818+ self.layoutWidget.setObjectName("layoutWidget")
819+ self.horizontalLayout_2 = QtGui.QHBoxLayout(self.layoutWidget)
820+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
821+ self.LeftSide = QtGui.QWidget(self.layoutWidget)
822+ self.LeftSide.setObjectName("LeftSide")
823+ self.tabWidget = QtGui.QTabWidget(self.LeftSide)
824+ self.tabWidget.setGeometry(QtCore.QRect(0, 0, 341, 401))
825+ self.tabWidget.setObjectName("tabWidget")
826+ self.BackgroundTab = QtGui.QWidget()
827+ self.BackgroundTab.setObjectName("BackgroundTab")
828+ self.layoutWidget1 = QtGui.QWidget(self.BackgroundTab)
829+ self.layoutWidget1.setGeometry(QtCore.QRect(10, 10, 321, 351))
830+ self.layoutWidget1.setObjectName("layoutWidget1")
831+ self.gridLayout = QtGui.QGridLayout(self.layoutWidget1)
832+ self.gridLayout.setObjectName("gridLayout")
833+ self.BackgroundLabel = QtGui.QLabel(self.layoutWidget1)
834+ self.BackgroundLabel.setObjectName("BackgroundLabel")
835+ self.gridLayout.addWidget(self.BackgroundLabel, 0, 0, 1, 2)
836+ self.BackgroundComboBox = QtGui.QComboBox(self.layoutWidget1)
837+ self.BackgroundComboBox.setObjectName("BackgroundComboBox")
838+ self.BackgroundComboBox.addItem(QtCore.QString())
839+ self.BackgroundComboBox.addItem(QtCore.QString())
840+ self.gridLayout.addWidget(self.BackgroundComboBox, 0, 2, 1, 2)
841+ self.BackgroundTypeLabel = QtGui.QLabel(self.layoutWidget1)
842+ self.BackgroundTypeLabel.setObjectName("BackgroundTypeLabel")
843+ self.gridLayout.addWidget(self.BackgroundTypeLabel, 1, 0, 1, 2)
844+ self.BackgroundTypeComboBox = QtGui.QComboBox(self.layoutWidget1)
845+ self.BackgroundTypeComboBox.setObjectName("BackgroundTypeComboBox")
846+ self.BackgroundTypeComboBox.addItem(QtCore.QString())
847+ self.BackgroundTypeComboBox.addItem(QtCore.QString())
848+ self.BackgroundTypeComboBox.addItem(QtCore.QString())
849+ self.gridLayout.addWidget(self.BackgroundTypeComboBox, 1, 2, 1, 2)
850+ self.Color1Label = QtGui.QLabel(self.layoutWidget1)
851+ self.Color1Label.setObjectName("Color1Label")
852+ self.gridLayout.addWidget(self.Color1Label, 2, 0, 1, 1)
853+ self.Color1PushButton = QtGui.QPushButton(self.layoutWidget1)
854+ self.Color1PushButton.setObjectName("Color1PushButton")
855+ self.gridLayout.addWidget(self.Color1PushButton, 2, 2, 1, 2)
856+ self.Color2Label = QtGui.QLabel(self.layoutWidget1)
857+ self.Color2Label.setObjectName("Color2Label")
858+ self.gridLayout.addWidget(self.Color2Label, 3, 0, 1, 1)
859+ self.Color2PushButton = QtGui.QPushButton(self.layoutWidget1)
860+ self.Color2PushButton.setObjectName("Color2PushButton")
861+ self.gridLayout.addWidget(self.Color2PushButton, 3, 2, 1, 2)
862+ self.ImageLabel = QtGui.QLabel(self.layoutWidget1)
863+ self.ImageLabel.setObjectName("ImageLabel")
864+ self.gridLayout.addWidget(self.ImageLabel, 4, 0, 1, 1)
865+ self.ImageLineEdit = QtGui.QLineEdit(self.layoutWidget1)
866+ self.ImageLineEdit.setObjectName("ImageLineEdit")
867+ self.gridLayout.addWidget(self.ImageLineEdit, 4, 1, 1, 2)
868+ self.ImagePushButton = QtGui.QPushButton(self.layoutWidget1)
869+ icon1 = QtGui.QIcon()
870+ icon1.addPixmap(QtGui.QPixmap(":/services/service_open.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
871+ self.ImagePushButton.setIcon(icon1)
872+ self.ImagePushButton.setObjectName("ImagePushButton")
873+ self.gridLayout.addWidget(self.ImagePushButton, 4, 3, 1, 1)
874+ self.GradientLabel = QtGui.QLabel(self.layoutWidget1)
875+ self.GradientLabel.setObjectName("GradientLabel")
876+ self.gridLayout.addWidget(self.GradientLabel, 5, 0, 1, 1)
877+ self.GradientComboBox = QtGui.QComboBox(self.layoutWidget1)
878+ self.GradientComboBox.setObjectName("GradientComboBox")
879+ self.GradientComboBox.addItem(QtCore.QString())
880+ self.GradientComboBox.addItem(QtCore.QString())
881+ self.GradientComboBox.addItem(QtCore.QString())
882+ self.gridLayout.addWidget(self.GradientComboBox, 5, 2, 1, 2)
883+ self.tabWidget.addTab(self.BackgroundTab, "")
884+ self.FontTab = QtGui.QWidget()
885+ self.FontTab.setObjectName("FontTab")
886+ self.MainFontGroupBox = QtGui.QGroupBox(self.FontTab)
887+ self.MainFontGroupBox.setGeometry(QtCore.QRect(20, 20, 307, 119))
888+ self.MainFontGroupBox.setObjectName("MainFontGroupBox")
889+ self.gridLayout_2 = QtGui.QGridLayout(self.MainFontGroupBox)
890+ self.gridLayout_2.setObjectName("gridLayout_2")
891+ self.MainFontlabel = QtGui.QLabel(self.MainFontGroupBox)
892+ self.MainFontlabel.setObjectName("MainFontlabel")
893+ self.gridLayout_2.addWidget(self.MainFontlabel, 0, 0, 1, 1)
894+ self.MainFontComboBox = QtGui.QFontComboBox(self.MainFontGroupBox)
895+ self.MainFontComboBox.setObjectName("MainFontComboBox")
896+ self.gridLayout_2.addWidget(self.MainFontComboBox, 0, 1, 1, 2)
897+ self.MainFontColorLabel = QtGui.QLabel(self.MainFontGroupBox)
898+ self.MainFontColorLabel.setObjectName("MainFontColorLabel")
899+ self.gridLayout_2.addWidget(self.MainFontColorLabel, 1, 0, 1, 1)
900+ self.MainFontColorPushButton = QtGui.QPushButton(self.MainFontGroupBox)
901+ self.MainFontColorPushButton.setObjectName("MainFontColorPushButton")
902+ self.gridLayout_2.addWidget(self.MainFontColorPushButton, 1, 2, 1, 1)
903+ self.MainFontSize = QtGui.QLabel(self.MainFontGroupBox)
904+ self.MainFontSize.setObjectName("MainFontSize")
905+ self.gridLayout_2.addWidget(self.MainFontSize, 2, 0, 1, 1)
906+ self.MainFontSizeLineEdit = QtGui.QLineEdit(self.MainFontGroupBox)
907+ self.MainFontSizeLineEdit.setObjectName("MainFontSizeLineEdit")
908+ self.gridLayout_2.addWidget(self.MainFontSizeLineEdit, 2, 1, 1, 1)
909+ self.MainFontlSlider = QtGui.QSlider(self.MainFontGroupBox)
910+ self.MainFontlSlider.setProperty("value", QtCore.QVariant(15))
911+ self.MainFontlSlider.setMaximum(40)
912+ self.MainFontlSlider.setOrientation(QtCore.Qt.Horizontal)
913+ self.MainFontlSlider.setTickPosition(QtGui.QSlider.TicksBelow)
914+ self.MainFontlSlider.setTickInterval(5)
915+ self.MainFontlSlider.setObjectName("MainFontlSlider")
916+ self.gridLayout_2.addWidget(self.MainFontlSlider, 2, 2, 1, 1)
917+ self.FooterFontGroupBox = QtGui.QGroupBox(self.FontTab)
918+ self.FooterFontGroupBox.setGeometry(QtCore.QRect(20, 170, 307, 119))
919+ self.FooterFontGroupBox.setObjectName("FooterFontGroupBox")
920+ self.gridLayout_3 = QtGui.QGridLayout(self.FooterFontGroupBox)
921+ self.gridLayout_3.setObjectName("gridLayout_3")
922+ self.FooterFontlabel = QtGui.QLabel(self.FooterFontGroupBox)
923+ self.FooterFontlabel.setObjectName("FooterFontlabel")
924+ self.gridLayout_3.addWidget(self.FooterFontlabel, 0, 0, 1, 1)
925+ self.FooterFontComboBox = QtGui.QFontComboBox(self.FooterFontGroupBox)
926+ self.FooterFontComboBox.setObjectName("FooterFontComboBox")
927+ self.gridLayout_3.addWidget(self.FooterFontComboBox, 0, 1, 1, 2)
928+ self.FooterFontColorLabel = QtGui.QLabel(self.FooterFontGroupBox)
929+ self.FooterFontColorLabel.setObjectName("FooterFontColorLabel")
930+ self.gridLayout_3.addWidget(self.FooterFontColorLabel, 1, 0, 1, 1)
931+ self.FooterColorPushButton = QtGui.QPushButton(self.FooterFontGroupBox)
932+ self.FooterColorPushButton.setObjectName("FooterColorPushButton")
933+ self.gridLayout_3.addWidget(self.FooterColorPushButton, 1, 2, 1, 1)
934+ self.FooterFontSize = QtGui.QLabel(self.FooterFontGroupBox)
935+ self.FooterFontSize.setObjectName("FooterFontSize")
936+ self.gridLayout_3.addWidget(self.FooterFontSize, 2, 0, 1, 1)
937+ self.FooterFontSizeLineEdit = QtGui.QLineEdit(self.FooterFontGroupBox)
938+ self.FooterFontSizeLineEdit.setObjectName("FooterFontSizeLineEdit")
939+ self.gridLayout_3.addWidget(self.FooterFontSizeLineEdit, 2, 1, 1, 1)
940+ self.FooterFontlSlider = QtGui.QSlider(self.FooterFontGroupBox)
941+ self.FooterFontlSlider.setProperty("value", QtCore.QVariant(15))
942+ self.FooterFontlSlider.setMaximum(40)
943+ self.FooterFontlSlider.setOrientation(QtCore.Qt.Horizontal)
944+ self.FooterFontlSlider.setTickPosition(QtGui.QSlider.TicksBelow)
945+ self.FooterFontlSlider.setTickInterval(5)
946+ self.FooterFontlSlider.setObjectName("FooterFontlSlider")
947+ self.gridLayout_3.addWidget(self.FooterFontlSlider, 2, 2, 1, 1)
948+ self.tabWidget.addTab(self.FontTab, "")
949+ self.OptionsTab = QtGui.QWidget()
950+ self.OptionsTab.setObjectName("OptionsTab")
951+ self.ShadowGroupBox = QtGui.QGroupBox(self.OptionsTab)
952+ self.ShadowGroupBox.setGeometry(QtCore.QRect(20, 10, 301, 80))
953+ self.ShadowGroupBox.setObjectName("ShadowGroupBox")
954+ self.layoutWidget2 = QtGui.QWidget(self.ShadowGroupBox)
955+ self.layoutWidget2.setGeometry(QtCore.QRect(10, 20, 281, 54))
956+ self.layoutWidget2.setObjectName("layoutWidget2")
957+ self.formLayout = QtGui.QFormLayout(self.layoutWidget2)
958+ self.formLayout.setObjectName("formLayout")
959+ self.ShadowCheckBox = QtGui.QCheckBox(self.layoutWidget2)
960+ self.ShadowCheckBox.setObjectName("ShadowCheckBox")
961+ self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.ShadowCheckBox)
962+ self.ShadowColorLabel = QtGui.QLabel(self.layoutWidget2)
963+ self.ShadowColorLabel.setObjectName("ShadowColorLabel")
964+ self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.ShadowColorLabel)
965+ self.ShadowColorPushButton = QtGui.QPushButton(self.layoutWidget2)
966+ self.ShadowColorPushButton.setObjectName("ShadowColorPushButton")
967+ self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.ShadowColorPushButton)
968+ self.AlignmentGroupBox = QtGui.QGroupBox(self.OptionsTab)
969+ self.AlignmentGroupBox.setGeometry(QtCore.QRect(10, 200, 321, 161))
970+ self.AlignmentGroupBox.setObjectName("AlignmentGroupBox")
971+ self.gridLayout_4 = QtGui.QGridLayout(self.AlignmentGroupBox)
972+ self.gridLayout_4.setObjectName("gridLayout_4")
973+ self.HorizontalLabel = QtGui.QLabel(self.AlignmentGroupBox)
974+ self.HorizontalLabel.setObjectName("HorizontalLabel")
975+ self.gridLayout_4.addWidget(self.HorizontalLabel, 0, 0, 1, 1)
976+ self.HorizontalComboBox = QtGui.QComboBox(self.AlignmentGroupBox)
977+ self.HorizontalComboBox.setObjectName("HorizontalComboBox")
978+ self.HorizontalComboBox.addItem(QtCore.QString())
979+ self.HorizontalComboBox.addItem(QtCore.QString())
980+ self.HorizontalComboBox.addItem(QtCore.QString())
981+ self.gridLayout_4.addWidget(self.HorizontalComboBox, 0, 1, 1, 1)
982+ self.VerticalLabel = QtGui.QLabel(self.AlignmentGroupBox)
983+ self.VerticalLabel.setObjectName("VerticalLabel")
984+ self.gridLayout_4.addWidget(self.VerticalLabel, 1, 0, 1, 1)
985+ self.VerticalComboBox = QtGui.QComboBox(self.AlignmentGroupBox)
986+ self.VerticalComboBox.setObjectName("VerticalComboBox")
987+ self.VerticalComboBox.addItem(QtCore.QString())
988+ self.VerticalComboBox.addItem(QtCore.QString())
989+ self.VerticalComboBox.addItem(QtCore.QString())
990+ self.gridLayout_4.addWidget(self.VerticalComboBox, 1, 1, 1, 1)
991+ self.OutlineGroupBox = QtGui.QGroupBox(self.OptionsTab)
992+ self.OutlineGroupBox.setGeometry(QtCore.QRect(20, 110, 301, 80))
993+ self.OutlineGroupBox.setObjectName("OutlineGroupBox")
994+ self.layoutWidget_3 = QtGui.QWidget(self.OutlineGroupBox)
995+ self.layoutWidget_3.setGeometry(QtCore.QRect(10, 20, 281, 54))
996+ self.layoutWidget_3.setObjectName("layoutWidget_3")
997+ self.OutlineformLayout = QtGui.QFormLayout(self.layoutWidget_3)
998+ self.OutlineformLayout.setObjectName("OutlineformLayout")
999+ self.OutlineCheckBox = QtGui.QCheckBox(self.layoutWidget_3)
1000+ self.OutlineCheckBox.setObjectName("OutlineCheckBox")
1001+ self.OutlineformLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.OutlineCheckBox)
1002+ self.OutlineColorLabel = QtGui.QLabel(self.layoutWidget_3)
1003+ self.OutlineColorLabel.setObjectName("OutlineColorLabel")
1004+ self.OutlineformLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.OutlineColorLabel)
1005+ self.OutlineColorPushButton = QtGui.QPushButton(self.layoutWidget_3)
1006+ self.OutlineColorPushButton.setObjectName("OutlineColorPushButton")
1007+ self.OutlineformLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.OutlineColorPushButton)
1008+ self.tabWidget.addTab(self.OptionsTab, "")
1009+ self.horizontalLayout_2.addWidget(self.LeftSide)
1010+ self.RightSide = QtGui.QWidget(self.layoutWidget)
1011+ self.RightSide.setObjectName("RightSide")
1012+ self.ThemePreView = QtGui.QGraphicsView(self.RightSide)
1013+ self.ThemePreView.setGeometry(QtCore.QRect(0, 30, 341, 341))
1014+ self.ThemePreView.setObjectName("ThemePreView")
1015+ self.horizontalLayout_2.addWidget(self.RightSide)
1016+ self.layoutWidget3 = QtGui.QWidget(AmendThemeDialog)
1017+ self.layoutWidget3.setGeometry(QtCore.QRect(50, 20, 441, 41))
1018+ self.layoutWidget3.setObjectName("layoutWidget3")
1019+ self.horizontalLayout = QtGui.QHBoxLayout(self.layoutWidget3)
1020+ self.horizontalLayout.setObjectName("horizontalLayout")
1021+ self.ThemeNameLabel = QtGui.QLabel(self.layoutWidget3)
1022+ self.ThemeNameLabel.setObjectName("ThemeNameLabel")
1023+ self.horizontalLayout.addWidget(self.ThemeNameLabel)
1024+ self.ThemeNameEdit = QtGui.QLineEdit(self.layoutWidget3)
1025+ self.ThemeNameEdit.setObjectName("ThemeNameEdit")
1026+ self.horizontalLayout.addWidget(self.ThemeNameEdit)
1027+
1028+ self.retranslateUi(AmendThemeDialog)
1029+ self.tabWidget.setCurrentIndex(1)
1030+ QtCore.QMetaObject.connectSlotsByName(AmendThemeDialog)
1031+
1032+ def retranslateUi(self, AmendThemeDialog):
1033+ AmendThemeDialog.setWindowTitle(QtGui.QApplication.translate("AmendThemeDialog", "Theme Maintance", None, QtGui.QApplication.UnicodeUTF8))
1034+ self.BackgroundLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Background:", None, QtGui.QApplication.UnicodeUTF8))
1035+ self.BackgroundComboBox.setItemText(0, QtGui.QApplication.translate("AmendThemeDialog", "Opaque", None, QtGui.QApplication.UnicodeUTF8))
1036+ self.BackgroundComboBox.setItemText(1, QtGui.QApplication.translate("AmendThemeDialog", "Transparent", None, QtGui.QApplication.UnicodeUTF8))
1037+ self.BackgroundTypeLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Background Type:", None, QtGui.QApplication.UnicodeUTF8))
1038+ self.BackgroundTypeComboBox.setItemText(0, QtGui.QApplication.translate("AmendThemeDialog", "Solid Color", None, QtGui.QApplication.UnicodeUTF8))
1039+ self.BackgroundTypeComboBox.setItemText(1, QtGui.QApplication.translate("AmendThemeDialog", "Gradient", None, QtGui.QApplication.UnicodeUTF8))
1040+ self.BackgroundTypeComboBox.setItemText(2, QtGui.QApplication.translate("AmendThemeDialog", "Image", None, QtGui.QApplication.UnicodeUTF8))
1041+ self.Color1Label.setText(QtGui.QApplication.translate("AmendThemeDialog", "<Color1>", None, QtGui.QApplication.UnicodeUTF8))
1042+ self.Color2Label.setText(QtGui.QApplication.translate("AmendThemeDialog", "<Color2>", None, QtGui.QApplication.UnicodeUTF8))
1043+ self.ImageLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Image:", None, QtGui.QApplication.UnicodeUTF8))
1044+ self.GradientLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Gradient :", None, QtGui.QApplication.UnicodeUTF8))
1045+ self.GradientComboBox.setItemText(0, QtGui.QApplication.translate("AmendThemeDialog", "Horizontal", None, QtGui.QApplication.UnicodeUTF8))
1046+ self.GradientComboBox.setItemText(1, QtGui.QApplication.translate("AmendThemeDialog", "Vertical", None, QtGui.QApplication.UnicodeUTF8))
1047+ self.GradientComboBox.setItemText(2, QtGui.QApplication.translate("AmendThemeDialog", "Circular", None, QtGui.QApplication.UnicodeUTF8))
1048+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.BackgroundTab), QtGui.QApplication.translate("AmendThemeDialog", "Background", None, QtGui.QApplication.UnicodeUTF8))
1049+ self.MainFontGroupBox.setTitle(QtGui.QApplication.translate("AmendThemeDialog", "Main Font", None, QtGui.QApplication.UnicodeUTF8))
1050+ self.MainFontlabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Font:", None, QtGui.QApplication.UnicodeUTF8))
1051+ self.MainFontColorLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Font Color", None, QtGui.QApplication.UnicodeUTF8))
1052+ self.MainFontSize.setText(QtGui.QApplication.translate("AmendThemeDialog", "Size:", None, QtGui.QApplication.UnicodeUTF8))
1053+ self.FooterFontGroupBox.setTitle(QtGui.QApplication.translate("AmendThemeDialog", "Footer Font", None, QtGui.QApplication.UnicodeUTF8))
1054+ self.FooterFontlabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Font:", None, QtGui.QApplication.UnicodeUTF8))
1055+ self.FooterFontColorLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Font Color", None, QtGui.QApplication.UnicodeUTF8))
1056+ self.FooterFontSize.setText(QtGui.QApplication.translate("AmendThemeDialog", "Size:", None, QtGui.QApplication.UnicodeUTF8))
1057+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.FontTab), QtGui.QApplication.translate("AmendThemeDialog", "Font", None, QtGui.QApplication.UnicodeUTF8))
1058+ self.ShadowGroupBox.setTitle(QtGui.QApplication.translate("AmendThemeDialog", "Shadow", None, QtGui.QApplication.UnicodeUTF8))
1059+ self.ShadowCheckBox.setText(QtGui.QApplication.translate("AmendThemeDialog", "Use Shadow", None, QtGui.QApplication.UnicodeUTF8))
1060+ self.ShadowColorLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Shadow Color:", None, QtGui.QApplication.UnicodeUTF8))
1061+ self.AlignmentGroupBox.setTitle(QtGui.QApplication.translate("AmendThemeDialog", "Alignment", None, QtGui.QApplication.UnicodeUTF8))
1062+ self.HorizontalLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Horizontal Align:", None, QtGui.QApplication.UnicodeUTF8))
1063+ self.HorizontalComboBox.setItemText(0, QtGui.QApplication.translate("AmendThemeDialog", "Left", None, QtGui.QApplication.UnicodeUTF8))
1064+ self.HorizontalComboBox.setItemText(1, QtGui.QApplication.translate("AmendThemeDialog", "Right", None, QtGui.QApplication.UnicodeUTF8))
1065+ self.HorizontalComboBox.setItemText(2, QtGui.QApplication.translate("AmendThemeDialog", "Center", None, QtGui.QApplication.UnicodeUTF8))
1066+ self.VerticalLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Vertical Align:", None, QtGui.QApplication.UnicodeUTF8))
1067+ self.VerticalComboBox.setItemText(0, QtGui.QApplication.translate("AmendThemeDialog", "Top", None, QtGui.QApplication.UnicodeUTF8))
1068+ self.VerticalComboBox.setItemText(1, QtGui.QApplication.translate("AmendThemeDialog", "Middle", None, QtGui.QApplication.UnicodeUTF8))
1069+ self.VerticalComboBox.setItemText(2, QtGui.QApplication.translate("AmendThemeDialog", "Bottom", None, QtGui.QApplication.UnicodeUTF8))
1070+ self.OutlineGroupBox.setTitle(QtGui.QApplication.translate("AmendThemeDialog", "Outline", None, QtGui.QApplication.UnicodeUTF8))
1071+ self.OutlineCheckBox.setText(QtGui.QApplication.translate("AmendThemeDialog", "Use Outline", None, QtGui.QApplication.UnicodeUTF8))
1072+ self.OutlineColorLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Outline Color:", None, QtGui.QApplication.UnicodeUTF8))
1073+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.OptionsTab), QtGui.QApplication.translate("AmendThemeDialog", "Display Options", None, QtGui.QApplication.UnicodeUTF8))
1074+ self.ThemeNameLabel.setText(QtGui.QApplication.translate("AmendThemeDialog", "Theme Name", None, QtGui.QApplication.UnicodeUTF8))
1075+
1076
1077=== added file 'openlp/core/ui/amendthemeform.py'
1078--- openlp/core/ui/amendthemeform.py 1970-01-01 00:00:00 +0000
1079+++ openlp/core/ui/amendthemeform.py 2009-04-04 17:36:15 +0000
1080@@ -0,0 +1,37 @@
1081+# -*- coding: utf-8 -*-
1082+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
1083+"""
1084+OpenLP - Open Source Lyrics Projection
1085+Copyright (c) 2008 Raoul Snyman
1086+Portions copyright (c) 2008 Martin Thompson, Tim Bentley,
1087+
1088+This program is free software; you can redistribute it and/or modify it under
1089+the terms of the GNU General Public License as published by the Free Software
1090+Foundation; version 2 of the License.
1091+
1092+This program is distributed in the hope that it will be useful, but WITHOUT ANY
1093+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
1094+PARTICULAR PURPOSE. See the GNU General Public License for more details.
1095+
1096+You should have received a copy of the GNU General Public License along with
1097+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
1098+Place, Suite 330, Boston, MA 02111-1307 USA
1099+"""
1100+import logging
1101+
1102+from PyQt4 import QtCore, QtGui
1103+
1104+#from openlp.core.resources import *
1105+
1106+from amendthemedialog import Ui_AmendThemeDialog
1107+
1108+log = logging.getLogger(u'AmendThemeForm')
1109+
1110+class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
1111+
1112+ def __init__(self, parent=None):
1113+ QtGui.QDialog.__init__(self, parent)
1114+ self.setupUi(self)
1115+
1116+ def loadTheme(self, theme):
1117+ pass
1118
1119=== modified file 'openlp/core/ui/mainwindow.py' (properties changed: -x to +x)
1120--- openlp/core/ui/mainwindow.py 2009-03-23 19:17:07 +0000
1121+++ openlp/core/ui/mainwindow.py 2009-04-05 18:33:56 +0000
1122@@ -39,16 +39,16 @@
1123
1124 def __init__(self):
1125 self.main_window = QtGui.QMainWindow()
1126- self.EventManager = EventManager()
1127+ self.EventManager = EventManager()
1128 self.alert_form = AlertForm()
1129 self.about_form = AboutForm()
1130 self.settings_form = SettingsForm()
1131-
1132+
1133 pluginpath = os.path.split(os.path.abspath(__file__))[0]
1134 pluginpath = os.path.abspath(os.path.join(pluginpath, '..', '..','plugins'))
1135 self.plugin_manager = PluginManager(pluginpath)
1136 self.plugin_helpers = {}
1137-
1138+
1139 self.setupUi()
1140
1141 log.info(u'Load Plugins')
1142@@ -56,7 +56,7 @@
1143 self.plugin_helpers[u'live'] = self.LiveController
1144 self.plugin_helpers[u'event'] = self.EventManager
1145 self.plugin_helpers[u'theme'] = self.ThemeManagerContents # Theme manger
1146-
1147+
1148 self.plugin_manager.find_plugins(pluginpath, self.plugin_helpers, self.EventManager)
1149 # hook methods have to happen after find_plugins. Find plugins needs the controllers
1150 # hence the hooks have moved from setupUI() to here
1151@@ -77,9 +77,14 @@
1152 self.plugin_manager.hook_export_menu(self.FileExportMenu)
1153
1154 # Call the initialise method to setup plugins.
1155- log.info(u'initialise plugins')
1156+ log.info(u'initialise plugins')
1157 self.plugin_manager.initialise_plugins()
1158-
1159+
1160+ # Once all components are initialised load the Themes
1161+ log.info(u'Load Themes')
1162+ self.ThemeManagerContents.setEventManager(self.EventManager)
1163+ self.ThemeManagerContents.loadThemes()
1164+
1165 def setupUi(self):
1166 self.main_window.setObjectName("main_window")
1167 self.main_window.resize(1087, 847)
1168@@ -176,7 +181,7 @@
1169 self.ServiceManagerContents = ServiceManager(self)
1170 self.ServiceManagerDock.setWidget(self.ServiceManagerContents)
1171 self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.ServiceManagerDock)
1172- #Theme Manager Defined
1173+ #Theme Manager Defined
1174 self.ThemeManagerDock = QtGui.QDockWidget(self.main_window)
1175 ThemeManagerIcon = QtGui.QIcon()
1176 ThemeManagerIcon.addPixmap(QtGui.QPixmap(":/system/system_thememanager.png"),
1177@@ -184,46 +189,12 @@
1178 self.ThemeManagerDock.setWindowIcon(ThemeManagerIcon)
1179 self.ThemeManagerDock.setFloating(False)
1180 self.ThemeManagerDock.setObjectName("ThemeManagerDock")
1181-
1182- self.ThemeManagerContents = ThemeManager(self)
1183-
1184-# self.ThemeManagerContents = QtGui.QWidget()
1185-# self.ThemeManagerContents.setObjectName("ThemeManagerContents")
1186-# self.ThemeManagerLayout = QtGui.QVBoxLayout(self.ThemeManagerContents)
1187-# self.ThemeManagerLayout.setSpacing(0)
1188-# self.ThemeManagerLayout.setMargin(0)
1189-# self.ThemeManagerLayout.setObjectName("ThemeManagerLayout")
1190-# self.ThemeManagerToolbar = QtGui.QToolBar(self.ThemeManagerContents)
1191-# self.ThemeManagerToolbar.setObjectName("ThemeManagerToolbar")
1192-# NewThemeIcon = QtGui.QIcon()
1193-# NewThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_new.png"),
1194-# QtGui.QIcon.Normal, QtGui.QIcon.Off)
1195-# self.ThemeNewItem = self.ThemeManagerToolbar.addAction(NewThemeIcon, 'New theme')
1196-# EditThemeIcon = QtGui.QIcon()
1197-# EditThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_edit.png"),
1198-# QtGui.QIcon.Normal, QtGui.QIcon.Off)
1199-# self.ThemeEditItem = self.ThemeManagerToolbar.addAction(EditThemeIcon, 'Edit theme')
1200-# DeleteThemeIcon = QtGui.QIcon()
1201-# DeleteThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_delete.png"),
1202-# QtGui.QIcon.Normal, QtGui.QIcon.Off)
1203-# self.ThemeDeleteButton = self.ThemeManagerToolbar.addAction(DeleteThemeIcon, 'Delete theme')
1204-# self.ThemeManagerToolbar.addSeparator()
1205-# ImportThemeIcon = QtGui.QIcon()
1206-# ImportThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_import.png"),
1207-# QtGui.QIcon.Normal, QtGui.QIcon.Off)
1208-# self.ThemeImportButton = self.ThemeManagerToolbar.addAction(ImportThemeIcon, 'Import theme')
1209-# ExportThemeIcon = QtGui.QIcon()
1210-# ExportThemeIcon.addPixmap(QtGui.QPixmap(":/themes/theme_export.png"),
1211-# QtGui.QIcon.Normal, QtGui.QIcon.Off)
1212-# self.ThemeExportButton = self.ThemeManagerToolbar.addAction(ExportThemeIcon, 'Export theme')
1213-# self.ThemeManagerLayout.addWidget(self.ThemeManagerToolbar)
1214-# self.ThemeManagerListView = QtGui.QListView(self.ThemeManagerContents)
1215-# self.ThemeManagerListView.setObjectName("ThemeManagerListView")
1216-# self.ThemeManagerLayout.addWidget(self.ThemeManagerListView)
1217+
1218+ self.ThemeManagerContents = ThemeManager(self)
1219
1220 self.ThemeManagerDock.setWidget(self.ThemeManagerContents)
1221 self.main_window.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.ThemeManagerDock)
1222-
1223+
1224 self.FileNewItem = QtGui.QAction(self.main_window)
1225 self.FileNewItem.setIcon(self.ServiceManagerContents.Toolbar.getIconFromTitle("New Service"))
1226 self.FileNewItem.setObjectName("FileNewItem")
1227
1228=== modified file 'openlp/core/ui/thememanager.py' (properties changed: -x to +x)
1229--- openlp/core/ui/thememanager.py 2009-03-28 20:12:22 +0000
1230+++ openlp/core/ui/thememanager.py 2009-04-05 18:33:56 +0000
1231@@ -28,14 +28,20 @@
1232 from PyQt4 import QtCore, QtGui
1233 from PyQt4.QtCore import *
1234 from PyQt4.QtGui import *
1235-# from openlp.core.resources import *
1236-# from openlp.core.ui import AboutForm, AlertForm, SettingsForm, SlideController
1237+
1238+from openlp.core.ui import AmendThemeForm
1239 from openlp.core import translate
1240+from openlp.core import Renderer
1241+from openlp.core.theme import Theme
1242+from openlp.core.lib import Event
1243+from openlp.core.lib import EventType
1244+from openlp.core.lib import EventManager
1245 from openlp.core.lib import OpenLPToolbar
1246+from openlp.core.lib import ThemeXMLBuilder
1247+from openlp.core.lib import ThemeXMLParser
1248 from openlp.core.utils import ConfigHelper
1249-#from openlp.core.lib import ThemeItem
1250-
1251-# from openlp.core import PluginManager
1252+
1253+
1254 import logging
1255
1256 class ThemeData(QAbstractItemModel):
1257@@ -51,7 +57,7 @@
1258 self.items=[]
1259 self.rowheight=50
1260 self.maximagewidth=self.rowheight*16/9.0;
1261- log.info("Starting")
1262+ log.info(u'Starting')
1263
1264 def clearItems(self):
1265 self.items=[]
1266@@ -64,9 +70,10 @@
1267
1268 def insertRow(self, row, filename):
1269 self.beginInsertRows(QModelIndex(),row,row)
1270- log.info("insert row %d:%s"%(row,filename))
1271+ log.info(u'insert row %d:%s'%(row,filename))
1272 (prefix, shortfilename) = os.path.split(str(filename))
1273- log.info("shortfilename=%s"%(shortfilename))
1274+ log.info(u'shortfilename=%s'%(shortfilename))
1275+ theme = shortfilename.split(u'.')
1276 # create a preview image
1277 if os.path.exists(filename):
1278 preview = QPixmap(str(filename))
1279@@ -83,8 +90,8 @@
1280 p=QPixmap(w,h)
1281 p.fill(Qt.transparent)
1282 # finally create the row
1283- self.items.insert(row,(filename, p, shortfilename))
1284- log.info("Items: %s" % self.items)
1285+ self.items.insert(row,(filename, p, shortfilename, theme[0]))
1286+ log.info(u'Items: %s' % self.items)
1287 self.endInsertRows()
1288
1289 def removeRow(self, row):
1290@@ -106,7 +113,7 @@
1291 if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
1292 return QVariant()
1293 if role==Qt.DisplayRole:
1294- retval= self.items[row][2]
1295+ retval= self.items[row][3]
1296 elif role == Qt.DecorationRole:
1297 retval= self.items[row][1]
1298 else:
1299@@ -122,7 +129,7 @@
1300 yield i
1301
1302 def item(self, row):
1303- log.info("Get Item:%d -> %s" %(row, str(self.items)))
1304+ log.info(u'Get Item:%d -> %s' %(row, str(self.items)))
1305 return self.items[row]
1306
1307 class ThemeManager(QWidget):
1308@@ -138,14 +145,19 @@
1309 self.Layout = QtGui.QVBoxLayout(self)
1310 self.Layout.setSpacing(0)
1311 self.Layout.setMargin(0)
1312+ self.amendThemeForm = AmendThemeForm()
1313 self.Toolbar = OpenLPToolbar(self)
1314- self.Toolbar.addToolbarButton("New Theme", ":/themes/theme_new.png")
1315- self.Toolbar.addToolbarButton("Edit Theme", ":/themes/theme_edit.png")
1316- self.Toolbar.addToolbarButton("Delete Theme", ":/themes/theme_delete.png")
1317+ self.Toolbar.addToolbarButton(translate('ThemeManager',u'New Theme'), ":/themes/theme_new.png",
1318+ translate('ThemeManager',u'Allows a Theme to be created'), self.onAddTheme)
1319+ self.Toolbar.addToolbarButton(translate('ThemeManager',u'Edit Theme'), ":/themes/theme_edit.png",
1320+ translate('ThemeManager',u'Allows a Theme to be amended'), self.onEditTheme)
1321+ self.Toolbar.addToolbarButton(translate('ThemeManager',u'Delete Theme'), ":/themes/theme_delete.png",
1322+ translate('ThemeManager',u'Allows a Theme to be deleted'), self.onDeleteTheme)
1323 self.Toolbar.addSeparator()
1324- self.Toolbar.addToolbarButton("Import Theme", ":/themes/theme_import.png",
1325- u'Allows Themes to be imported', self.onImportTheme)
1326- self.Toolbar.addToolbarButton("Export Theme", ":/themes/theme_export.png")
1327+ self.Toolbar.addToolbarButton(translate('ThemeManager',u'Import Theme'), ":/themes/theme_import.png",
1328+ translate('ThemeManager',u'Allows Themes to be imported'), self.onImportTheme)
1329+ self.Toolbar.addToolbarButton(translate('ThemeManager',u'Export Theme'), ":/themes/theme_export.png",
1330+ translate('ThemeManager',u'Allows Themes to be exported'), self.onExportTheme)
1331 self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
1332 self.Toolbar.addAction(self.ThemeWidget)
1333
1334@@ -161,62 +173,29 @@
1335 self.themelist= []
1336 self.path = os.path.join(ConfigHelper.get_data_path(), u'themes')
1337 self.checkThemesExists(self.path)
1338- self.loadThemes() # load the themes
1339-
1340-# def addThemeItem(self, item):
1341-# """Adds Theme item"""
1342-# log.info("addThemeItem")
1343-# indexes=self.TreeView.selectedIndexes()
1344-# assert len(indexes) <= 1 # can only have one selected index in this view
1345-# if indexes == []:
1346-# log.info("No row")
1347-# row = None
1348-# selected_item = None
1349-# else:
1350-# row=indexes[0].row()
1351-# # if currently selected is of correct type, add it to it
1352-# log.info("row:%d"%row)
1353-# selected_item=self.Theme_data.item(row)
1354-# if type(selected_item) == type(item):
1355-# log.info("Add to existing item")
1356-# selected_item.add(item)
1357-# else:
1358-# log.info("Create new item")
1359-# if row is None:
1360-# self.Theme_data.addRow(item)
1361-# else:
1362-# self.Theme_data.insertRow(row+1, item)
1363-#
1364-# def removeThemeItem(self):
1365-# """Remove currently selected item"""
1366-# pass
1367-#
1368-# def oos_as_text(self):
1369-# text=[]
1370-# log.info( "oos as text")
1371-# log.info("Data:"+str(self.Theme_data))
1372-# for i in self.Theme_data:
1373-# text.append("# " + str(i))
1374-# text.append(i.get_oos_text())
1375-# return '\n'.join(text)
1376-#
1377-# def write_oos(self, filename):
1378-# """
1379-# Write a full OOS file out - iterate over plugins and call their respective methods
1380-# This format is totally arbitrary testing purposes - something sensible needs to go in here!
1381-# """
1382-# oosfile=open(filename, "w")
1383-# oosfile.write("# BEGIN OOS\n")
1384-# oosfile.write(self.oos_as_text)
1385-# oosfile.write("# END OOS\n")
1386-# oosfile.close()
1387+
1388+ def setEventManager(self, eventManager):
1389+ self.eventManager = eventManager
1390+
1391+ def onAddTheme(self):
1392+ self.amendThemeForm.exec_()
1393+
1394+ def onEditTheme(self):
1395+ self.amendThemeForm.loadTheme(theme)
1396+ self.amendThemeForm.exec_()
1397+
1398+ def onDeleteTheme(self):
1399+ pass
1400+
1401+ def onExportTheme(self):
1402+ pass
1403
1404 def onImportTheme(self):
1405 files = QtGui.QFileDialog.getOpenFileNames(None,
1406 translate('ThemeManager', u'Select Import File'),
1407 self.path,
1408 u'Theme (*.theme)')
1409- log.info(u'New Themes) %s', str(files))
1410+ log.info(u'New Themes %s', str(files))
1411 if len(files) > 0:
1412 for file in files:
1413 self.unzipTheme(file, self.path)
1414@@ -228,9 +207,11 @@
1415 # self.themelist = [u'African Sunset', u'Snowy Mountains', u'Wilderness', u'Wet and Windy London']
1416 for root, dirs, files in os.walk(self.path):
1417 for name in files:
1418- if name.endswith(u'.bmp'):
1419+ if name.endswith(u'.png'):
1420 self.Theme_data.addRow(os.path.join(self.path, name))
1421
1422+ self.eventManager.post_event(Event(EventType.ThemeListChanged))
1423+
1424 def getThemes(self):
1425 return self.themelist
1426
1427@@ -249,16 +230,99 @@
1428 os.mkdir(os.path.join(dir, file))
1429 else:
1430 fullpath = os.path.join(dir, file)
1431+ names = file.split(u'/')
1432+ xml_data = zip.read(file)
1433 if file.endswith(u'.xml'):
1434- self.checkVersion1(fullpath)
1435- outfile = open(fullpath, 'w')
1436- outfile.write(zip.read(file))
1437- outfile.close()
1438+ if self.checkVersion1(xml_data):
1439+ filexml = self.migrateVersion122(filename, fullpath, xml_data)
1440+ outfile = open(fullpath, 'w')
1441+ outfile.write(filexml)
1442+ outfile.close()
1443+ self.generateImage(dir,names[0], filexml)
1444+ else:
1445+ if file.endswith(u'.bmp'):
1446+ if fullpath is not os.path.join(dir, file):
1447+ outfile = open(fullpath, 'w')
1448+ outfile.write(zip.read(file))
1449+ outfile.close()
1450
1451 def checkVersion1(self, xmlfile):
1452- file=open(xmlfile)
1453- t=''.join(file.readlines()) # read the file and change list to a string
1454+ log.debug(u'checkVersion1 ')
1455+ t = xmlfile
1456 tree = ElementTree(element=XML(t)).getroot()
1457- print "AA"
1458- print tree.find('BackgroundType')
1459- print "AAA"
1460+ if tree.find(u'BackgroundType') is None :
1461+ return False
1462+ else:
1463+ return True
1464+
1465+ def migrateVersion122(self, filename , fullpath, xml_data):
1466+ log.debug(u'migrateVersion122 %s %s', filename , fullpath)
1467+ t=Theme(xml_data)
1468+
1469+ newtheme = ThemeXMLBuilder()
1470+ newtheme.new_document(t.Name)
1471+ if t.BackgroundType == 0:
1472+ newtheme.add_background_solid(str(t.BackgroundParameter1.name()))
1473+ elif t.BackgroundType == 1:
1474+ direction = "vertical"
1475+ if t.BackgroundParameter1.name() == 1:
1476+ direction = "horizontal"
1477+ newtheme.add_background_gradient(str(t.BackgroundParameter1.name()), str(t.BackgroundParameter2.name()), direction)
1478+ else:
1479+ newtheme.add_background_image(str(t.BackgroundParameter1))
1480+
1481+ newtheme.add_font(str(t.FontName), str(t.FontColor.name()), str(t.FontProportion * 2))
1482+ newtheme.add_font(str(t.FontName), str(t.FontColor.name()), str(12), u'footer')
1483+ outline = False
1484+ shadow = False
1485+ if t.Shadow == 1:
1486+ shadow = True
1487+ if t.Outline == 1:
1488+ outline = True
1489+ newtheme.add_display(str(shadow), str(t.ShadowColor.name()), str(outline), str(t.OutlineColor.name()),
1490+ str(t.HorizontalAlign), str(t.VerticalAlign), str(t.WrapStyle))
1491+ return newtheme.extract_xml()
1492+
1493+ def generateImage(self, dir, name, theme_xml):
1494+ log.debug(u'generateImage %s %s ', dir, theme_xml)
1495+ theme = ThemeXMLParser(theme_xml)
1496+ #print theme
1497+ size=QtCore.QSize(800,600)
1498+ frame=TstFrame(size)
1499+ frame=frame
1500+ paintdest=frame.GetPixmap()
1501+ r=Renderer()
1502+ r.set_paint_dest(paintdest)
1503+
1504+ r.set_theme(theme) # set default theme
1505+ r._render_background()
1506+ r.set_text_rectangle(QtCore.QRect(0,0, size.width()-1, size.height()-1))
1507+
1508+ lines=[]
1509+ lines.append(u'Amazing Grace!')
1510+ lines.append(u'How sweet the sound')
1511+ lines.append(u'To save a wretch like me;')
1512+ lines.append(u'I once was lost but now am found,')
1513+ lines.append(u'Was blind, but now I see.')
1514+
1515+ answer=r._render_lines(lines)
1516+ r._get_extent_and_render(u'Amazing Grace (John Newton) ', (10, 560), True, None, True)
1517+ r._get_extent_and_render(u'CCLI xxx (c)Openlp.org', (10, 580), True, None, True)
1518+
1519+ im=frame.GetPixmap().toImage()
1520+ testpathname=os.path.join(dir, name+u'.png')
1521+ if os.path.exists(testpathname):
1522+ os.unlink(testpathname)
1523+ im.save(testpathname, u'png')
1524+ log.debug(u'Theme image written to %s',testpathname)
1525+
1526+
1527+class TstFrame:
1528+ def __init__(self, size):
1529+ """Create the DemoPanel."""
1530+ self.width=size.width();
1531+ self.height=size.height();
1532+ # create something to be painted into
1533+ self._Buffer = QtGui.QPixmap(self.width, self.height)
1534+ def GetPixmap(self):
1535+ return self._Buffer
1536
1537=== modified file 'openlp/plugins/bibles/lib/biblestab.py'
1538--- openlp/plugins/bibles/lib/biblestab.py 2009-03-09 12:49:55 +0000
1539+++ openlp/plugins/bibles/lib/biblestab.py 2009-04-04 10:24:39 +0000
1540@@ -68,12 +68,14 @@
1541 self.NewChaptersCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox)
1542 self.NewChaptersCheckBox.setObjectName("NewChaptersCheckBox")
1543 self.VerseDisplayLayout.addWidget(self.NewChaptersCheckBox, 1, 0, 1, 1)
1544+
1545 self.DisplayStyleWidget = QtGui.QWidget(self.VerseDisplayGroupBox)
1546 self.DisplayStyleWidget.setObjectName(u'DisplayStyleWidget')
1547 self.DisplayStyleLayout = QtGui.QHBoxLayout(self.DisplayStyleWidget)
1548 self.DisplayStyleLayout.setSpacing(8)
1549 self.DisplayStyleLayout.setMargin(0)
1550 self.DisplayStyleLayout.setObjectName(u'DisplayStyleLayout')
1551+
1552 self.DisplayStyleLabel = QtGui.QLabel(self.DisplayStyleWidget)
1553 self.DisplayStyleLabel.setObjectName(u'DisplayStyleLabel')
1554 self.DisplayStyleLayout.addWidget(self.DisplayStyleLabel)
1555@@ -85,9 +87,26 @@
1556 self.DisplayStyleComboBox.addItem(QtCore.QString())
1557 self.DisplayStyleLayout.addWidget(self.DisplayStyleComboBox)
1558 self.VerseDisplayLayout.addWidget(self.DisplayStyleWidget, 2, 0, 1, 1)
1559+
1560+ self.BibleThemeWidget = QtGui.QWidget(self.VerseDisplayGroupBox)
1561+ self.BibleThemeWidget.setObjectName(u'BibleThemeWidget')
1562+ self.BibleThemeLayout = QtGui.QHBoxLayout(self.BibleThemeWidget)
1563+ self.BibleThemeLayout.setSpacing(8)
1564+ self.BibleThemeLayout.setMargin(0)
1565+ self.BibleThemeLayout.setObjectName(u'BibleThemeLayout')
1566+
1567+ self.BibleThemeLabel = QtGui.QLabel(self.BibleThemeWidget)
1568+ self.BibleThemeLabel.setObjectName(u'BibleThemeLabel')
1569+ self.BibleThemeLayout.addWidget(self.BibleThemeLabel)
1570+ self.BibleThemeComboBox = QtGui.QComboBox(self.BibleThemeWidget)
1571+ self.BibleThemeComboBox.setObjectName(u'BibleThemeComboBox')
1572+ self.BibleThemeComboBox.addItem(QtCore.QString())
1573+ self.BibleThemeLayout.addWidget(self.BibleThemeComboBox)
1574+ self.VerseDisplayLayout.addWidget(self.BibleThemeWidget, 3, 0, 1, 1)
1575+
1576 self.ChangeNoteLabel = QtGui.QLabel(self.VerseDisplayGroupBox)
1577 self.ChangeNoteLabel.setObjectName(u'ChangeNoteLabel')
1578- self.VerseDisplayLayout.addWidget(self.ChangeNoteLabel, 3, 0, 1, 1)
1579+ self.VerseDisplayLayout.addWidget(self.ChangeNoteLabel, 4, 0, 1, 1)
1580 self.BibleLeftLayout.addWidget(self.VerseDisplayGroupBox)
1581 self.BibleLeftSpacer = QtGui.QSpacerItem(40, 20,
1582 QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
1583@@ -132,6 +151,7 @@
1584 self.ParagraphRadioButton.setText(translate('SettingsForm','Paragraph style'))
1585 self.NewChaptersCheckBox.setText(translate('SettingsForm', 'Only show new chapter numbers'))
1586 self.DisplayStyleLabel.setText(translate('SettingsForm', 'Display Style:'))
1587+ self.BibleThemeLabel.setText(translate('SettingsForm', 'Bible Theme:'))
1588 self.DisplayStyleComboBox.setItemText(0, translate('SettingsForm', 'No brackets'))
1589 self.DisplayStyleComboBox.setItemText(1, translate('SettingsForm', '( and )'))
1590 self.DisplayStyleComboBox.setItemText(2, translate('SettingsForm', '{ and }'))
1591@@ -165,6 +185,7 @@
1592 self.paragraph_style = self.convertStringToBoolean(self.config.get_config('paragraph style', u'True'))
1593 self.show_new_chapters = self.convertStringToBoolean(self.config.get_config('display new chapter', u"False"))
1594 self.display_style = int(self.config.get_config('display brackets', '0'))
1595+ self.bible_theme = int(self.config.get_config('bible theme', '0'))
1596 self.bible_search = self.convertStringToBoolean(self.config.get_config('search as type', u'True'))
1597 if self.paragraph_style:
1598 self.ParagraphRadioButton.setChecked(True)
1599@@ -173,9 +194,14 @@
1600 self.NewChaptersCheckBox.setChecked(self.show_new_chapters)
1601 self.DisplayStyleComboBox.setCurrentIndex(self.display_style)
1602 self.BibleSearchCheckBox.setChecked(self.bible_search)
1603+ if self.bible_theme == 0: # must be new set to first
1604+ self.BibleThemeComboBox.setCurrentIndex(self.bible_theme)
1605+ else:
1606+ pass # TODO need to code
1607
1608 def save(self):
1609 self.config.set_config("paragraph style", str(self.paragraph_style))
1610 self.config.set_config("display new chapter", str(self.show_new_chapters))
1611 self.config.set_config("display brackets", str(self.display_style))
1612 self.config.set_config("search as type", str(self.bible_search))
1613+ self.config.set_config("bible theme", str(self.bible_theme))
1614
1615=== added file 'resources/forms/amendthemedialog.ui'
1616--- resources/forms/amendthemedialog.ui 1970-01-01 00:00:00 +0000
1617+++ resources/forms/amendthemedialog.ui 2009-04-04 17:36:15 +0000
1618@@ -0,0 +1,547 @@
1619+<?xml version="1.0" encoding="UTF-8"?>
1620+<ui version="4.0">
1621+ <class>AmendThemeDialog</class>
1622+ <widget class="QWidget" name="AmendThemeDialog">
1623+ <property name="geometry">
1624+ <rect>
1625+ <x>0</x>
1626+ <y>0</y>
1627+ <width>752</width>
1628+ <height>533</height>
1629+ </rect>
1630+ </property>
1631+ <property name="windowTitle">
1632+ <string>Theme Maintance</string>
1633+ </property>
1634+ <property name="windowIcon">
1635+ <iconset resource="../images/openlp-2.qrc">
1636+ <normaloff>:/icon/openlp.org-icon-32.bmp</normaloff>:/icon/openlp.org-icon-32.bmp</iconset>
1637+ </property>
1638+ <widget class="QDialogButtonBox" name="ThemeButtonBox">
1639+ <property name="geometry">
1640+ <rect>
1641+ <x>580</x>
1642+ <y>500</y>
1643+ <width>156</width>
1644+ <height>26</height>
1645+ </rect>
1646+ </property>
1647+ <property name="standardButtons">
1648+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
1649+ </property>
1650+ </widget>
1651+ <widget class="QWidget" name="layoutWidget">
1652+ <property name="geometry">
1653+ <rect>
1654+ <x>30</x>
1655+ <y>70</y>
1656+ <width>691</width>
1657+ <height>401</height>
1658+ </rect>
1659+ </property>
1660+ <layout class="QHBoxLayout" name="horizontalLayout_2">
1661+ <item>
1662+ <widget class="QWidget" name="LeftSide" native="true">
1663+ <widget class="QTabWidget" name="tabWidget">
1664+ <property name="geometry">
1665+ <rect>
1666+ <x>0</x>
1667+ <y>0</y>
1668+ <width>341</width>
1669+ <height>401</height>
1670+ </rect>
1671+ </property>
1672+ <property name="currentIndex">
1673+ <number>1</number>
1674+ </property>
1675+ <widget class="QWidget" name="BackgroundTab">
1676+ <attribute name="title">
1677+ <string>Background</string>
1678+ </attribute>
1679+ <widget class="QWidget" name="layoutWidget">
1680+ <property name="geometry">
1681+ <rect>
1682+ <x>10</x>
1683+ <y>10</y>
1684+ <width>321</width>
1685+ <height>351</height>
1686+ </rect>
1687+ </property>
1688+ <layout class="QGridLayout" name="gridLayout">
1689+ <item row="0" column="0" colspan="2">
1690+ <widget class="QLabel" name="BackgroundLabel">
1691+ <property name="text">
1692+ <string>Background:</string>
1693+ </property>
1694+ </widget>
1695+ </item>
1696+ <item row="0" column="2" colspan="2">
1697+ <widget class="QComboBox" name="BackgroundComboBox">
1698+ <item>
1699+ <property name="text">
1700+ <string>Opaque</string>
1701+ </property>
1702+ </item>
1703+ <item>
1704+ <property name="text">
1705+ <string>Transparent</string>
1706+ </property>
1707+ </item>
1708+ </widget>
1709+ </item>
1710+ <item row="1" column="0" colspan="2">
1711+ <widget class="QLabel" name="BackgroundTypeLabel">
1712+ <property name="text">
1713+ <string>Background Type:</string>
1714+ </property>
1715+ </widget>
1716+ </item>
1717+ <item row="1" column="2" colspan="2">
1718+ <widget class="QComboBox" name="BackgroundTypeComboBox">
1719+ <item>
1720+ <property name="text">
1721+ <string>Solid Color</string>
1722+ </property>
1723+ </item>
1724+ <item>
1725+ <property name="text">
1726+ <string>Gradient</string>
1727+ </property>
1728+ </item>
1729+ <item>
1730+ <property name="text">
1731+ <string>Image</string>
1732+ </property>
1733+ </item>
1734+ </widget>
1735+ </item>
1736+ <item row="2" column="0">
1737+ <widget class="QLabel" name="Color1Label">
1738+ <property name="text">
1739+ <string>&lt;Color1&gt;</string>
1740+ </property>
1741+ </widget>
1742+ </item>
1743+ <item row="2" column="2" colspan="2">
1744+ <widget class="QPushButton" name="Color1PushButton">
1745+ <property name="text">
1746+ <string/>
1747+ </property>
1748+ </widget>
1749+ </item>
1750+ <item row="3" column="0">
1751+ <widget class="QLabel" name="Color2Label">
1752+ <property name="text">
1753+ <string>&lt;Color2&gt;</string>
1754+ </property>
1755+ </widget>
1756+ </item>
1757+ <item row="3" column="2" colspan="2">
1758+ <widget class="QPushButton" name="Color2PushButton">
1759+ <property name="text">
1760+ <string/>
1761+ </property>
1762+ </widget>
1763+ </item>
1764+ <item row="4" column="0">
1765+ <widget class="QLabel" name="ImageLabel">
1766+ <property name="text">
1767+ <string>Image:</string>
1768+ </property>
1769+ </widget>
1770+ </item>
1771+ <item row="4" column="1" colspan="2">
1772+ <widget class="QLineEdit" name="ImageLineEdit"/>
1773+ </item>
1774+ <item row="4" column="3">
1775+ <widget class="QPushButton" name="ImagePushButton">
1776+ <property name="text">
1777+ <string/>
1778+ </property>
1779+ <property name="icon">
1780+ <iconset resource="../images/openlp-2.qrc">
1781+ <normaloff>:/services/service_open.png</normaloff>:/services/service_open.png</iconset>
1782+ </property>
1783+ </widget>
1784+ </item>
1785+ <item row="5" column="0">
1786+ <widget class="QLabel" name="GradientLabel">
1787+ <property name="text">
1788+ <string>Gradient :</string>
1789+ </property>
1790+ </widget>
1791+ </item>
1792+ <item row="5" column="2" colspan="2">
1793+ <widget class="QComboBox" name="GradientComboBox">
1794+ <item>
1795+ <property name="text">
1796+ <string>Horizontal</string>
1797+ </property>
1798+ </item>
1799+ <item>
1800+ <property name="text">
1801+ <string>Vertical</string>
1802+ </property>
1803+ </item>
1804+ <item>
1805+ <property name="text">
1806+ <string>Circular</string>
1807+ </property>
1808+ </item>
1809+ </widget>
1810+ </item>
1811+ </layout>
1812+ </widget>
1813+ </widget>
1814+ <widget class="QWidget" name="FontTab">
1815+ <attribute name="title">
1816+ <string>Font</string>
1817+ </attribute>
1818+ <widget class="QGroupBox" name="MainFontGroupBox">
1819+ <property name="geometry">
1820+ <rect>
1821+ <x>20</x>
1822+ <y>20</y>
1823+ <width>307</width>
1824+ <height>119</height>
1825+ </rect>
1826+ </property>
1827+ <property name="title">
1828+ <string>Main Font</string>
1829+ </property>
1830+ <layout class="QGridLayout" name="gridLayout_2">
1831+ <item row="0" column="0">
1832+ <widget class="QLabel" name="MainFontlabel">
1833+ <property name="text">
1834+ <string>Font:</string>
1835+ </property>
1836+ </widget>
1837+ </item>
1838+ <item row="0" column="1" colspan="2">
1839+ <widget class="QFontComboBox" name="MainFontComboBox"/>
1840+ </item>
1841+ <item row="1" column="0">
1842+ <widget class="QLabel" name="MainFontColorLabel">
1843+ <property name="text">
1844+ <string>Font Color</string>
1845+ </property>
1846+ </widget>
1847+ </item>
1848+ <item row="1" column="2">
1849+ <widget class="QPushButton" name="MainFontColorPushButton">
1850+ <property name="text">
1851+ <string/>
1852+ </property>
1853+ </widget>
1854+ </item>
1855+ <item row="2" column="0">
1856+ <widget class="QLabel" name="MainFontSize">
1857+ <property name="text">
1858+ <string>Size:</string>
1859+ </property>
1860+ </widget>
1861+ </item>
1862+ <item row="2" column="1">
1863+ <widget class="QLineEdit" name="MainFontSizeLineEdit"/>
1864+ </item>
1865+ <item row="2" column="2">
1866+ <widget class="QSlider" name="MainFontlSlider">
1867+ <property name="value">
1868+ <number>15</number>
1869+ </property>
1870+ <property name="maximum">
1871+ <number>40</number>
1872+ </property>
1873+ <property name="orientation">
1874+ <enum>Qt::Horizontal</enum>
1875+ </property>
1876+ <property name="tickPosition">
1877+ <enum>QSlider::TicksBelow</enum>
1878+ </property>
1879+ <property name="tickInterval">
1880+ <number>5</number>
1881+ </property>
1882+ </widget>
1883+ </item>
1884+ </layout>
1885+ </widget>
1886+ <widget class="QGroupBox" name="FooterFontGroupBox">
1887+ <property name="geometry">
1888+ <rect>
1889+ <x>20</x>
1890+ <y>170</y>
1891+ <width>307</width>
1892+ <height>119</height>
1893+ </rect>
1894+ </property>
1895+ <property name="title">
1896+ <string>Footer Font</string>
1897+ </property>
1898+ <layout class="QGridLayout" name="gridLayout_3">
1899+ <item row="0" column="0">
1900+ <widget class="QLabel" name="FooterFontlabel">
1901+ <property name="text">
1902+ <string>Font:</string>
1903+ </property>
1904+ </widget>
1905+ </item>
1906+ <item row="0" column="1" colspan="2">
1907+ <widget class="QFontComboBox" name="FooterFontComboBox"/>
1908+ </item>
1909+ <item row="1" column="0">
1910+ <widget class="QLabel" name="FooterFontColorLabel">
1911+ <property name="text">
1912+ <string>Font Color</string>
1913+ </property>
1914+ </widget>
1915+ </item>
1916+ <item row="1" column="2">
1917+ <widget class="QPushButton" name="FooterColorPushButton">
1918+ <property name="text">
1919+ <string/>
1920+ </property>
1921+ </widget>
1922+ </item>
1923+ <item row="2" column="0">
1924+ <widget class="QLabel" name="FooterFontSize">
1925+ <property name="text">
1926+ <string>Size:</string>
1927+ </property>
1928+ </widget>
1929+ </item>
1930+ <item row="2" column="1">
1931+ <widget class="QLineEdit" name="FooterFontSizeLineEdit"/>
1932+ </item>
1933+ <item row="2" column="2">
1934+ <widget class="QSlider" name="FooterFontlSlider">
1935+ <property name="value">
1936+ <number>15</number>
1937+ </property>
1938+ <property name="maximum">
1939+ <number>40</number>
1940+ </property>
1941+ <property name="orientation">
1942+ <enum>Qt::Horizontal</enum>
1943+ </property>
1944+ <property name="tickPosition">
1945+ <enum>QSlider::TicksBelow</enum>
1946+ </property>
1947+ <property name="tickInterval">
1948+ <number>5</number>
1949+ </property>
1950+ </widget>
1951+ </item>
1952+ </layout>
1953+ </widget>
1954+ </widget>
1955+ <widget class="QWidget" name="OptionsTab">
1956+ <attribute name="title">
1957+ <string>Display Options</string>
1958+ </attribute>
1959+ <widget class="QGroupBox" name="ShadowGroupBox">
1960+ <property name="geometry">
1961+ <rect>
1962+ <x>20</x>
1963+ <y>10</y>
1964+ <width>301</width>
1965+ <height>80</height>
1966+ </rect>
1967+ </property>
1968+ <property name="title">
1969+ <string>Shadow</string>
1970+ </property>
1971+ <widget class="QWidget" name="layoutWidget">
1972+ <property name="geometry">
1973+ <rect>
1974+ <x>10</x>
1975+ <y>20</y>
1976+ <width>281</width>
1977+ <height>54</height>
1978+ </rect>
1979+ </property>
1980+ <layout class="QFormLayout" name="formLayout">
1981+ <item row="0" column="0">
1982+ <widget class="QCheckBox" name="ShadowCheckBox">
1983+ <property name="text">
1984+ <string>Use Shadow</string>
1985+ </property>
1986+ </widget>
1987+ </item>
1988+ <item row="1" column="0">
1989+ <widget class="QLabel" name="ShadowColorLabel">
1990+ <property name="text">
1991+ <string>Shadow Color:</string>
1992+ </property>
1993+ </widget>
1994+ </item>
1995+ <item row="1" column="1">
1996+ <widget class="QPushButton" name="ShadowColorPushButton">
1997+ <property name="text">
1998+ <string/>
1999+ </property>
2000+ </widget>
2001+ </item>
2002+ </layout>
2003+ </widget>
2004+ </widget>
2005+ <widget class="QGroupBox" name="AlignmentGroupBox">
2006+ <property name="geometry">
2007+ <rect>
2008+ <x>10</x>
2009+ <y>200</y>
2010+ <width>321</width>
2011+ <height>161</height>
2012+ </rect>
2013+ </property>
2014+ <property name="title">
2015+ <string>Alignment</string>
2016+ </property>
2017+ <layout class="QGridLayout" name="gridLayout_4">
2018+ <item row="0" column="0">
2019+ <widget class="QLabel" name="HorizontalLabel">
2020+ <property name="text">
2021+ <string>Horizontal Align:</string>
2022+ </property>
2023+ </widget>
2024+ </item>
2025+ <item row="0" column="1">
2026+ <widget class="QComboBox" name="HorizontalComboBox">
2027+ <item>
2028+ <property name="text">
2029+ <string>Left</string>
2030+ </property>
2031+ </item>
2032+ <item>
2033+ <property name="text">
2034+ <string>Right</string>
2035+ </property>
2036+ </item>
2037+ <item>
2038+ <property name="text">
2039+ <string>Center</string>
2040+ </property>
2041+ </item>
2042+ </widget>
2043+ </item>
2044+ <item row="1" column="0">
2045+ <widget class="QLabel" name="VerticalLabel">
2046+ <property name="text">
2047+ <string>Vertical Align:</string>
2048+ </property>
2049+ </widget>
2050+ </item>
2051+ <item row="1" column="1">
2052+ <widget class="QComboBox" name="VerticalComboBox">
2053+ <item>
2054+ <property name="text">
2055+ <string>Top</string>
2056+ </property>
2057+ </item>
2058+ <item>
2059+ <property name="text">
2060+ <string>Middle</string>
2061+ </property>
2062+ </item>
2063+ <item>
2064+ <property name="text">
2065+ <string>Bottom</string>
2066+ </property>
2067+ </item>
2068+ </widget>
2069+ </item>
2070+ </layout>
2071+ </widget>
2072+ <widget class="QGroupBox" name="OutlineGroupBox">
2073+ <property name="geometry">
2074+ <rect>
2075+ <x>20</x>
2076+ <y>110</y>
2077+ <width>301</width>
2078+ <height>80</height>
2079+ </rect>
2080+ </property>
2081+ <property name="title">
2082+ <string>Outline</string>
2083+ </property>
2084+ <widget class="QWidget" name="layoutWidget_3">
2085+ <property name="geometry">
2086+ <rect>
2087+ <x>10</x>
2088+ <y>20</y>
2089+ <width>281</width>
2090+ <height>54</height>
2091+ </rect>
2092+ </property>
2093+ <layout class="QFormLayout" name="OutlineformLayout">
2094+ <item row="0" column="0">
2095+ <widget class="QCheckBox" name="OutlineCheckBox">
2096+ <property name="text">
2097+ <string>Use Outline</string>
2098+ </property>
2099+ </widget>
2100+ </item>
2101+ <item row="1" column="0">
2102+ <widget class="QLabel" name="OutlineColorLabel">
2103+ <property name="text">
2104+ <string>Outline Color:</string>
2105+ </property>
2106+ </widget>
2107+ </item>
2108+ <item row="1" column="1">
2109+ <widget class="QPushButton" name="OutlineColorPushButton">
2110+ <property name="text">
2111+ <string/>
2112+ </property>
2113+ </widget>
2114+ </item>
2115+ </layout>
2116+ </widget>
2117+ </widget>
2118+ </widget>
2119+ </widget>
2120+ </widget>
2121+ </item>
2122+ <item>
2123+ <widget class="QWidget" name="RightSide" native="true">
2124+ <widget class="QGraphicsView" name="ThemePreView">
2125+ <property name="geometry">
2126+ <rect>
2127+ <x>0</x>
2128+ <y>30</y>
2129+ <width>341</width>
2130+ <height>341</height>
2131+ </rect>
2132+ </property>
2133+ </widget>
2134+ </widget>
2135+ </item>
2136+ </layout>
2137+ </widget>
2138+ <widget class="QWidget" name="layoutWidget">
2139+ <property name="geometry">
2140+ <rect>
2141+ <x>50</x>
2142+ <y>20</y>
2143+ <width>441</width>
2144+ <height>41</height>
2145+ </rect>
2146+ </property>
2147+ <layout class="QHBoxLayout" name="horizontalLayout">
2148+ <item>
2149+ <widget class="QLabel" name="ThemeNameLabel">
2150+ <property name="text">
2151+ <string>Theme Name</string>
2152+ </property>
2153+ </widget>
2154+ </item>
2155+ <item>
2156+ <widget class="QLineEdit" name="ThemeNameEdit"/>
2157+ </item>
2158+ </layout>
2159+ </widget>
2160+ </widget>
2161+ <resources>
2162+ <include location="../images/openlp-2.qrc"/>
2163+ </resources>
2164+ <connections/>
2165+</ui>