Replace theme editor with wizard.

Revamp theme XML schema
Move theme code to use new schema and auto migrate V2 themes to it.
Revamp V1 import code.
Add two new gradient backgrounds.

bzr-revno: 1118
Fixes: https://launchpad.net/bugs/599146
This commit is contained in:
Tim Bentley 2010-11-19 19:18:37 +00:00
commit 8d7f6f454b
15 changed files with 2464 additions and 929 deletions

View File

@ -303,6 +303,8 @@ def expand_tags(text):
text = text.replace(tag[u'end tag'], tag[u'end html']) text = text.replace(tag[u'end tag'], tag[u'end html'])
return text return text
from theme import ThemeLevel, ThemeXML, BackgroundGradientType, BackgroundType, \
HorizontalType, VerticalType
from spelltextedit import SpellTextEdit from spelltextedit import SpellTextEdit
from eventreceiver import Receiver from eventreceiver import Receiver
from imagemanager import ImageManager from imagemanager import ImageManager
@ -317,7 +319,6 @@ from htmlbuilder import build_html, build_lyrics_format_css, \
build_lyrics_outline_css build_lyrics_outline_css
from toolbar import OpenLPToolbar from toolbar import OpenLPToolbar
from dockwidget import OpenLPDockWidget from dockwidget import OpenLPDockWidget
from theme import ThemeLevel, ThemeXML
from renderer import Renderer from renderer import Renderer
from rendermanager import RenderManager from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem from mediamanageritem import MediaManagerItem

View File

@ -25,8 +25,11 @@
############################################################################### ###############################################################################
import logging import logging
from PyQt4 import QtWebKit from PyQt4 import QtWebKit
from openlp.core.lib import BackgroundType, BackgroundGradientType
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
HTMLSRC = u""" HTMLSRC = u"""
@ -368,16 +371,32 @@ def build_background_css(item, width, height):
theme = item.themedata theme = item.themedata
background = u'background-color: black' background = u'background-color: black'
if theme: if theme:
if theme.background_type == u'solid': if theme.background_type == BackgroundType.to_string(BackgroundType.Solid):
background = u'background-color: %s' % theme.background_color background = u'background-color: %s' % theme.background_color
else: else:
if theme.background_direction == u'horizontal': if theme.background_direction == BackgroundGradientType.to_string \
(BackgroundGradientType.Horizontal):
background = \ background = \
u'background: ' \ u'background: ' \
u'-webkit-gradient(linear, left top, left bottom, ' \ u'-webkit-gradient(linear, left top, left bottom, ' \
'from(%s), to(%s))' % (theme.background_start_color, 'from(%s), to(%s))' % (theme.background_start_color,
theme.background_end_color) theme.background_end_color)
elif theme.background_direction == u'vertical': elif theme.background_direction == BackgroundGradientType.to_string \
(BackgroundGradientType.LeftTop):
background = \
u'background: ' \
u'-webkit-gradient(linear, left top, right bottom, ' \
'from(%s), to(%s))' % (theme.background_start_color,
theme.background_end_color)
elif theme.background_direction == BackgroundGradientType.to_string \
(BackgroundGradientType.LeftBottom):
background = \
u'background: ' \
u'-webkit-gradient(linear, left bottom, right top, ' \
'from(%s), to(%s))' % (theme.background_start_color,
theme.background_end_color)
elif theme.background_direction == BackgroundGradientType.to_string \
(BackgroundGradientType.Vertical):
background = \ background = \
u'background: -webkit-gradient(linear, left top, ' \ u'background: -webkit-gradient(linear, left top, ' \
u'right top, from(%s), to(%s))' % \ u'right top, from(%s), to(%s))' % \
@ -452,17 +471,17 @@ def build_lyrics_css(item, webkitvers):
lyricsmain += build_lyrics_outline_css(theme) lyricsmain += build_lyrics_outline_css(theme)
else: else:
outline = build_lyrics_outline_css(theme) outline = build_lyrics_outline_css(theme)
if theme.display_shadow: if theme.font_main_shadow:
if theme.display_outline and webkitvers < 534.3: if theme.font_main_outline and webkitvers < 534.3:
shadow = u'padding-left: %spx; padding-top: %spx;' % \ shadow = u'padding-left: %spx; padding-top: %spx;' % \
(int(theme.display_shadow_size) + (int(theme.font_main_shadow_size) +
(int(theme.display_outline_size) * 2), (int(theme.font_main_outline_size) * 2),
theme.display_shadow_size) theme.font_main_shadow_size)
shadow += build_lyrics_outline_css(theme, True) shadow += build_lyrics_outline_css(theme, True)
else: else:
lyricsmain += u' text-shadow: %s %spx %spx;' % \ lyricsmain += u' text-shadow: %s %spx %spx;' % \
(theme.display_shadow_color, theme.display_shadow_size, (theme.font_main_shadow_color, theme.font_main_shadow_size,
theme.display_shadow_size) theme.font_main_shadow_size)
lyrics_css = style % (lyricstable, lyrics, lyricsmain, outline, shadow) lyrics_css = style % (lyricstable, lyrics, lyricsmain, outline, shadow)
return lyrics_css return lyrics_css
@ -477,14 +496,14 @@ def build_lyrics_outline_css(theme, is_shadow=False):
`is_shadow` `is_shadow`
If true, use the shadow colors instead If true, use the shadow colors instead
""" """
if theme.display_outline: if theme.font_main_outline:
size = float(theme.display_outline_size) / 16 size = float(theme.font_main_outline_size) / 16
if is_shadow: if is_shadow:
fill_color = theme.display_shadow_color fill_color = theme.font_main_shadow_color
outline_color = theme.display_shadow_color outline_color = theme.font_main_shadow_color
else: else:
fill_color = theme.font_main_color fill_color = theme.font_main_color
outline_color = theme.display_outline_color outline_color = theme.font_main_outline_color
return u' -webkit-text-stroke: %sem %s; ' \ return u' -webkit-text-stroke: %sem %s; ' \
u'-webkit-text-fill-color: %s; ' % (size, outline_color, fill_color) u'-webkit-text-fill-color: %s; ' % (size, outline_color, fill_color)
else: else:
@ -517,23 +536,23 @@ def build_lyrics_format_css(theme, width, height):
valign = u'middle' valign = u'middle'
else: else:
valign = u'top' valign = u'top'
if theme.display_outline: if theme.font_main_outline:
left_margin = int(theme.display_outline_size) * 2 left_margin = int(theme.font_main_outline_size) * 2
else: else:
left_margin = 0 left_margin = 0
lyrics = u'white-space:pre-wrap; word-wrap: break-word; ' \ lyrics = u'white-space:pre-wrap; word-wrap: break-word; ' \
'text-align: %s; vertical-align: %s; font-family: %s; ' \ 'text-align: %s; vertical-align: %s; font-family: %s; ' \
'font-size: %spt; color: %s; line-height: %d%%; margin:0;' \ 'font-size: %spt; color: %s; line-height: %d%%; margin:0;' \
'padding:0; padding-left:%spx; width: %spx; height: %spx; ' % \ 'padding:0; padding-left:%spx; width: %spx; height: %spx; ' % \
(align, valign, theme.font_main_name, theme.font_main_proportion, (align, valign, theme.font_main_name, theme.font_main_size,
theme.font_main_color, 100 + int(theme.font_main_line_adjustment), theme.font_main_color, 100 + int(theme.font_main_line_adjustment),
left_margin, width, height) left_margin, width, height)
if theme.display_outline: if theme.font_main_outline:
if webkit_version() < 534.3: if webkit_version() < 534.3:
lyrics += u' letter-spacing: 1px;' lyrics += u' letter-spacing: 1px;'
if theme.font_main_italics: if theme.font_main_italics:
lyrics += u' font-style:italic; ' lyrics += u' font-style:italic; '
if theme.font_main_weight == u'Bold': if theme.font_main_bold:
lyrics += u' font-weight:bold; ' lyrics += u' font-weight:bold; '
return lyrics return lyrics
@ -553,7 +572,7 @@ def build_lyrics_html(item, webkitvers):
# display:table/display:table-cell are required for each lyric block. # display:table/display:table-cell are required for each lyric block.
lyrics = u'' lyrics = u''
theme = item.themedata theme = item.themedata
if webkitvers < 534.4 and theme and theme.display_outline: if webkitvers < 534.4 and theme and theme.font_main_outline:
lyrics += u'<div class="lyricstable">' \ lyrics += u'<div class="lyricstable">' \
u'<div id="lyricsshadow" style="opacity:1" ' \ u'<div id="lyricsshadow" style="opacity:1" ' \
u'class="lyricscell lyricsshadow"></div></div>' u'class="lyricscell lyricsshadow"></div></div>'
@ -589,7 +608,7 @@ def build_footer_css(item, height):
bottom = height - int(item.footer.y()) - int(item.footer.height()) bottom = height - int(item.footer.y()) - int(item.footer.height())
lyrics_html = style % (item.footer.x(), bottom, lyrics_html = style % (item.footer.x(), bottom,
item.footer.width(), theme.font_footer_name, item.footer.width(), theme.font_footer_name,
theme.font_footer_proportion, theme.font_footer_color) theme.font_footer_size, theme.font_footer_color)
return lyrics_html return lyrics_html
def build_alert_css(alertTab, width): def build_alert_css(alertTab, width):

View File

@ -77,9 +77,9 @@ class Renderer(object):
self._rect_footer = rect_footer self._rect_footer = rect_footer
self.page_width = self._rect.width() self.page_width = self._rect.width()
self.page_height = self._rect.height() self.page_height = self._rect.height()
if self._theme.display_shadow: if self._theme.font_main_shadow:
self.page_width -= int(self._theme.display_shadow_size) self.page_width -= int(self._theme.font_main_shadow_size)
self.page_height -= int(self._theme.display_shadow_size) self.page_height -= int(self._theme.font_main_shadow_size)
self.web = QtWebKit.QWebView() self.web = QtWebKit.QWebView()
self.web.setVisible(False) self.web.setVisible(False)
self.web.resize(self.page_width, self.page_height) self.web.resize(self.page_width, self.page_height)

View File

@ -28,52 +28,56 @@ Provide the theme XML and handling functions for OpenLP v2 themes.
""" """
import os import os
import re import re
import logging
from xml.dom.minidom import Document from xml.dom.minidom import Document
from xml.etree.ElementTree import ElementTree, XML from xml.etree.ElementTree import ElementTree, XML
from lxml import etree, objectify
from openlp.core.lib import str_to_bool from openlp.core.lib import str_to_bool
log = logging.getLogger(__name__)
BLANK_THEME_XML = \ BLANK_THEME_XML = \
'''<?xml version="1.0" encoding="utf-8"?> '''<?xml version="1.0" encoding="utf-8"?>
<theme version="1.0"> <theme version="1.0">
<name>BlankStyle</name> <name> </name>
<background mode="transparent"/> <background type="image">
<background type="solid" mode="opaque"> <filename></filename>
<color>#000000</color>
</background> </background>
<background type="gradient" mode="opaque"> <background type="gradient">
<startColor>#000000</startColor> <startColor>#000000</startColor>
<endColor>#000000</endColor> <endColor>#000000</endColor>
<direction>vertical</direction> <direction>vertical</direction>
</background> </background>
<background type="image" mode="opaque"> <background type="solid">
<filename></filename> <color>#000000</color>
</background> </background>
<font type="main"> <font type="main">
<name>Arial</name> <name>Arial</name>
<color>#000000</color> <color>#FFFFFF</color>
<proportion>30</proportion> <size>30</size>
<weight>Normal</weight> <bold>False</bold>
<italics>False</italics> <italics>False</italics>
<line_adjustment>0</line_adjustment> <line_adjustment>0</line_adjustment>
<shadow shadowColor="#000000" shadowSize="5">True</shadow>
<outline outlineColor="#000000" outlineSize="2">False</outline>
<location override="False" x="10" y="10" width="1004" height="690"/> <location override="False" x="10" y="10" width="1004" height="690"/>
</font> </font>
<font type="footer"> <font type="footer">
<name>Arial</name> <name>Arial</name>
<color>#000000</color> <color>#FFFFFF</color>
<proportion>12</proportion> <size>12</size>
<weight>Normal</weight> <bold>False</bold>
<italics>False</italics> <italics>False</italics>
<line_adjustment>0</line_adjustment> <line_adjustment>0</line_adjustment>
<shadow shadowColor="#000000" shadowSize="5">True</shadow>
<outline outlineColor="#000000" outlineSize="2">False</outline>
<location override="False" x="10" y="690" width="1004" height="78"/> <location override="False" x="10" y="690" width="1004" height="78"/>
</font> </font>
<display> <display>
<shadow color="#000000" size="5">True</shadow>
<outline color="#000000" size="2">False</outline>
<horizontalAlign>0</horizontalAlign> <horizontalAlign>0</horizontalAlign>
<verticalAlign>0</verticalAlign> <verticalAlign>0</verticalAlign>
<wrapStyle>0</wrapStyle>
<slideTransition>False</slideTransition> <slideTransition>False</slideTransition>
</display> </display>
</theme> </theme>
@ -87,10 +91,76 @@ class ThemeLevel(object):
Service = 2 Service = 2
Song = 3 Song = 3
class BackgroundType(object):
Solid = 0
Gradient = 1
Image = 2
@staticmethod
def to_string(type):
if type == BackgroundType.Solid:
return u'solid'
elif type == BackgroundType.Gradient:
return u'gradient'
elif type == BackgroundType.Image:
return u'image'
@staticmethod
def from_string(type_string):
if type_string == u'solid':
return BackgroundType.Solid
elif type_string == u'gradient':
return BackgroundType.Gradient
elif type_string == u'image':
return BackgroundType.Image
class BackgroundGradientType(object):
Horizontal = 0
Vertical = 1
Circular = 2
LeftTop = 3
LeftBottom = 4
@staticmethod
def to_string(type):
if type == BackgroundGradientType.Horizontal:
return u'horizontal'
elif type == BackgroundGradientType.Vertical:
return u'vertical'
elif type == BackgroundGradientType.Circular:
return u'circular'
elif type == BackgroundGradientType.LeftTop:
return u'leftTop'
elif type == BackgroundGradientType.LeftBottom:
return u'leftBottom'
@staticmethod
def from_string(type_string):
if type_string == u'horizontal':
return BackgroundGradientType.Horizontal
elif type_string == u'vertical':
return BackgroundGradientType.Vertical
elif type_string == u'circular':
return BackgroundGradientType.Circular
elif type_string == u'leftTop':
return BackgroundGradientType.LeftTop
elif type_string == u'leftBottom':
return BackgroundGradientType.LeftBottom
class HorizontalType(object):
Left = 0
Center = 1
Right = 2
class VerticalType(object):
Top = 0
Middle = 1
Bottom = 2
boolean_list = [u'italics', u'override', u'outline', u'shadow', boolean_list = [u'italics', u'override', u'outline', u'shadow',
u'slide_transition'] u'slide_transition']
integer_list = [u'proportion', u'line_adjustment', u'x', u'height', u'y', integer_list = [u'size', u'line_adjustment', u'x', u'height', u'y',
u'width', u'shadow_size', u'outline_size', u'horizontal_align', u'width', u'shadow_size', u'outline_size', u'horizontal_align',
u'vertical_align', u'wrap_style'] u'vertical_align', u'wrap_style']
@ -104,6 +174,7 @@ class ThemeXML(object):
""" """
# Create the minidom document # Create the minidom document
self.theme_xml = Document() self.theme_xml = Document()
self.parse_xml(BLANK_THEME_XML)
def extend_image_filename(self, path): def extend_image_filename(self, path):
""" """
@ -112,19 +183,21 @@ class ThemeXML(object):
``path`` ``path``
The path name to be added. The path name to be added.
""" """
if self.background_filename and path: if self.background_type == u'image':
self.theme_name = self.theme_name.strip() if self.background_filename and path:
self.background_filename = self.background_filename.strip() self.theme_name = self.theme_name.strip()
self.background_filename = os.path.join(path, self.theme_name, self.background_filename = self.background_filename.strip()
self.background_filename) self.background_filename = os.path.join(path, self.theme_name,
self.background_filename)
def new_document(self, name): def _new_document(self, name):
""" """
Create a new theme XML document. Create a new theme XML document.
""" """
self.theme_xml = Document()
self.theme = self.theme_xml.createElement(u'theme') self.theme = self.theme_xml.createElement(u'theme')
self.theme_xml.appendChild(self.theme) self.theme_xml.appendChild(self.theme)
self.theme.setAttribute(u'version', u'1.0') self.theme.setAttribute(u'version', u'2.0')
self.name = self.theme_xml.createElement(u'name') self.name = self.theme_xml.createElement(u'name')
text_node = self.theme_xml.createTextNode(name) text_node = self.theme_xml.createTextNode(name)
self.name.appendChild(text_node) self.name.appendChild(text_node)
@ -146,10 +219,9 @@ class ThemeXML(object):
The color of the background. The color of the background.
""" """
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') background.setAttribute(u'type', u'solid')
self.theme.appendChild(background) self.theme.appendChild(background)
self.child_element(background, u'color', bkcolor) self.child_element(background, u'color', unicode(bkcolor))
def add_background_gradient(self, startcolor, endcolor, direction): def add_background_gradient(self, startcolor, endcolor, direction):
""" """
@ -165,15 +237,14 @@ class ThemeXML(object):
The direction of the gradient. The direction of the gradient.
""" """
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'gradient') background.setAttribute(u'type', u'gradient')
self.theme.appendChild(background) self.theme.appendChild(background)
# Create startColor element # Create startColor element
self.child_element(background, u'startColor', startcolor) self.child_element(background, u'startColor', unicode(startcolor))
# Create endColor element # Create endColor element
self.child_element(background, u'endColor', endcolor) self.child_element(background, u'endColor', unicode(endcolor))
# Create direction element # Create direction element
self.child_element(background, u'direction', direction) self.child_element(background, u'direction', unicode(direction))
def add_background_image(self, filename): def add_background_image(self, filename):
""" """
@ -183,15 +254,15 @@ class ThemeXML(object):
The file name of the image. The file name of the image.
""" """
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'image') background.setAttribute(u'type', u'image')
self.theme.appendChild(background) self.theme.appendChild(background)
#Create Filename element # Create Filename element
self.child_element(background, u'filename', filename) self.child_element(background, u'filename', filename)
def add_font(self, name, color, proportion, override, fonttype=u'main', def add_font(self, name, color, size, override, fonttype=u'main',
weight=u'Normal', italics=u'False', line_adjustment=0, bold=u'False', italics=u'False', line_adjustment=0,
xpos=0, ypos=0, width=0, height=0): xpos=0, ypos=0, width=0, height=0 , outline=u'False', outline_color=u'#ffffff',
outline_pixel=2, shadow=u'False', shadow_color=u'#ffffff', shadow_pixel=5):
""" """
Add a Font. Add a Font.
@ -201,7 +272,7 @@ class ThemeXML(object):
``color`` ``color``
The colour of the font. The colour of the font.
``proportion`` ``size``
The size of the font. The size of the font.
``override`` ``override``
@ -227,45 +298,6 @@ class ThemeXML(object):
``height`` ``height``
The height of the text block. The height of the text block.
"""
background = self.theme_xml.createElement(u'font')
background.setAttribute(u'type', fonttype)
self.theme.appendChild(background)
#Create Font name element
self.child_element(background, u'name', name)
#Create Font color element
self.child_element(background, u'color', color)
#Create Proportion name element
self.child_element(background, u'proportion', proportion)
#Create weight name element
self.child_element(background, u'weight', weight)
#Create italics name element
self.child_element(background, u'italics', italics)
#Create indentation name element
self.child_element(
background, u'line_adjustment', unicode(line_adjustment))
#Create Location element
element = self.theme_xml.createElement(u'location')
element.setAttribute(u'override', override)
if override == u'True':
element.setAttribute(u'x', xpos)
element.setAttribute(u'y', ypos)
element.setAttribute(u'width', width)
element.setAttribute(u'height', height)
background.appendChild(element)
def add_display(self, shadow, shadow_color, outline, outline_color,
horizontal, vertical, wrap, transition, shadow_pixel=5,
outline_pixel=2):
"""
Add a Display options.
``shadow``
Whether or not to show a shadow.
``shadow_color``
The colour of the shadow.
``outline`` ``outline``
Whether or not to show an outline. Whether or not to show an outline.
@ -273,53 +305,88 @@ class ThemeXML(object):
``outline_color`` ``outline_color``
The colour of the outline. The colour of the outline.
``outline_size``
How big the Shadow is
``shadow``
Whether or not to show a shadow.
``shadow_color``
The colour of the shadow.
``shadow_size``
How big the Shadow is
"""
background = self.theme_xml.createElement(u'font')
background.setAttribute(u'type', fonttype)
self.theme.appendChild(background)
# Create Font name element
self.child_element(background, u'name', name)
# Create Font color element
self.child_element(background, u'color', color)
# Create Proportion name element
self.child_element(background, u'size', unicode(size))
# Create weight name element
self.child_element(background, u'bold', unicode(bold))
# Create italics name element
self.child_element(background, u'italics', unicode(italics))
# Create indentation name element
self.child_element(
background, u'line_adjustment', unicode(line_adjustment))
# Create Location element
element = self.theme_xml.createElement(u'location')
element.setAttribute(u'override', unicode(override))
element.setAttribute(u'x', unicode(xpos))
element.setAttribute(u'y', unicode(ypos))
element.setAttribute(u'width', unicode(width))
element.setAttribute(u'height', unicode(height))
background.appendChild(element)
# Shadow
element = self.theme_xml.createElement(u'shadow')
element.setAttribute(u'shadowColor', unicode(shadow_color))
element.setAttribute(u'shadowSize', unicode(shadow_pixel))
value = self.theme_xml.createTextNode(unicode(shadow))
element.appendChild(value)
background.appendChild(element)
# Outline
element = self.theme_xml.createElement(u'outline')
element.setAttribute(u'outlineColor', unicode(outline_color))
element.setAttribute(u'outlineSize', unicode(outline_pixel))
value = self.theme_xml.createTextNode(unicode(outline))
element.appendChild(value)
background.appendChild(element)
def add_display(self, horizontal, vertical, transition):
"""
Add a Display options.
``horizontal`` ``horizontal``
The horizontal alignment of the text. The horizontal alignment of the text.
``vertical`` ``vertical``
The vertical alignment of the text. The vertical alignment of the text.
``wrap``
Wrap style.
``transition`` ``transition``
Whether the slide transition is active. Whether the slide transition is active.
""" """
background = self.theme_xml.createElement(u'display') background = self.theme_xml.createElement(u'display')
self.theme.appendChild(background) self.theme.appendChild(background)
# Shadow
element = self.theme_xml.createElement(u'shadow')
element.setAttribute(u'color', shadow_color)
element.setAttribute(u'size', unicode(shadow_pixel))
value = self.theme_xml.createTextNode(shadow)
element.appendChild(value)
background.appendChild(element)
# Outline
element = self.theme_xml.createElement(u'outline')
element.setAttribute(u'color', outline_color)
element.setAttribute(u'size', unicode(outline_pixel))
value = self.theme_xml.createTextNode(outline)
element.appendChild(value)
background.appendChild(element)
# Horizontal alignment # Horizontal alignment
element = self.theme_xml.createElement(u'horizontalAlign') element = self.theme_xml.createElement(u'horizontalAlign')
value = self.theme_xml.createTextNode(horizontal) value = self.theme_xml.createTextNode(unicode(horizontal))
element.appendChild(value) element.appendChild(value)
background.appendChild(element) background.appendChild(element)
# Vertical alignment # Vertical alignment
element = self.theme_xml.createElement(u'verticalAlign') element = self.theme_xml.createElement(u'verticalAlign')
value = self.theme_xml.createTextNode(vertical) value = self.theme_xml.createTextNode(unicode(vertical))
element.appendChild(value)
background.appendChild(element)
# Wrap style
element = self.theme_xml.createElement(u'wrapStyle')
value = self.theme_xml.createTextNode(wrap)
element.appendChild(value) element.appendChild(value)
background.appendChild(element) background.appendChild(element)
# Slide Transition # Slide Transition
element = self.theme_xml.createElement(u'slideTransition') element = self.theme_xml.createElement(u'slideTransition')
value = self.theme_xml.createTextNode(transition) value = self.theme_xml.createTextNode(unicode(transition))
element.appendChild(value) element.appendChild(value)
background.appendChild(element) background.appendChild(element)
@ -342,12 +409,14 @@ class ThemeXML(object):
""" """
Print out the XML string. Print out the XML string.
""" """
self._build_xml_from_attrs()
return self.theme_xml.toxml(u'utf-8').decode(u'utf-8') return self.theme_xml.toxml(u'utf-8').decode(u'utf-8')
def extract_formatted_xml(self): def extract_formatted_xml(self):
""" """
Pull out the XML string formatted for human consumption Pull out the XML string formatted for human consumption
""" """
self._build_xml_from_attrs()
return self.theme_xml.toprettyxml(indent=u' ', newl=u'\n', return self.theme_xml.toprettyxml(indent=u' ', newl=u'\n',
encoding=u'utf-8') encoding=u'utf-8')
@ -358,8 +427,7 @@ class ThemeXML(object):
``xml`` ``xml``
The XML string to parse. The XML string to parse.
""" """
self.parse_xml(BLANK_THEME_XML) self.parse_xml(unicode(xml))
self.parse_xml(xml)
def parse_xml(self, xml): def parse_xml(self, xml):
""" """
@ -368,51 +436,95 @@ class ThemeXML(object):
``xml`` ``xml``
The XML string to parse. The XML string to parse.
""" """
theme_xml = ElementTree(element=XML(xml.encode(u'ascii', # remove encoding string
u'xmlcharrefreplace'))) line = xml.find(u'?>')
if line:
xml = xml[line + 2:]
try:
theme_xml = objectify.fromstring(xml)
except etree.XMLSyntaxError:
log.exception(u'Invalid xml %s', xml)
return
xml_iter = theme_xml.getiterator() xml_iter = theme_xml.getiterator()
master = u''
for element in xml_iter: for element in xml_iter:
if not isinstance(element.text, unicode): parent = element.getparent()
element.text = unicode(str(element.text), u'utf-8') master = u''
if element.getchildren(): if parent is not None:
master = element.tag + u'_' if element.getparent().tag == u'font':
master = element.getparent().tag + u'_' + \
element.getparent().attrib[u'type']
# set up Outline and Shadow Tags and move to font_main
if element.getparent().tag == u'display':
if element.tag.startswith(u'shadow') or \
element.tag.startswith(u'outline'):
self._create_attr(u'font_main', element.tag, element.text)
master = element.getparent().tag
if element.getparent().tag == u'background':
master = element.getparent().tag
if element.getparent().attrib:
for attr in element.getparent().attrib:
self._create_attr(master, attr, \
element.getparent().attrib[attr])
if master:
self._create_attr(master, element.tag, element.text)
if element.attrib:
for attr in element.attrib:
base_element = attr
# correction for the shadow and outline tags
if element.tag == u'shadow' or element.tag == u'outline':
if not attr.startswith(element.tag):
base_element = element.tag + u'_' + attr
self._create_attr(master, base_element,
element.attrib[attr])
else: else:
# background transparent tags have no children so special case if element.tag == u'name':
if element.tag == u'background': self._create_attr(u'theme', element.tag, element.text)
for e in element.attrib.iteritems():
self._create_attr(element.tag , e[0], e[1]) def _translate_tags(self, master, element, value):
if element.attrib: """
for e in element.attrib.iteritems(): Clean up XML removing and redefining tags
if master == u'font_' and e[0] == u'type': """
master += e[1] + u'_' master = master.strip().lstrip()
elif master == u'display_' and (element.tag == u'shadow' element = element.strip().lstrip()
or element.tag == u'outline'): value = unicode(value).strip().lstrip()
self._create_attr(master, element.tag, element.text) if master == u'display':
self._create_attr(master, element.tag + u'_'+ e[0], if element == u'wrapStyle':
e[1]) return True, None, None, None
else: if element.startswith(u'shadow') or element.startswith(u'outline'):
field = master + e[0] master = u'font_main'
self._create_attr(master, e[0], e[1]) # fix bold font
if element == u'weight':
element = u'bold'
if value == u'Normal':
value = False
else: else:
if element.tag: value = True
element.text = element.text.strip().lstrip() if element == u'proportion':
self._create_attr(master , element.tag, element.text) element = u'size'
return False, master, element, value
def _create_attr(self, master , element, value): def _create_attr(self, master , element, value):
""" """
Create the attributes with the correct data types and name format Create the attributes with the correct data types and name format
""" """
reject, master, element, value = \
self._translate_tags(master, element, value)
if reject:
return
field = self._de_hump(element) field = self._de_hump(element)
tag = master + u'_' + field
if field in boolean_list: if field in boolean_list:
setattr(self, master + field, str_to_bool(value)) setattr(self, tag, str_to_bool(value))
elif field in integer_list: elif field in integer_list:
setattr(self, master + field, int(value)) setattr(self, tag, int(value))
else: else:
# make string value unicode
if not isinstance(value, unicode):
value = unicode(str(value), u'utf-8')
# None means an empty string so lets have one. # None means an empty string so lets have one.
if value == u'None': if value == u'None':
value = u'' value = u''
setattr(self, master + field, unicode(value)) setattr(self, tag, unicode(value).strip().lstrip())
def __str__(self): def __str__(self):
""" """
@ -431,3 +543,58 @@ class ThemeXML(object):
s1 = re.sub(u'(.)([A-Z][a-z]+)', r'\1_\2', name) s1 = re.sub(u'(.)([A-Z][a-z]+)', r'\1_\2', name)
return re.sub(u'([a-z0-9])([A-Z])', r'\1_\2', s1).lower() return re.sub(u'([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
def _build_xml_from_attrs(self):
"""
Build the XML from the varables in the object
"""
self._new_document(self.theme_name)
if self.background_type == \
BackgroundType.to_string(BackgroundType.Solid):
self.add_background_solid(self.background_color)
elif self.background_type == \
BackgroundType.to_string(BackgroundType.Gradient):
self.add_background_gradient(
self.background_start_color,
self.background_end_color,
self.background_direction)
else:
filename = \
os.path.split(self.background_filename)[1]
self.add_background_image(filename)
self.add_font(self.font_main_name,
self.font_main_color,
self.font_main_size,
self.font_main_override, u'main',
self.font_main_bold,
self.font_main_italics,
self.font_main_line_adjustment,
self.font_main_x,
self.font_main_y,
self.font_main_width,
self.font_main_height,
self.font_main_outline,
self.font_main_outline_color,
self.font_main_outline_size,
self.font_main_shadow,
self.font_main_shadow_color,
self.font_main_shadow_size)
self.add_font(self.font_footer_name,
self.font_footer_color,
self.font_footer_size,
self.font_footer_override, u'footer',
self.font_footer_bold,
self.font_footer_italics,
0, # line adjustment
self.font_footer_x,
self.font_footer_y,
self.font_footer_width,
self.font_footer_height,
self.font_footer_outline,
self.font_footer_outline_color,
self.font_footer_outline_size,
self.font_footer_shadow,
self.font_footer_shadow_color,
self.font_footer_shadow_size)
self.add_display(self.display_horizontal_align,
self.display_vertical_align,
self.display_slide_transition)

View File

@ -37,12 +37,12 @@ class HideMode(object):
Theme = 2 Theme = 2
Screen = 3 Screen = 3
from themeform import ThemeForm
from filerenameform import FileRenameForm from filerenameform import FileRenameForm
from maindisplay import MainDisplay from maindisplay import MainDisplay
from servicenoteform import ServiceNoteForm from servicenoteform import ServiceNoteForm
from serviceitemeditform import ServiceItemEditForm from serviceitemeditform import ServiceItemEditForm
from screen import ScreenList from screen import ScreenList
from amendthemeform import AmendThemeForm
from slidecontroller import SlideController from slidecontroller import SlideController
from splashscreen import SplashScreen from splashscreen import SplashScreen
from generaltab import GeneralTab from generaltab import GeneralTab
@ -58,4 +58,4 @@ from thememanager import ThemeManager
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm',
'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeManager', 'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeManager',
'AmendThemeForm', 'MediaDockManager', 'ServiceItemEditForm'] 'MediaDockManager', 'ServiceItemEditForm']

View File

@ -81,6 +81,9 @@ class AdvancedTab(SettingsTab):
self.doubleClickLiveCheckBox = QtGui.QCheckBox(self.uiGroupBox) self.doubleClickLiveCheckBox = QtGui.QCheckBox(self.uiGroupBox)
self.doubleClickLiveCheckBox.setObjectName(u'doubleClickLiveCheckBox') self.doubleClickLiveCheckBox.setObjectName(u'doubleClickLiveCheckBox')
self.uiLayout.addWidget(self.doubleClickLiveCheckBox) self.uiLayout.addWidget(self.doubleClickLiveCheckBox)
self.expandServiceItemCheckBox = QtGui.QCheckBox(self.uiGroupBox)
self.expandServiceItemCheckBox.setObjectName(u'expandServiceItemCheckBox')
self.uiLayout.addWidget(self.expandServiceItemCheckBox)
self.leftLayout.addWidget(self.uiGroupBox) self.leftLayout.addWidget(self.uiGroupBox)
self.expandServiceItemCheckBox = QtGui.QCheckBox(self.uiGroupBox) self.expandServiceItemCheckBox = QtGui.QCheckBox(self.uiGroupBox)
self.expandServiceItemCheckBox.setObjectName( self.expandServiceItemCheckBox.setObjectName(

View File

@ -90,6 +90,16 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtCore.QObject.connect(self.fontMainSizeSpinBox, QtCore.QObject.connect(self.fontMainSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'), QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainSizeSpinBoxChanged) self.onFontMainSizeSpinBoxChanged)
QtCore.QObject.connect(self.fontMainLineAdjustmentSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainLineAdjustmentSpinBoxChanged)
QtCore.QObject.connect(self.shadowSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onShadowSpinBoxChanged)
QtCore.QObject.connect(self.outlineSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onOutlineSpinBoxChanged)
QtCore.QObject.connect(self.fontFooterSizeSpinBox, QtCore.QObject.connect(self.fontFooterSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'), QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterSizeSpinBoxChanged) self.onFontFooterSizeSpinBoxChanged)
@ -118,12 +128,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtCore.QObject.connect(self.fontFooterHeightSpinBox, QtCore.QObject.connect(self.fontFooterHeightSpinBox,
QtCore.SIGNAL(u'editingFinished()'), QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterHeightSpinBoxChanged) self.onFontFooterHeightSpinBoxChanged)
QtCore.QObject.connect(self.shadowSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onShadowSpinBoxChanged)
QtCore.QObject.connect(self.outlineSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onOutlineSpinBoxChanged)
# CheckBoxes # CheckBoxes
QtCore.QObject.connect(self.fontMainDefaultCheckBox, QtCore.QObject.connect(self.fontMainDefaultCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), QtCore.SIGNAL(u'stateChanged(int)'),
@ -525,7 +530,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else: else:
self.gradientComboBox.setCurrentIndex(2) self.gradientComboBox.setCurrentIndex(2)
# Font Main Tab # Font Main Tab
self.fontMainComboBox.setCurrentFont( self.mainFontComboBox.setCurrentFont(
QtGui.QFont(self.theme.font_main_name)) QtGui.QFont(self.theme.font_main_name))
self.fontMainSizeSpinBox.setValue(self.theme.font_main_proportion) self.fontMainSizeSpinBox.setValue(self.theme.font_main_proportion)
if not self.theme.font_main_italics and \ if not self.theme.font_main_italics and \

View File

@ -855,7 +855,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.plugin_manager.finalise_plugins() self.plugin_manager.finalise_plugins()
# Save settings # Save settings
self.saveSettings() self.saveSettings()
#Close down the display # Close down the display
self.LiveController.display.close() self.LiveController.display.close()
def serviceChanged(self, reset=False, serviceName=None): def serviceChanged(self, reset=False, serviceName=None):

View File

@ -116,6 +116,7 @@ class ServiceManager(QtGui.QWidget):
self.layout = QtGui.QVBoxLayout(self) self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0) self.layout.setSpacing(0)
self.layout.setMargin(0) self.layout.setMargin(0)
self.expandTabs = False
# Create the top toolbar # Create the top toolbar
self.toolbar = OpenLPToolbar(self) self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
@ -890,8 +891,8 @@ class ServiceManager(QtGui.QWidget):
``expand`` ``expand``
Override the default expand settings. (Tristate) Override the default expand settings. (Tristate)
""" """
log.debug(u'addServiceItem') # if not passed set to config value
if expand == None: if expand is None:
expand = self.expandTabs expand = self.expandTabs
sitem = self.findServiceItem()[0] sitem = self.findServiceItem()[0]
item.render() item.render()

591
openlp/core/ui/themeform.py Normal file
View File

@ -0,0 +1,591 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import logging
import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, BackgroundType, BackgroundGradientType
from openlp.core.utils import get_images_filter
from themewizard import Ui_ThemeWizard
log = logging.getLogger(__name__)
class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
"""
This is the Bible Import Wizard, which allows easy importing of Bibles
into OpenLP from other formats like OSIS, CSV and OpenSong.
"""
log.info(u'ThemeWizardForm loaded')
def __init__(self, parent):
"""
Instantiate the wizard, and run any extra setup we need to.
``parent``
The QWidget-derived parent of the wizard.
"""
QtGui.QWizard.__init__(self, parent)
self.thememanager = parent
self.setupUi(self)
self.registerFields()
self.accepted = False
QtCore.QObject.connect(self.backgroundTypeComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onBackgroundComboBox)
QtCore.QObject.connect(self.gradientComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onGradientComboBox)
QtCore.QObject.connect(self.color1PushButton,
QtCore.SIGNAL(u'pressed()'),
self.onColor1PushButtonClicked)
QtCore.QObject.connect(self.color2PushButton,
QtCore.SIGNAL(u'pressed()'),
self.onColor2PushButtonClicked)
QtCore.QObject.connect(self.imageBrowseButton,
QtCore.SIGNAL(u'pressed()'),
self.onImageBrowseButtonClicked)
QtCore.QObject.connect(self.mainColorPushButton,
QtCore.SIGNAL(u'pressed()'),
self.onMainColourPushButtonClicked)
QtCore.QObject.connect(self.outlineColorPushButton,
QtCore.SIGNAL(u'pressed()'),
self.onOutlineColourPushButtonClicked)
QtCore.QObject.connect(self.shadowColorPushButton,
QtCore.SIGNAL(u'pressed()'),
self.onShadowColourPushButtonClicked)
QtCore.QObject.connect(self.outlineCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onOutlineCheckCheckBoxChanged)
QtCore.QObject.connect(self.shadowCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onShadowCheckCheckBoxChanged)
QtCore.QObject.connect(self.footerColorPushButton,
QtCore.SIGNAL(u'pressed()'),
self.onFooterColourPushButtonClicked)
QtCore.QObject.connect(self.mainDefaultPositionCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onMainDefaultPositionCheckBox)
QtCore.QObject.connect(self.footerDefaultPositionCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onFooterDefaultPositionCheckBox)
QtCore.QObject.connect(self,
QtCore.SIGNAL(u'currentIdChanged(int)'),
self.pageChanged)
def pageChanged(self, pageId):
"""
Detects Page changes and updates.
"""
if pageId == 6:
self.updateTheme()
frame = self.thememanager.generateImage(self.theme)
self.previewBoxLabel.setPixmap(QtGui.QPixmap.fromImage(frame))
def setDefaults(self):
"""
Set up display at start of theme edit.
"""
self.restart()
self.accepted = False
self.setBackgroundTabValues()
self.setMainAreaTabValues()
self.setFooterAreaTabValues()
self.setAlignmentTabValues()
self.setPositionTabValues()
self.setPreviewTabValues()
def registerFields(self):
"""
Map field names to screen names,
"""
self.backgroundPage.registerField(
u'background_type', self.backgroundTypeComboBox)
self.backgroundPage.registerField(
u'color_1', self.color1PushButton)
self.backgroundPage.registerField(
u'color_2', self.color2PushButton)
self.backgroundPage.registerField(
u'background_image', self.imageLineEdit)
self.backgroundPage.registerField(
u'gradient', self.gradientComboBox)
self.mainAreaPage.registerField(
u'mainFontComboBox', self.mainFontComboBox)
self.mainAreaPage.registerField(
u'mainColorPushButton', self.mainColorPushButton)
self.mainAreaPage.registerField(
u'mainSizeSpinBox', self.mainSizeSpinBox)
self.mainAreaPage.registerField(
u'lineSpacingSpinBox', self.lineSpacingSpinBox)
self.mainAreaPage.registerField(
u'outlineCheckBox', self.outlineCheckBox)
self.mainAreaPage.registerField(
u'outlineColorPushButton', self.outlineColorPushButton)
self.mainAreaPage.registerField(
u'outlineSizeSpinBox', self.outlineSizeSpinBox)
self.mainAreaPage.registerField(
u'shadowCheckBox', self.shadowCheckBox)
self.mainAreaPage.registerField(
u'boldCheckBox', self.boldCheckBox)
self.mainAreaPage.registerField(
u'italicsCheckBox', self.italicsCheckBox)
self.mainAreaPage.registerField(
u'shadowColorPushButton', self.shadowColorPushButton)
self.mainAreaPage.registerField(
u'shadowSizeSpinBox', self.shadowSizeSpinBox)
self.mainAreaPage.registerField(
u'footerSizeSpinBox', self.footerSizeSpinBox)
self.areaPositionPage.registerField(
u'mainPositionX', self.mainXSpinBox)
self.areaPositionPage.registerField(
u'mainPositionY', self.mainYSpinBox)
self.areaPositionPage.registerField(
u'mainPositionWidth', self.mainWidthSpinBox)
self.areaPositionPage.registerField(
u'mainPositionHeight', self.mainHeightSpinBox)
self.areaPositionPage.registerField(
u'footerPositionX', self.footerXSpinBox)
self.areaPositionPage.registerField(
u'footerPositionY', self.footerYSpinBox)
self.areaPositionPage.registerField(
u'footerPositionWidth', self.footerWidthSpinBox)
self.areaPositionPage.registerField(
u'footerPositionHeight', self.footerHeightSpinBox)
self.backgroundPage.registerField(
u'horizontal', self.horizontalComboBox)
self.backgroundPage.registerField(
u'vertical', self.verticalComboBox)
self.backgroundPage.registerField(
u'slideTransition', self.transitionsCheckBox)
self.backgroundPage.registerField(
u'name', self.themeNameEdit)
def onOutlineCheckCheckBoxChanged(self, state):
"""
Change state as Outline check box changed
"""
if state == QtCore.Qt.Checked:
self.theme.font_main_outline = True
else:
self.theme.font_main_outline = False
self.outlineColorPushButton.setEnabled(self.theme.font_main_outline)
self.outlineSizeSpinBox.setEnabled(self.theme.font_main_outline)
def onShadowCheckCheckBoxChanged(self, state):
"""
Change state as Shadow check box changed
"""
if state == QtCore.Qt.Checked:
self.theme.font_main_shadow = True
else:
self.theme.font_main_shadow = False
self.shadowColorPushButton.setEnabled(self.theme.font_main_shadow)
self.shadowSizeSpinBox.setEnabled(self.theme.font_main_shadow)
def onMainDefaultPositionCheckBox(self, value):
"""
Change state as Main Area Position check box changed
"""
if value == QtCore.Qt.Checked:
self.theme.font_main_override = False
else:
self.theme.font_main_override = True
self.mainXSpinBox.setEnabled(self.theme.font_main_override)
self.mainYSpinBox.setEnabled(self.theme.font_main_override)
self.mainHeightSpinBox.setEnabled(self.theme.font_main_override)
self.mainWidthSpinBox.setEnabled(self.theme.font_main_override)
def onFooterDefaultPositionCheckBox(self, value):
"""
Change state as Footer Area Position check box changed
"""
if value == QtCore.Qt.Checked:
self.theme.font_footer_override = False
else:
self.theme.font_footer_override = True
self.footerXSpinBox.setEnabled(self.theme.font_footer_override)
self.footerYSpinBox.setEnabled(self.theme.font_footer_override)
self.footerHeightSpinBox.setEnabled(self.theme.font_footer_override)
self.footerWidthSpinBox.setEnabled(self.theme.font_footer_override)
def exec_(self):
"""
Run the wizard.
"""
self.setDefaults()
return QtGui.QWizard.exec_(self)
def initializePage(self, id):
"""
Set up the pages for Initial run through dialog
"""
log.debug(u'initializePage %s' % id)
if id == 1:
self.setBackgroundTabValues()
elif id == 2:
self.setMainAreaTabValues()
elif id == 3:
self.setFooterAreaTabValues()
elif id == 4:
self.setAlignmentTabValues()
elif id == 5:
self.setPositionTabValues()
def setBackgroundTabValues(self):
"""
Handle the display and State of the background display tab.
"""
if self.theme.background_type == \
BackgroundType.to_string(BackgroundType.Solid):
self.setField(u'background_type', QtCore.QVariant(0))
self.color1PushButton.setVisible(True)
self.color1Label.setVisible(True)
self.color1PushButton.setStyleSheet(u'background-color: %s' %
self.theme.background_color)
self.color1Label.setText(
translate('OpenLP.ThemeForm', 'Color:'))
self.color2PushButton.setVisible(False)
self.color2Label.setVisible(False)
self.gradientLabel.setVisible(False)
self.gradientComboBox.setVisible(False)
self.imageLabel.setVisible(False)
self.imageLineEdit.setVisible(False)
self.imageBrowseButton.setVisible(False)
self.imageLineEdit.setText(u'')
elif self.theme.background_type == \
BackgroundType.to_string(BackgroundType.Gradient):
self.setField(u'background_type', QtCore.QVariant(1))
self.color1PushButton.setVisible(True)
self.color1Label.setVisible(True)
self.color1PushButton.setStyleSheet(u'background-color: %s' %
self.theme.background_start_color)
self.color1Label.setText(
translate('OpenLP.ThemeForm', 'First color:'))
self.color2PushButton.setVisible(True)
self.color2Label.setVisible(True)
self.color2PushButton.setStyleSheet(u'background-color: %s' %
self.theme.background_end_color)
self.color2Label.setText(
translate('OpenLP.ThemeForm', 'Second color:'))
self.gradientLabel.setVisible(True)
self.gradientComboBox.setVisible(True)
self.imageLabel.setVisible(False)
self.imageLineEdit.setVisible(False)
self.imageBrowseButton.setVisible(False)
self.imageLineEdit.setText(u'')
else:
self.setField(u'background_type', QtCore.QVariant(2))
self.color1PushButton.setVisible(False)
self.color1Label.setVisible(False)
self.color2PushButton.setVisible(False)
self.color2Label.setVisible(False)
self.gradientLabel.setVisible(False)
self.gradientComboBox.setVisible(False)
self.imageLineEdit.setVisible(True)
self.imageLabel.setVisible(True)
self.imageBrowseButton.setVisible(True)
self.imageLineEdit.setText(self.theme.background_filename)
if self.theme.background_direction == \
BackgroundGradientType.to_string(BackgroundGradientType.Horizontal):
self.setField(u'gradient', QtCore.QVariant(0))
elif self.theme.background_direction == \
BackgroundGradientType.to_string(BackgroundGradientType.Vertical):
self.setField(u'gradient', QtCore.QVariant(1))
elif self.theme.background_direction == \
BackgroundGradientType.to_string(BackgroundGradientType.Circular):
self.setField(u'gradient', QtCore.QVariant(2))
elif self.theme.background_direction == \
BackgroundGradientType.to_string(BackgroundGradientType.LeftTop):
self.setField(u'gradient', QtCore.QVariant(3))
else:
self.setField(u'gradient', QtCore.QVariant(4))
def setMainAreaTabValues(self):
"""
Handle the display and State of the Main Area tab.
"""
self.mainFontComboBox.setCurrentFont(
QtGui.QFont(self.theme.font_main_name))
self.mainColorPushButton.setStyleSheet(u'background-color: %s' %
self.theme.font_main_color)
self.setField(u'mainSizeSpinBox', \
QtCore.QVariant(self.theme.font_main_size))
self.setField(u'lineSpacingSpinBox', \
QtCore.QVariant(self.theme.font_main_line_adjustment))
self.setField(u'outlineCheckBox', \
QtCore.QVariant(self.theme.font_main_outline))
self.outlineColorPushButton.setStyleSheet(u'background-color: %s' %
self.theme.font_main_outline_color)
self.setField(u'outlineSizeSpinBox', \
QtCore.QVariant(self.theme.font_main_outline_size))
self.setField(u'shadowCheckBox', \
QtCore.QVariant(self.theme.font_main_shadow))
self.shadowColorPushButton.setStyleSheet(u'background-color: %s' %
self.theme.font_main_shadow_color)
self.setField(u'shadowSizeSpinBox', \
QtCore.QVariant(self.theme.font_main_shadow_size))
self.setField(u'boldCheckBox', \
QtCore.QVariant(self.theme.font_main_bold))
self.setField(u'italicsCheckBox', \
QtCore.QVariant(self.theme.font_main_italics))
# Set up field states
if self.theme.font_main_outline:
self.setField(u'outlineCheckBox', QtCore.QVariant(False))
else:
self.setField(u'outlineCheckBox', QtCore.QVariant(True))
self.outlineColorPushButton.setEnabled(self.theme.font_main_outline)
self.outlineSizeSpinBox.setEnabled(self.theme.font_main_outline)
if self.theme.font_main_shadow:
self.setField(u'shadowCheckBox', QtCore.QVariant(False))
else:
self.setField(u'shadowCheckBox', QtCore.QVariant(True))
self.shadowColorPushButton.setEnabled(self.theme.font_main_shadow)
self.shadowSizeSpinBox.setEnabled(self.theme.font_main_shadow)
def setFooterAreaTabValues(self):
"""
Handle the display and State of the Footer Area tab.
"""
self.footerFontComboBox.setCurrentFont(
QtGui.QFont(self.theme.font_main_name))
self.footerColorPushButton.setStyleSheet(u'background-color: %s' %
self.theme.font_footer_color)
self.setField(u'footerSizeSpinBox', \
QtCore.QVariant(self.theme.font_footer_size))
def setPositionTabValues(self):
"""
Handle the display and State of the Position tab.
"""
# Main Area
if self.theme.font_main_override:
self.mainDefaultPositionCheckBox.setChecked(False)
else:
self.mainDefaultPositionCheckBox.setChecked(True)
self.setField(u'mainPositionX', \
QtCore.QVariant(self.theme.font_main_x))
self.setField(u'mainPositionY', \
QtCore.QVariant(self.theme.font_main_y))
self.setField(u'mainPositionHeight', \
QtCore.QVariant(self.theme.font_main_height))
self.setField(u'mainPositionWidth', \
QtCore.QVariant(self.theme.font_main_width))
# Footer
if self.theme.font_footer_override:
self.footerDefaultPositionCheckBox.setChecked(False)
else:
self.footerDefaultPositionCheckBox.setChecked(True)
self.setField(u'footerPositionX', \
QtCore.QVariant(self.theme.font_footer_x))
self.setField(u'footerPositionY', \
QtCore.QVariant(self.theme.font_footer_y))
self.setField(u'footerPositionHeight', \
QtCore.QVariant(self.theme.font_footer_height))
self.setField(u'footerPositionWidth', \
QtCore.QVariant(self.theme.font_footer_width))
def setAlignmentTabValues(self):
"""
Define the Tab Alignments Page
"""
self.setField(u'horizontal', \
QtCore.QVariant(self.theme.display_horizontal_align))
self.setField(u'vertical', \
QtCore.QVariant(self.theme.display_vertical_align))
self.setField(u'slideTransition', \
QtCore.QVariant(self.theme.display_slide_transition))
def setPreviewTabValues(self):
self.setField(u'name', QtCore.QVariant(self.theme.theme_name))
if len(self.theme.theme_name) > 1:
self.themeNameEdit.setEnabled(False)
else:
self.themeNameEdit.setEnabled(True)
def onBackgroundComboBox(self, index):
"""
Background style Combo box has changed.
"""
self.theme.background_type = BackgroundType.to_string(index)
self.setBackgroundTabValues()
def onGradientComboBox(self, index):
"""
Background gradient Combo box has changed.
"""
self.theme.background_direction = \
BackgroundGradientType.to_string(index)
self.setBackgroundTabValues()
def onColor1PushButtonClicked(self):
"""
Background / Gradient 1 Color button pushed.
"""
if self.theme.background_type == \
BackgroundType.to_string(BackgroundType.Solid):
self.theme.background_color = \
self._colorButton(self.theme.background_color)
else:
self.theme.background_start_color = \
self._colorButton(self.theme.background_start_color)
self.setBackgroundTabValues()
def onColor2PushButtonClicked(self):
"""
Gradient 2 Color button pushed.
"""
self.theme.background_end_color = \
self._colorButton(self.theme.background_end_color)
self.setBackgroundTabValues()
def onImageBrowseButtonClicked(self):
"""
Background Image button pushed.
"""
images_filter = get_images_filter()
images_filter = '%s;;%s (*.*) (*)' % (images_filter,
translate('OpenLP.ThemeForm', 'All Files'))
filename = QtGui.QFileDialog.getOpenFileName(self,
translate('OpenLP.ThemeForm', 'Select Image'), u'',
images_filter)
if filename:
self.theme.background_filename = unicode(filename)
self.setBackgroundTabValues()
def onMainFontComboBox(self):
"""
Main Font Combo box changed
"""
self.theme.font_main_name = self.mainFontComboBox.currentFont().family()
def onMainColourPushButtonClicked(self):
self.theme.font_main_color = \
self._colorButton(self.theme.font_main_color)
self.setMainAreaTabValues()
def onOutlineColourPushButtonClicked(self):
self.theme.font_main_outline_color = \
self._colorButton(self.theme.font_main_outline_color)
self.setMainAreaTabValues()
def onShadowColourPushButtonClicked(self):
self.theme.font_main_shadow_color = \
self._colorButton(self.theme.font_main_shadow_color)
self.setMainAreaTabValues()
def onFooterColourPushButtonClicked(self):
self.theme.font_footer_color = \
self._colorButton(self.theme.font_footer_color)
self.setFooterAreaTabValues()
def updateTheme(self):
"""
Update the theme object from the UI for fields not already updated
when the are changed.
"""
log.debug(u'updateTheme')
# main page
self.theme.font_main_name = \
unicode(self.mainFontComboBox.currentFont().family())
self.theme.font_main_size = \
self.field(u'mainSizeSpinBox').toInt()[0]
self.theme.font_main_line_adjustment = \
self.field(u'lineSpacingSpinBox').toInt()[0]
self.theme.font_main_outline_size = \
self.field(u'outlineSizeSpinBox').toInt()[0]
self.theme.font_main_shadow_size = \
self.field(u'shadowSizeSpinBox').toInt()[0]
self.theme.font_main_bold = \
self.field(u'boldCheckBox').toBool()
self.theme.font_main_italics = \
self.field(u'italicsCheckBox').toBool()
# footer page
self.theme.font_footer_name = \
unicode(self.footerFontComboBox.currentFont().family())
self.theme.font_footer_size = \
self.field(u'footerSizeSpinBox').toInt()[0]
# position page
self.theme.font_main_x = self.field(u'mainPositionX').toInt()[0]
self.theme.font_main_y = self.field(u'mainPositionY').toInt()[0]
self.theme.font_main_height = \
self.field(u'mainPositionHeight').toInt()[0]
self.theme.font_main_width = self.field(u'mainPositionWidth').toInt()[0]
self.theme.font_footer_x = self.field(u'footerPositionX').toInt()[0]
self.theme.font_footer_y = self.field(u'footerPositionY').toInt()[0]
self.theme.font_footer_height = \
self.field(u'footerPositionHeight').toInt()[0]
self.theme.font_footer_width = \
self.field(u'footerPositionWidth').toInt()[0]
# position page
self.theme.display_horizontal_align = \
self.horizontalComboBox.currentIndex()
self.theme.display_vertical_align = \
self.verticalComboBox.currentIndex()
self.theme.display_slide_transition = \
self.field(u'slideTransition').toBool()
def accept(self):
"""
Lets save the them as Finish has been pressed
"""
# Some reason getting double submission.
# Hack to stop it for now.
if self.accepted:
return
self.accepted = True
# Save the theme name
self.theme.theme_name = \
unicode(self.field(u'name').toString())
if not self.theme.theme_name:
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeForm', 'Theme Name Missing'),
translate('OpenLP.ThemeForm',
'There is no name for this theme. '
'Please enter one.'),
(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
return
save_from = None
save_to = None
if self.theme.background_type == \
BackgroundType.to_string(BackgroundType.Image):
filename = \
os.path.split(unicode(self.theme.background_filename))[1]
save_to = os.path.join(self.path, self.theme.theme_name, filename)
save_from = self.theme.background_filename
if self.thememanager.saveTheme(self.theme, save_from, save_to):
return QtGui.QDialog.accept(self)
def _colorButton(self, field):
"""
Handle Color buttons
"""
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(field), self)
if new_color.isValid():
field = new_color.name()
return field

View File

@ -32,10 +32,11 @@ import logging
from xml.etree.ElementTree import ElementTree, XML from xml.etree.ElementTree import ElementTree, XML
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.ui import AmendThemeForm, FileRenameForm from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.theme import Theme from openlp.core.theme import Theme
from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \ from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \
build_icon, Receiver, SettingsManager, translate, check_item_selected build_icon, Receiver, SettingsManager, translate, check_item_selected, \
BackgroundType, BackgroundGradientType
from openlp.core.utils import AppLocation, get_filesystem_encoding from openlp.core.utils import AppLocation, get_filesystem_encoding
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -52,7 +53,7 @@ class ThemeManager(QtGui.QWidget):
self.layout = QtGui.QVBoxLayout(self) self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0) self.layout.setSpacing(0)
self.layout.setMargin(0) self.layout.setMargin(0)
self.amendThemeForm = AmendThemeForm(self) self.themeForm = ThemeForm(self)
self.fileRenameForm = FileRenameForm(self) self.fileRenameForm = FileRenameForm(self)
self.toolbar = OpenLPToolbar(self) self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
@ -125,7 +126,7 @@ class ThemeManager(QtGui.QWidget):
self.checkThemesExists(self.path) self.checkThemesExists(self.path)
self.thumbPath = os.path.join(self.path, u'thumbnails') self.thumbPath = os.path.join(self.path, u'thumbnails')
self.checkThemesExists(self.thumbPath) self.checkThemesExists(self.thumbPath)
self.amendThemeForm.path = self.path self.themeForm.path = self.path
self.oldBackgroundImage = None self.oldBackgroundImage = None
self.editingDefault = False self.editingDefault = False
# Last little bits of setting up # Last little bits of setting up
@ -213,10 +214,10 @@ class ThemeManager(QtGui.QWidget):
Loads a new theme with the default settings and then launches the theme Loads a new theme with the default settings and then launches the theme
editing form for the user to make their customisations. editing form for the user to make their customisations.
""" """
theme = self.createThemeFromXml(self.baseTheme(), self.path) theme = ThemeXML()
self.amendThemeForm.loadTheme(theme)
self.saveThemeName = u'' self.saveThemeName = u''
self.amendThemeForm.exec_() self.themeForm.theme = theme
self.themeForm.exec_()
def onRenameTheme(self): def onRenameTheme(self):
""" """
@ -242,66 +243,25 @@ class ThemeManager(QtGui.QWidget):
self.saveThemeName = u'' self.saveThemeName = u''
if self.fileRenameForm.exec_(): if self.fileRenameForm.exec_():
newThemeName = unicode(self.fileRenameForm.FileNameEdit.text()) newThemeName = unicode(self.fileRenameForm.FileNameEdit.text())
oldThemeData = self.getThemeData(oldThemeName) themeData = self.getThemeData(oldThemeName)
self.cloneThemeData(oldThemeData, newThemeName) self.cloneThemeData(themeData, newThemeName)
self.loadThemes() self.loadThemes()
def cloneThemeData(self, oldThemeData, newThemeName): def cloneThemeData(self, themeData, newThemeName):
""" """
Takes a theme and makes a new copy of it as well as saving it.
""" """
log.debug(u'cloneThemeData') log.debug(u'cloneThemeData')
new_theme = ThemeXML() themeData.new_document(newThemeName)
new_theme.new_document(newThemeName) themeData.build_xml_from_attrs()
save_from = None
save_to = None save_to = None
if oldThemeData.background_type == u'solid': save_from = None
new_theme.add_background_solid( if themeData.background_type == u'image':
unicode(oldThemeData.background_color)) save_to = os.path.join(self.path, newThemeName,
elif oldThemeData.background_type == u'gradient': os.path.split(unicode(themeData.background_filename))[1])
new_theme.add_background_gradient( save_from = themeData.background_filename
unicode(oldThemeData.background_start_color), theme = themeData.extract_xml()
unicode(oldThemeData.background_end_color), pretty_theme = themeData.extract_formatted_xml()
oldThemeData.background_direction)
else:
filename = \
os.path.split(unicode(oldThemeData.background_filename))[1]
new_theme.add_background_image(filename)
save_to = os.path.join(self.path, newThemeName, filename)
save_from = oldThemeData.background_filename
new_theme.add_font(unicode(oldThemeData.font_main_name),
unicode(oldThemeData.font_main_color),
unicode(oldThemeData.font_main_proportion),
unicode(oldThemeData.font_main_override), u'main',
unicode(oldThemeData.font_main_weight),
unicode(oldThemeData.font_main_italics),
unicode(oldThemeData.font_main_line_adjustment),
unicode(oldThemeData.font_main_x),
unicode(oldThemeData.font_main_y),
unicode(oldThemeData.font_main_width),
unicode(oldThemeData.font_main_height))
new_theme.add_font(unicode(oldThemeData.font_footer_name),
unicode(oldThemeData.font_footer_color),
unicode(oldThemeData.font_footer_proportion),
unicode(oldThemeData.font_footer_override), u'footer',
unicode(oldThemeData.font_footer_weight),
unicode(oldThemeData.font_footer_italics),
0, # line adjustment
unicode(oldThemeData.font_footer_x),
unicode(oldThemeData.font_footer_y),
unicode(oldThemeData.font_footer_width),
unicode(oldThemeData.font_footer_height))
new_theme.add_display(unicode(oldThemeData.display_shadow),
unicode(oldThemeData.display_shadow_color),
unicode(oldThemeData.display_outline),
unicode(oldThemeData.display_outline_color),
unicode(oldThemeData.display_horizontal_align),
unicode(oldThemeData.display_vertical_align),
unicode(oldThemeData.display_wrap_style),
unicode(oldThemeData.display_slide_transition),
unicode(oldThemeData.display_shadow_size),
unicode(oldThemeData.display_outline_size))
theme = new_theme.extract_xml()
pretty_theme = new_theme.extract_formatted_xml()
self.saveTheme(newThemeName, theme, pretty_theme, save_from, save_to) self.saveTheme(newThemeName, theme, pretty_theme, save_from, save_to)
def onEditTheme(self): def onEditTheme(self):
@ -320,10 +280,10 @@ class ThemeManager(QtGui.QWidget):
unicode(item.data(QtCore.Qt.UserRole).toString())) unicode(item.data(QtCore.Qt.UserRole).toString()))
if theme.background_type == u'image': if theme.background_type == u'image':
self.oldBackgroundImage = theme.background_filename self.oldBackgroundImage = theme.background_filename
self.amendThemeForm.loadTheme(theme)
self.saveThemeName = unicode( self.saveThemeName = unicode(
item.data(QtCore.Qt.UserRole).toString()) item.data(QtCore.Qt.UserRole).toString())
self.amendThemeForm.exec_() self.themeForm.theme = theme
self.themeForm.exec_()
def onDeleteTheme(self): def onDeleteTheme(self):
""" """
@ -340,7 +300,8 @@ class ThemeManager(QtGui.QWidget):
# confirm deletion # confirm deletion
answer = QtGui.QMessageBox.question(self, answer = QtGui.QMessageBox.question(self,
translate('OpenLP.ThemeManager', 'Delete Confirmation'), translate('OpenLP.ThemeManager', 'Delete Confirmation'),
translate('OpenLP.ThemeManager', 'Delete theme?'), unicode(translate('OpenLP.ThemeManager', 'Delete %s theme?'))
% theme,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No), QtGui.QMessageBox.No) QtGui.QMessageBox.No), QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No: if answer == QtGui.QMessageBox.No:
@ -513,8 +474,9 @@ class ThemeManager(QtGui.QWidget):
unicode(themename) + u'.xml') unicode(themename) + u'.xml')
xml = get_text_file_string(xml_file) xml = get_text_file_string(xml_file)
if not xml: if not xml:
xml = self.baseTheme() return self.baseTheme()
return self.createThemeFromXml(xml, self.path) else:
return self.createThemeFromXml(xml, self.path)
def checkThemesExists(self, dir): def checkThemesExists(self, dir):
""" """
@ -585,7 +547,8 @@ class ThemeManager(QtGui.QWidget):
outfile = open(fullpath, u'wb') outfile = open(fullpath, u'wb')
outfile.write(zip.read(file)) outfile.write(zip.read(file))
if filexml: if filexml:
self.generateAndSaveImage(dir, themename, filexml) theme = self.createThemeFromXml(filexml, self.path)
self.generateAndSaveImage(dir, themename, theme)
else: else:
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'), translate('OpenLP.ThemeManager', 'Error'),
@ -632,50 +595,59 @@ class ThemeManager(QtGui.QWidget):
""" """
theme = Theme(xml_data) theme = Theme(xml_data)
newtheme = ThemeXML() newtheme = ThemeXML()
newtheme.new_document(theme.Name) newtheme.theme_name = theme.Name
if theme.BackgroundType == 0: if theme.BackgroundType == 0:
newtheme.add_background_solid(unicode( newtheme.background_type = \
theme.BackgroundParameter1.name())) BackgroundType.to_string(BackgroundType.Solid)
newtheme.background_color = \
unicode(theme.BackgroundParameter1.name())
elif theme.BackgroundType == 1: elif theme.BackgroundType == 1:
direction = u'vertical' newtheme.background_type = \
BackgroundType.to_string(BackgroundType.Gradient)
newtheme.background_direction = \
BackgroundGradientType. \
to_string(BackgroundGradientType.Horizontal)
if theme.BackgroundParameter3.name() == 1: if theme.BackgroundParameter3.name() == 1:
direction = u'horizontal' newtheme.background_direction = \
newtheme.add_background_gradient( BackgroundGradientType. \
unicode(theme.BackgroundParameter1.name()), to_string(BackgroundGradientType.Horizontal)
unicode(theme.BackgroundParameter2.name()), direction) newtheme.background_start_color = \
unicode(theme.BackgroundParameter1.name())
newtheme.background_end_color = \
unicode(theme.BackgroundParameter2.name())
else: else:
newtheme.add_background_image(unicode(theme.BackgroundParameter1)) newtheme.background_type = \
newtheme.add_font(unicode(theme.FontName), BackgroundType.to_string(BackgroundType.Image)
unicode(theme.FontColor.name()), newtheme.background_filename = unicode(theme.BackgroundParameter1)
unicode(theme.FontProportion * 3), u'False') newtheme.font_main_name = theme.FontName
newtheme.add_font(unicode(theme.FontName), newtheme.font_main_color = unicode(theme.FontColor.name())
unicode(theme.FontColor.name()), newtheme.font_main_size = theme.FontProportion * 3
unicode(12), u'False', u'footer') newtheme.font_footer_name = theme.FontName
outline = False newtheme.font_footer_color = unicode(theme.FontColor.name())
shadow = False newtheme.font_main_shadow = False
if theme.Shadow == 1: if theme.Shadow == 1:
shadow = True newtheme.font_main_shadow = True
newtheme.font_main_shadow_color = unicode(theme.ShadowColor.name())
if theme.Outline == 1: if theme.Outline == 1:
outline = True newtheme.font_main_outline = True
newtheme.font_main_outline_color = unicode(theme.OutlineColor.name())
vAlignCorrection = 0 vAlignCorrection = 0
if theme.VerticalAlign == 2: if theme.VerticalAlign == 2:
vAlignCorrection = 1 vAlignCorrection = 1
elif theme.VerticalAlign == 1: elif theme.VerticalAlign == 1:
vAlignCorrection = 2 vAlignCorrection = 2
newtheme.add_display(unicode(shadow), newtheme.display_horizontal_align = theme.HorizontalAlign
unicode(theme.ShadowColor.name()), newtheme.display_vertical_align = vAlignCorrection
unicode(outline), unicode(theme.OutlineColor.name()),
unicode(theme.HorizontalAlign), unicode(vAlignCorrection),
unicode(theme.WrapStyle), unicode(0))
return newtheme.extract_xml() return newtheme.extract_xml()
def saveTheme(self, name, theme_xml, theme_pretty_xml, image_from, def saveTheme(self, theme, image_from, image_to):
image_to):
""" """
Called by thememaintenance Dialog to save the theme Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list and to trigger the reload of the theme list
""" """
log.debug(u'saveTheme %s %s', name, theme_xml) name = theme.theme_name
theme_pretty_xml = theme.extract_formatted_xml()
log.debug(u'saveTheme %s %s', name, theme_pretty_xml)
theme_dir = os.path.join(self.path, name) theme_dir = os.path.join(self.path, name)
if not os.path.exists(theme_dir): if not os.path.exists(theme_dir):
os.mkdir(os.path.join(self.path, name)) os.mkdir(os.path.join(self.path, name))
@ -724,7 +696,7 @@ class ThemeManager(QtGui.QWidget):
unicode(image_to).encode(encoding)) unicode(image_to).encode(encoding))
except IOError: except IOError:
log.exception(u'Failed to save theme image') log.exception(u'Failed to save theme image')
self.generateAndSaveImage(self.path, name, theme_xml) self.generateAndSaveImage(self.path, name, theme)
self.loadThemes() self.loadThemes()
# Check if we need to set a new service theme # Check if we need to set a new service theme
if editedServiceTheme: if editedServiceTheme:
@ -749,14 +721,16 @@ class ThemeManager(QtGui.QWidget):
self.global_theme) self.global_theme)
self.editingDefault = False self.editingDefault = False
self.pushThemes() self.pushThemes()
return True
else: else:
# Don't close the dialog - allow the user to change the name of # Don't close the dialog - allow the user to change the name of
# the theme or to cancel the theme dialog completely. # the theme or to cancel the theme dialog completely.
return False return False
def generateAndSaveImage(self, dir, name, theme_xml): def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s %s', dir, name, theme_xml) log.debug(u'generateAndSaveImage %s %s', dir, name)
theme = self.createThemeFromXml(theme_xml, dir) #theme = self.createThemeFromXml(theme_xml, dir)
theme_xml = theme.extract_xml()
frame = self.generateImage(theme) frame = self.generateImage(theme)
samplepathname = os.path.join(self.path, name + u'.png') samplepathname = os.path.join(self.path, name + u'.png')
if os.path.exists(samplepathname): if os.path.exists(samplepathname):
@ -792,15 +766,6 @@ class ThemeManager(QtGui.QWidget):
""" """
log.debug(u'base theme created') log.debug(u'base theme created')
newtheme = ThemeXML() newtheme = ThemeXML()
newtheme.new_document(
unicode(translate('OpenLP.ThemeManager', 'New Theme')))
newtheme.add_background_solid(u'#000000')
newtheme.add_font(unicode(QtGui.QFont().family()), u'#FFFFFF',
u'30', u'False')
newtheme.add_font(unicode(QtGui.QFont().family()), u'#FFFFFF',
u'12', u'False', u'footer')
newtheme.add_display(u'False', u'#FFFFFF', u'False',
unicode(u'#FFFFFF'), u'0', u'0', u'0', u'False')
return newtheme.extract_xml() return newtheme.extract_xml()
def createThemeFromXml(self, theme_xml, path): def createThemeFromXml(self, theme_xml, path):

View File

@ -0,0 +1,547 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# 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 PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, build_icon
class Ui_ThemeWizard(object):
def setupUi(self, ThemeWizard):
ThemeWizard.setObjectName(u'ThemeWizard')
ThemeWizard.resize(550, 386)
ThemeWizard.setModal(True)
ThemeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
ThemeWizard.setOptions(QtGui.QWizard.IndependentPages|QtGui.QWizard.NoBackButtonOnStartPage)
self.welcomePage = QtGui.QWizardPage()
self.welcomePage.setTitle(u'')
self.welcomePage.setSubTitle(u'')
self.welcomePage.setObjectName(u'welcomePage')
self.welcomeLayout = QtGui.QHBoxLayout(self.welcomePage)
self.welcomeLayout.setSpacing(8)
self.welcomeLayout.setMargin(0)
self.welcomeLayout.setObjectName(u'welcomeLayout')
self.importBibleImage = QtGui.QLabel(self.welcomePage)
self.importBibleImage.setMinimumSize(QtCore.QSize(163, 0))
self.importBibleImage.setMaximumSize(QtCore.QSize(163, 16777215))
self.importBibleImage.setLineWidth(0)
self.importBibleImage.setText(u'')
self.importBibleImage.setPixmap(QtGui.QPixmap(u':/wizards/wizard_importbible.bmp'))
self.importBibleImage.setIndent(0)
self.importBibleImage.setObjectName(u'importBibleImage')
self.welcomeLayout.addWidget(self.importBibleImage)
self.welcomePageLayout = QtGui.QVBoxLayout()
self.welcomePageLayout.setSpacing(8)
self.welcomePageLayout.setObjectName(u'welcomePageLayout')
self.titleLabel = QtGui.QLabel(self.welcomePage)
self.titleLabel.setObjectName(u'titleLabel')
self.welcomePageLayout.addWidget(self.titleLabel)
spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
self.welcomePageLayout.addItem(spacerItem)
self.informationLabel = QtGui.QLabel(self.welcomePage)
self.informationLabel.setWordWrap(True)
self.informationLabel.setMargin(10)
self.informationLabel.setObjectName(u'informationLabel')
self.welcomePageLayout.addWidget(self.informationLabel)
spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.welcomePageLayout.addItem(spacerItem1)
self.welcomeLayout.addLayout(self.welcomePageLayout)
ThemeWizard.addPage(self.welcomePage)
self.backgroundPage = QtGui.QWizardPage()
self.backgroundPage.setObjectName(u'backgroundPage')
self.backgroundLayout = QtGui.QFormLayout(self.backgroundPage)
self.backgroundLayout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow)
self.backgroundLayout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.backgroundLayout.setMargin(20)
self.backgroundLayout.setSpacing(8)
self.backgroundLayout.setObjectName(u'backgroundLayout')
self.backgroundTypeLabel = QtGui.QLabel(self.backgroundPage)
self.backgroundTypeLabel.setObjectName(u'backgroundTypeLabel')
self.backgroundLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.backgroundTypeLabel)
self.backgroundTypeComboBox = QtGui.QComboBox(self.backgroundPage)
self.backgroundTypeComboBox.setObjectName(u'backgroundTypeComboBox')
self.backgroundTypeComboBox.addItem(u'')
self.backgroundTypeComboBox.addItem(u'')
self.backgroundTypeComboBox.addItem(u'')
self.backgroundLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.backgroundTypeComboBox)
self.color1Label = QtGui.QLabel(self.backgroundPage)
self.color1Label.setObjectName(u'color1Label')
self.backgroundLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.color1Label)
self.color1PushButton = QtGui.QPushButton(self.backgroundPage)
self.color1PushButton.setText(u'')
self.color1PushButton.setObjectName(u'color1PushButton')
self.backgroundLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.color1PushButton)
self.color2Label = QtGui.QLabel(self.backgroundPage)
self.color2Label.setObjectName(u'color2Label')
self.backgroundLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.color2Label)
self.color2PushButton = QtGui.QPushButton(self.backgroundPage)
self.color2PushButton.setText(u'')
self.color2PushButton.setObjectName(u'color2PushButton')
self.backgroundLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.color2PushButton)
self.imageLabel = QtGui.QLabel(self.backgroundPage)
self.imageLabel.setObjectName(u'imageLabel')
self.backgroundLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.imageLabel)
self.imageLayout = QtGui.QHBoxLayout()
self.imageLayout.setSpacing(8)
self.imageLayout.setObjectName(u'imageLayout')
self.imageLineEdit = QtGui.QLineEdit(self.backgroundPage)
self.imageLineEdit.setObjectName(u'imageLineEdit')
self.imageLayout.addWidget(self.imageLineEdit)
self.imageBrowseButton = QtGui.QToolButton(self.backgroundPage)
self.imageBrowseButton.setText(u'')
self.imageBrowseButton.setIcon(build_icon(u':/general/general_open.png'))
self.imageBrowseButton.setObjectName(u'imageBrowseButton')
self.imageLayout.addWidget(self.imageBrowseButton)
self.backgroundLayout.setLayout(3, QtGui.QFormLayout.FieldRole, self.imageLayout)
self.gradientLabel = QtGui.QLabel(self.backgroundPage)
self.gradientLabel.setObjectName(u'gradientLabel')
self.backgroundLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.gradientLabel)
self.gradientComboBox = QtGui.QComboBox(self.backgroundPage)
self.gradientComboBox.setObjectName(u'gradientComboBox')
self.gradientComboBox.addItem(u'')
self.gradientComboBox.addItem(u'')
self.gradientComboBox.addItem(u'')
self.gradientComboBox.addItem(u'')
self.gradientComboBox.addItem(u'')
self.backgroundLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.gradientComboBox)
ThemeWizard.addPage(self.backgroundPage)
self.mainAreaPage = QtGui.QWizardPage()
self.mainAreaPage.setObjectName(u'mainAreaPage')
self.formLayout = QtGui.QFormLayout(self.mainAreaPage)
self.formLayout.setFormAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.formLayout.setContentsMargins(-1, 20, 20, 20)
self.formLayout.setSpacing(8)
self.formLayout.setObjectName(u'formLayout')
self.mainFontLabel = QtGui.QLabel(self.mainAreaPage)
self.mainFontLabel.setObjectName(u'mainFontLabel')
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.mainFontLabel)
self.mainFontComboBox = QtGui.QFontComboBox(self.mainAreaPage)
self.mainFontComboBox.setObjectName(u'mainFontComboBox')
self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.mainFontComboBox)
self.mainColorLabel = QtGui.QLabel(self.mainAreaPage)
self.mainColorLabel.setObjectName(u'mainColorLabel')
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.mainColorLabel)
self.mainColorPushButton = QtGui.QPushButton(self.mainAreaPage)
self.mainColorPushButton.setText(u'')
self.mainColorPushButton.setObjectName(u'mainColorPushButton')
self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.mainColorPushButton)
self.mainSizeLabel = QtGui.QLabel(self.mainAreaPage)
self.mainSizeLabel.setObjectName(u'mainSizeLabel')
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.mainSizeLabel)
self.mainSizeLayout = QtGui.QHBoxLayout()
self.mainSizeLayout.setSpacing(8)
self.mainSizeLayout.setMargin(0)
self.mainSizeLayout.setObjectName(u'mainSizeLayout')
self.mainSizeSpinBox = QtGui.QSpinBox(self.mainAreaPage)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.mainSizeSpinBox.sizePolicy().hasHeightForWidth())
self.mainSizeSpinBox.setSizePolicy(sizePolicy)
self.mainSizeSpinBox.setMinimumSize(QtCore.QSize(70, 0))
self.mainSizeSpinBox.setMaximum(999)
self.mainSizeSpinBox.setProperty(u'value', 16)
self.mainSizeSpinBox.setObjectName(u'mainSizeSpinBox')
self.mainSizeLayout.addWidget(self.mainSizeSpinBox)
self.mainLineCountLabel = QtGui.QLabel(self.mainAreaPage)
self.mainLineCountLabel.setObjectName(u'mainLineCountLabel')
self.mainSizeLayout.addWidget(self.mainLineCountLabel)
self.formLayout.setLayout(2, QtGui.QFormLayout.FieldRole, self.mainSizeLayout)
self.lineSpacingLabel = QtGui.QLabel(self.mainAreaPage)
self.lineSpacingLabel.setObjectName(u'lineSpacingLabel')
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.lineSpacingLabel)
self.lineSpacingSpinBox = QtGui.QSpinBox(self.mainAreaPage)
self.lineSpacingSpinBox.setMinimum(-50)
self.lineSpacingSpinBox.setMaximum(50)
self.lineSpacingSpinBox.setObjectName(u'lineSpacingSpinBox')
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.lineSpacingSpinBox)
self.outlineCheckBox = QtGui.QCheckBox(self.mainAreaPage)
self.outlineCheckBox.setObjectName(u'outlineCheckBox')
self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.outlineCheckBox)
self.outlineLayout = QtGui.QHBoxLayout()
self.outlineLayout.setObjectName(u'outlineLayout')
self.outlineColorPushButton = QtGui.QPushButton(self.mainAreaPage)
self.outlineColorPushButton.setEnabled(True)
self.outlineColorPushButton.setText(u'')
self.outlineColorPushButton.setObjectName(u'outlineColorPushButton')
self.outlineLayout.addWidget(self.outlineColorPushButton)
self.outlineSizeLabel = QtGui.QLabel(self.mainAreaPage)
self.outlineSizeLabel.setObjectName(u'outlineSizeLabel')
self.outlineLayout.addWidget(self.outlineSizeLabel)
self.outlineSizeSpinBox = QtGui.QSpinBox(self.mainAreaPage)
self.outlineSizeSpinBox.setObjectName(u'outlineSizeSpinBox')
self.outlineLayout.addWidget(self.outlineSizeSpinBox)
self.formLayout.setLayout(4, QtGui.QFormLayout.FieldRole, self.outlineLayout)
self.shadowCheckBox = QtGui.QCheckBox(self.mainAreaPage)
self.shadowCheckBox.setObjectName(u'shadowCheckBox')
self.formLayout.setWidget(5, QtGui.QFormLayout.LabelRole, self.shadowCheckBox)
self.shadowLayout = QtGui.QHBoxLayout()
self.shadowLayout.setObjectName(u'shadowLayout')
self.shadowColorPushButton = QtGui.QPushButton(self.mainAreaPage)
self.shadowColorPushButton.setEnabled(True)
self.shadowColorPushButton.setText(u'')
self.shadowColorPushButton.setObjectName(u'shadowColorPushButton')
self.shadowLayout.addWidget(self.shadowColorPushButton)
self.shadowSizeLabel = QtGui.QLabel(self.mainAreaPage)
self.shadowSizeLabel.setObjectName(u'shadowSizeLabel')
self.shadowLayout.addWidget(self.shadowSizeLabel)
self.shadowSizeSpinBox = QtGui.QSpinBox(self.mainAreaPage)
self.shadowSizeSpinBox.setObjectName(u'shadowSizeSpinBox')
self.shadowLayout.addWidget(self.shadowSizeSpinBox)
self.formLayout.setLayout(5, QtGui.QFormLayout.FieldRole, self.shadowLayout)
self.boldCheckBox = QtGui.QCheckBox(self.mainAreaPage)
self.boldCheckBox.setObjectName(u'boldCheckBox')
self.formLayout.setWidget(6, QtGui.QFormLayout.FieldRole, self.boldCheckBox)
self.italicsCheckBox = QtGui.QCheckBox(self.mainAreaPage)
self.italicsCheckBox.setObjectName(u'italicsCheckBox')
self.formLayout.setWidget(7, QtGui.QFormLayout.FieldRole, self.italicsCheckBox)
ThemeWizard.addPage(self.mainAreaPage)
self.footerAreaPage = QtGui.QWizardPage()
self.footerAreaPage.setObjectName(u'footerAreaPage')
self.footerLayout = QtGui.QFormLayout(self.footerAreaPage)
self.footerLayout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow)
self.footerLayout.setContentsMargins(50, 20, 20, 20)
self.footerLayout.setSpacing(8)
self.footerLayout.setObjectName(u'footerLayout')
self.footerFontLabel = QtGui.QLabel(self.footerAreaPage)
self.footerFontLabel.setObjectName(u'footerFontLabel')
self.footerLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.footerFontLabel)
self.footerFontComboBox = QtGui.QFontComboBox(self.footerAreaPage)
self.footerFontComboBox.setObjectName(u'footerFontComboBox')
self.footerLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.footerFontComboBox)
self.footerColorLabel = QtGui.QLabel(self.footerAreaPage)
self.footerColorLabel.setObjectName(u'footerColorLabel')
self.footerLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.footerColorLabel)
self.footerColorPushButton = QtGui.QPushButton(self.footerAreaPage)
self.footerColorPushButton.setText(u'')
self.footerColorPushButton.setObjectName(u'footerColorPushButton')
self.footerLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.footerColorPushButton)
self.footerSizeLabel = QtGui.QLabel(self.footerAreaPage)
self.footerSizeLabel.setObjectName(u'footerSizeLabel')
self.footerLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.footerSizeLabel)
self.footerSizeSpinBox = QtGui.QSpinBox(self.footerAreaPage)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.footerSizeSpinBox.sizePolicy().hasHeightForWidth())
self.footerSizeSpinBox.setSizePolicy(sizePolicy)
self.footerSizeSpinBox.setMinimumSize(QtCore.QSize(70, 0))
self.footerSizeSpinBox.setMaximum(999)
self.footerSizeSpinBox.setProperty(u'value', 10)
self.footerSizeSpinBox.setObjectName(u'footerSizeSpinBox')
self.footerLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.footerSizeSpinBox)
ThemeWizard.addPage(self.footerAreaPage)
self.alignmentPage = QtGui.QWizardPage()
self.alignmentPage.setObjectName(u'alignmentPage')
self.formLayout_2 = QtGui.QFormLayout(self.alignmentPage)
self.formLayout_2.setMargin(20)
self.formLayout_2.setObjectName(u'formLayout_2')
self.horizontalLabel = QtGui.QLabel(self.alignmentPage)
self.horizontalLabel.setObjectName(u'horizontalLabel')
self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.horizontalLabel)
self.horizontalComboBox = QtGui.QComboBox(self.alignmentPage)
self.horizontalComboBox.setEditable(False)
self.horizontalComboBox.setObjectName(u'horizontalComboBox')
self.horizontalComboBox.addItem(u'')
self.horizontalComboBox.addItem(u'')
self.horizontalComboBox.addItem(u'')
self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.horizontalComboBox)
self.verticalLabel = QtGui.QLabel(self.alignmentPage)
self.verticalLabel.setObjectName(u'verticalLabel')
self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.verticalLabel)
self.verticalComboBox = QtGui.QComboBox(self.alignmentPage)
self.verticalComboBox.setObjectName(u'verticalComboBox')
self.verticalComboBox.addItem(u'')
self.verticalComboBox.addItem(u'')
self.verticalComboBox.addItem(u'')
self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.verticalComboBox)
self.transitionsCheckBox = QtGui.QCheckBox(self.alignmentPage)
self.transitionsCheckBox.setObjectName(u'transitionsCheckBox')
self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.transitionsCheckBox)
ThemeWizard.addPage(self.alignmentPage)
self.areaPositionPage = QtGui.QWizardPage()
self.areaPositionPage.setObjectName(u'areaPositionPage')
self.gridLayout_2 = QtGui.QGridLayout(self.areaPositionPage)
self.gridLayout_2.setMargin(20)
self.gridLayout_2.setSpacing(8)
self.gridLayout_2.setObjectName(u'gridLayout_2')
self.mainPositionGroupBox = QtGui.QGroupBox(self.areaPositionPage)
self.mainPositionGroupBox.setMinimumSize(QtCore.QSize(248, 0))
self.mainPositionGroupBox.setObjectName(u'mainPositionGroupBox')
self.mainPositionLayout = QtGui.QFormLayout(self.mainPositionGroupBox)
self.mainPositionLayout.setMargin(8)
self.mainPositionLayout.setSpacing(8)
self.mainPositionLayout.setObjectName(u'mainPositionLayout')
self.mainDefaultPositionCheckBox = QtGui.QCheckBox(self.mainPositionGroupBox)
self.mainDefaultPositionCheckBox.setChecked(True)
self.mainDefaultPositionCheckBox.setTristate(False)
self.mainDefaultPositionCheckBox.setObjectName(u'mainDefaultPositionCheckBox')
self.mainPositionLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.mainDefaultPositionCheckBox)
self.nainXLabel = QtGui.QLabel(self.mainPositionGroupBox)
self.nainXLabel.setObjectName(u'nainXLabel')
self.mainPositionLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.nainXLabel)
self.mainXSpinBox = QtGui.QSpinBox(self.mainPositionGroupBox)
self.mainXSpinBox.setEnabled(False)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.mainXSpinBox.sizePolicy().hasHeightForWidth())
self.mainXSpinBox.setSizePolicy(sizePolicy)
self.mainXSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.mainXSpinBox.setMaximum(9999)
self.mainXSpinBox.setProperty(u'value', 0)
self.mainXSpinBox.setObjectName(u'mainXSpinBox')
self.mainPositionLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.mainXSpinBox)
self.mainYSpinBox = QtGui.QSpinBox(self.mainPositionGroupBox)
self.mainYSpinBox.setEnabled(False)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.mainYSpinBox.sizePolicy().hasHeightForWidth())
self.mainYSpinBox.setSizePolicy(sizePolicy)
self.mainYSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.mainYSpinBox.setMaximum(9999)
self.mainYSpinBox.setObjectName(u'mainYSpinBox')
self.mainPositionLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.mainYSpinBox)
self.mainYLabel = QtGui.QLabel(self.mainPositionGroupBox)
self.mainYLabel.setObjectName(u'mainYLabel')
self.mainPositionLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.mainYLabel)
self.mainWidthSpinBox = QtGui.QSpinBox(self.mainPositionGroupBox)
self.mainWidthSpinBox.setEnabled(False)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.mainWidthSpinBox.sizePolicy().hasHeightForWidth())
self.mainWidthSpinBox.setSizePolicy(sizePolicy)
self.mainWidthSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.mainWidthSpinBox.setMaximum(9999)
self.mainWidthSpinBox.setObjectName(u'mainWidthSpinBox')
self.mainPositionLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.mainWidthSpinBox)
self.mainWidthLabel = QtGui.QLabel(self.mainPositionGroupBox)
self.mainWidthLabel.setObjectName(u'mainWidthLabel')
self.mainPositionLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.mainWidthLabel)
self.mainHeightSpinBox = QtGui.QSpinBox(self.mainPositionGroupBox)
self.mainHeightSpinBox.setEnabled(False)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.mainHeightSpinBox.sizePolicy().hasHeightForWidth())
self.mainHeightSpinBox.setSizePolicy(sizePolicy)
self.mainHeightSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.mainHeightSpinBox.setMaximum(9999)
self.mainHeightSpinBox.setObjectName(u'mainHeightSpinBox')
self.mainPositionLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.mainHeightSpinBox)
self.mainHeightLabel = QtGui.QLabel(self.mainPositionGroupBox)
self.mainHeightLabel.setObjectName(u'mainHeightLabel')
self.mainPositionLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.mainHeightLabel)
self.gridLayout_2.addWidget(self.mainPositionGroupBox, 1, 0, 1, 1)
self.footerPositionGroupBox = QtGui.QGroupBox(self.areaPositionPage)
self.footerPositionGroupBox.setMinimumSize(QtCore.QSize(248, 0))
self.footerPositionGroupBox.setObjectName(u'footerPositionGroupBox')
self.footerPositionLayout = QtGui.QFormLayout(self.footerPositionGroupBox)
self.footerPositionLayout.setMargin(8)
self.footerPositionLayout.setSpacing(8)
self.footerPositionLayout.setObjectName(u'footerPositionLayout')
self.footerXLabel = QtGui.QLabel(self.footerPositionGroupBox)
self.footerXLabel.setObjectName(u'footerXLabel')
self.footerPositionLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.footerXLabel)
self.footerXSpinBox = QtGui.QSpinBox(self.footerPositionGroupBox)
self.footerXSpinBox.setEnabled(False)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.footerXSpinBox.sizePolicy().hasHeightForWidth())
self.footerXSpinBox.setSizePolicy(sizePolicy)
self.footerXSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.footerXSpinBox.setMaximum(9999)
self.footerXSpinBox.setProperty(u'value', 0)
self.footerXSpinBox.setObjectName(u'footerXSpinBox')
self.footerPositionLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.footerXSpinBox)
self.footerYLabel = QtGui.QLabel(self.footerPositionGroupBox)
self.footerYLabel.setObjectName(u'footerYLabel')
self.footerPositionLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.footerYLabel)
self.footerYSpinBox = QtGui.QSpinBox(self.footerPositionGroupBox)
self.footerYSpinBox.setEnabled(False)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.footerYSpinBox.sizePolicy().hasHeightForWidth())
self.footerYSpinBox.setSizePolicy(sizePolicy)
self.footerYSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.footerYSpinBox.setMaximum(9999)
self.footerYSpinBox.setProperty(u'value', 0)
self.footerYSpinBox.setObjectName(u'footerYSpinBox')
self.footerPositionLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.footerYSpinBox)
self.footerWidthLabel = QtGui.QLabel(self.footerPositionGroupBox)
self.footerWidthLabel.setObjectName(u'footerWidthLabel')
self.footerPositionLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.footerWidthLabel)
self.footerWidthSpinBox = QtGui.QSpinBox(self.footerPositionGroupBox)
self.footerWidthSpinBox.setEnabled(False)
self.footerWidthSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.footerWidthSpinBox.setMaximum(9999)
self.footerWidthSpinBox.setObjectName(u'footerWidthSpinBox')
self.footerPositionLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.footerWidthSpinBox)
self.footerHeightLabel = QtGui.QLabel(self.footerPositionGroupBox)
self.footerHeightLabel.setObjectName(u'footerHeightLabel')
self.footerPositionLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.footerHeightLabel)
self.footerHeightSpinBox = QtGui.QSpinBox(self.footerPositionGroupBox)
self.footerHeightSpinBox.setEnabled(False)
self.footerHeightSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.footerHeightSpinBox.setMaximum(9999)
self.footerHeightSpinBox.setObjectName(u'footerHeightSpinBox')
self.footerPositionLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.footerHeightSpinBox)
self.footerDefaultPositionCheckBox = QtGui.QCheckBox(self.footerPositionGroupBox)
self.footerDefaultPositionCheckBox.setChecked(True)
self.footerDefaultPositionCheckBox.setObjectName(u'footerDefaultPositionCheckBox')
self.footerPositionLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.footerDefaultPositionCheckBox)
self.gridLayout_2.addWidget(self.footerPositionGroupBox, 1, 1, 1, 1)
ThemeWizard.addPage(self.areaPositionPage)
self.previewPage = QtGui.QWizardPage()
self.previewPage.setObjectName(u'previewPage')
self.themeNameLabel = QtGui.QLabel(self.previewPage)
self.themeNameLabel.setGeometry(QtCore.QRect(20, 10, 82, 16))
self.themeNameLabel.setTextFormat(QtCore.Qt.PlainText)
self.themeNameLabel.setObjectName(u'themeNameLabel')
self.previewLabel = QtGui.QLabel(self.previewPage)
self.previewLabel.setGeometry(QtCore.QRect(250, 60, 48, 16))
self.previewLabel.setAlignment(QtCore.Qt.AlignCenter)
self.previewLabel.setObjectName(u'previewLabel')
self.themeNameEdit = QtGui.QLineEdit(self.previewPage)
self.themeNameEdit.setGeometry(QtCore.QRect(117, 4, 351, 23))
self.themeNameEdit.setObjectName(u'themeNameEdit')
self.groupBox = QtGui.QGroupBox(self.previewPage)
self.groupBox.setGeometry(QtCore.QRect(40, 80, 464, 214))
self.groupBox.setTitle(u'')
self.groupBox.setObjectName(u'groupBox')
self.horizontalLayout = QtGui.QHBoxLayout(self.groupBox)
self.horizontalLayout.setObjectName(u'horizontalLayout')
spacerItem2 = QtGui.QSpacerItem(58, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem2)
self.previewBoxLabel = QtGui.QLabel(self.groupBox)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.previewBoxLabel.sizePolicy().hasHeightForWidth())
self.previewBoxLabel.setSizePolicy(sizePolicy)
self.previewBoxLabel.setMinimumSize(QtCore.QSize(300, 200))
self.previewBoxLabel.setFrameShape(QtGui.QFrame.WinPanel)
self.previewBoxLabel.setFrameShadow(QtGui.QFrame.Sunken)
self.previewBoxLabel.setLineWidth(1)
self.previewBoxLabel.setText(u'')
self.previewBoxLabel.setScaledContents(True)
self.previewBoxLabel.setObjectName(u'previewBoxLabel')
self.horizontalLayout.addWidget(self.previewBoxLabel)
spacerItem3 = QtGui.QSpacerItem(78, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem3)
ThemeWizard.addPage(self.previewPage)
self.themeNameLabel.setBuddy(self.themeNameEdit)
self.retranslateUi(ThemeWizard)
QtCore.QObject.connect(ThemeWizard, QtCore.SIGNAL(u'accepted()'), ThemeWizard.accept)
QtCore.QMetaObject.connectSlotsByName(ThemeWizard)
def retranslateUi(self, ThemeWizard):
ThemeWizard.setWindowTitle(translate('OpenLP.ThemeForm', 'Theme Wizard'))
self.titleLabel.setText(translate('OpenLP.ThemeForm', '<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n'
'<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n'
'p, li { white-space: pre-wrap; }\n'
'</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:normal;\">\n'
'<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:14pt; font-weight:600;\">Welcome to the Theme Wizard</span></p></body></html>'))
self.informationLabel.setText(translate('OpenLP.ThemeForm', 'This wizard will help you to maintain Themes . Click the next button below to start the process by setting up your background.'))
self.backgroundPage.setTitle(translate('OpenLP.ThemeForm', 'Set Up Background'))
self.backgroundPage.setSubTitle(translate('OpenLP.ThemeForm', 'Set up your theme\'s background according to the parameters below.'))
self.backgroundTypeLabel.setText(translate('OpenLP.ThemeForm', 'Background type:'))
self.backgroundTypeComboBox.setItemText(0, translate('OpenLP.ThemeForm', 'Solid Color'))
self.backgroundTypeComboBox.setItemText(1, translate('OpenLP.ThemeForm', 'Gradient'))
self.backgroundTypeComboBox.setItemText(2, translate('OpenLP.ThemeForm', 'Image'))
self.color1Label.setText(translate('OpenLP.ThemeForm', '<Color1>'))
self.color2Label.setText(translate('OpenLP.ThemeForm', '<Color2>'))
self.imageLabel.setText(translate('OpenLP.ThemeForm', 'Image:'))
self.gradientLabel.setText(translate('OpenLP.ThemeForm', 'Gradient:'))
self.gradientComboBox.setItemText(0, translate('OpenLP.ThemeForm', 'Horizontal'))
self.gradientComboBox.setItemText(1, translate('OpenLP.ThemeForm', 'Vertical'))
self.gradientComboBox.setItemText(2, translate('OpenLP.ThemeForm', 'Circular'))
self.gradientComboBox.setItemText(3, translate('OpenLP.ThemeForm', 'Top Left - Bottom Right'))
self.gradientComboBox.setItemText(4, translate('OpenLP.ThemeForm', 'Bottom Left - Top Right'))
self.mainAreaPage.setTitle(translate('OpenLP.ThemeForm', 'Main Area Font Details'))
self.mainAreaPage.setSubTitle(translate('OpenLP.ThemeForm', 'Define the font and display characteristics for the Display text'))
self.mainFontLabel.setText(translate('OpenLP.ThemeForm', 'Font:'))
self.mainColorLabel.setText(translate('OpenLP.ThemeForm', 'Color:'))
self.mainSizeLabel.setText(translate('OpenLP.ThemeForm', 'Size:'))
self.mainSizeSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'pt'))
self.mainLineCountLabel.setText(translate('OpenLP.ThemeForm', '(%d lines per slide)'))
self.lineSpacingLabel.setText(translate('OpenLP.ThemeForm', 'Line Spacing:'))
self.lineSpacingSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'pt'))
self.outlineCheckBox.setText(translate('OpenLP.ThemeForm', '&Outline:'))
self.outlineSizeLabel.setText(translate('OpenLP.ThemeForm', 'Size:'))
self.outlineSizeSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'pt'))
self.shadowCheckBox.setText(translate('OpenLP.ThemeForm', '&Shadow:'))
self.shadowSizeLabel.setText(translate('OpenLP.ThemeForm', 'Size:'))
self.shadowSizeSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'pt'))
self.boldCheckBox.setText(translate('OpenLP.ThemeForm', 'Bold Display'))
self.italicsCheckBox.setText(translate('OpenLP.ThemeForm', 'Italic Display'))
self.footerAreaPage.setTitle(translate('OpenLP.ThemeForm', 'Footer Area Font Details'))
self.footerAreaPage.setSubTitle(translate('OpenLP.ThemeForm', 'Define the font and display characteristics for the Footer text'))
self.footerFontLabel.setText(translate('OpenLP.ThemeForm', 'Font:'))
self.footerColorLabel.setText(translate('OpenLP.ThemeForm', 'Color:'))
self.footerSizeLabel.setText(translate('OpenLP.ThemeForm', 'Size:'))
self.footerSizeSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'pt'))
self.alignmentPage.setTitle(translate('OpenLP.ThemeForm', 'Text Formatting Details'))
self.alignmentPage.setSubTitle(translate('OpenLP.ThemeForm', 'Allows additional display formatting information to be defined'))
self.horizontalLabel.setText(translate('OpenLP.ThemeForm', 'Horizontal Align:'))
self.horizontalComboBox.setItemText(0, translate('OpenLP.ThemeForm', 'Left'))
self.horizontalComboBox.setItemText(1, translate('OpenLP.ThemeForm', 'Right'))
self.horizontalComboBox.setItemText(2, translate('OpenLP.ThemeForm', 'Center'))
self.verticalLabel.setText(translate('OpenLP.ThemeForm', 'Vertcal Align:'))
self.verticalComboBox.setItemText(0, translate('OpenLP.ThemeForm', 'Top'))
self.verticalComboBox.setItemText(1, translate('OpenLP.ThemeForm', 'Middle'))
self.verticalComboBox.setItemText(2, translate('OpenLP.ThemeForm', 'Bottom'))
self.transitionsCheckBox.setText(translate('OpenLP.ThemeForm', 'Transitions'))
self.areaPositionPage.setTitle(translate('OpenLP.ThemeForm', 'Output Area Locations'))
self.areaPositionPage.setSubTitle(translate('OpenLP.ThemeForm', 'Allows you to change and move the Main and Footer areas.'))
self.mainPositionGroupBox.setTitle(translate('OpenLP.ThemeForm', '&Main Area'))
self.mainDefaultPositionCheckBox.setText(translate('OpenLP.ThemeForm', '&Use default location'))
self.nainXLabel.setText(translate('OpenLP.ThemeForm', 'X position:'))
self.mainXSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'px'))
self.mainYSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'px'))
self.mainYLabel.setText(translate('OpenLP.ThemeForm', 'Y position:'))
self.mainWidthSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'px'))
self.mainWidthLabel.setText(translate('OpenLP.ThemeForm', 'Width:'))
self.mainHeightSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'px'))
self.mainHeightLabel.setText(translate('OpenLP.ThemeForm', 'Height:'))
self.footerPositionGroupBox.setTitle(translate('OpenLP.ThemeForm', 'Footer Area'))
self.footerXLabel.setText(translate('OpenLP.ThemeForm', 'X position:'))
self.footerXSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'px'))
self.footerYLabel.setText(translate('OpenLP.ThemeForm', 'Y position:'))
self.footerYSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'px'))
self.footerWidthLabel.setText(translate('OpenLP.ThemeForm', 'Width:'))
self.footerWidthSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'px'))
self.footerHeightLabel.setText(translate('OpenLP.ThemeForm', 'Height:'))
self.footerHeightSpinBox.setSuffix(translate('OpenLP.ThemeForm', 'px'))
self.footerDefaultPositionCheckBox.setText(translate('OpenLP.ThemeForm', 'Use default location'))
self.previewPage.setTitle(translate('OpenLP.ThemeForm', 'Save and Preview'))
self.previewPage.setSubTitle(translate('OpenLP.ThemeForm', 'View the theme and save it replacing the current one or change the name to create a new theme'))
self.themeNameLabel.setText(translate('OpenLP.ThemeForm', 'Theme name:'))
self.previewLabel.setText(translate('OpenLP.ThemeForm', 'Preview'))

View File

@ -60,7 +60,6 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
def contextMenu(self, point): def contextMenu(self, point):
item = self.serviceManagerList.itemAt(point) item = self.serviceManagerList.itemAt(point)
print item
def insertVerse(self, title, num=1): def insertVerse(self, title, num=1):
if self.verseTextEdit.textCursor().columnNumber() != 0: if self.verseTextEdit.textCursor().columnNumber() != 0:

View File

@ -122,7 +122,8 @@ class SongsPlugin(Plugin):
self.toolsReindexItem = QtGui.QAction(tools_menu) self.toolsReindexItem = QtGui.QAction(tools_menu)
self.toolsReindexItem.setIcon(build_icon(u':/plugins/plugin_songs.png')) self.toolsReindexItem.setIcon(build_icon(u':/plugins/plugin_songs.png'))
self.toolsReindexItem.setObjectName(u'toolsReindexItem') self.toolsReindexItem.setObjectName(u'toolsReindexItem')
self.toolsReindexItem.setText(translate('SongsPlugin', '&Re-index Songs')) self.toolsReindexItem.setText(
translate('SongsPlugin', '&Re-index Songs'))
self.toolsReindexItem.setStatusTip( self.toolsReindexItem.setStatusTip(
translate('SongsPlugin', 'Re-index the songs database to improve ' translate('SongsPlugin', 'Re-index the songs database to improve '
'searching and ordering.')) 'searching and ordering.'))
@ -149,8 +150,9 @@ class SongsPlugin(Plugin):
song.title = u'' song.title = u''
if song.alternate_title is None: if song.alternate_title is None:
song.alternate_title = u'' song.alternate_title = u''
song.search_title = self.whitespace.sub(u' ', song.title.lower()) +\ song.search_title = self.whitespace.sub(u' ', \
u' ' + self.whitespace.sub(u' ', song.alternate_title.lower()) song.title.lower()) + u' ' + \
self.whitespace.sub(u' ', song.alternate_title.lower())
progressDialog.setValue(counter) progressDialog.setValue(counter)
self.manager.save_objects(songs) self.manager.save_objects(songs)
counter += 1 counter += 1

File diff suppressed because it is too large Load Diff