trunk r1125

This commit is contained in:
Andreas Preikschat 2010-11-28 15:36:29 +01:00
commit d2f6c4c9b0
44 changed files with 2839 additions and 985 deletions

View File

@ -48,7 +48,7 @@ Service Manger
--------------
The service manager contains the media items in your service file. This is the
area from wich your media items go live, and you can also save, open, and edit
area from which your media items go live, and you can also save, open, and edit
services files.
.. image:: pics/servicemanager.png

View File

@ -14,6 +14,8 @@ Contents:
introduction
glossary
dualmonitors
mediamanager
songs
Indices and tables
==================

View File

@ -0,0 +1,26 @@
=============
Media Manager
=============
Once you get your system set up for OpenLP you will be ready to add content to
your setup. This will all happen through the **Media Manager**. The
`Media Manager` contains all the bibles, songs, presentations, media, and
everything else that you will project through OpenLP.
Enabling the Plugins
--------------------
You may need to enable the plugins that came with OpenLP. As you can see below
this is what the `Media Manager` looks like with all the plugins enabled.
.. image:: pics/mediamanager.png
To enable the plugins navigate to :menuselection:`Settings --> Plugins` or
press `F7`. You will then want to click on the plugin to the left that you want
to enable and select **active** from the drop down box to the right.
.. image:: pics/plugins.png
Now you should be ready to add content to OpenLP check out the section of this
guide on the individual plugins.

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

0
documentation/manual/source/pics/vistapersonalize.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 139 KiB

0
documentation/manual/source/pics/winsevendisplay.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,100 @@
=====
Songs
=====
Managing your songs in OpenLP is a relatively simple process. There are also
converters provided to get data from other formats into OpenLP.
Song Importer
=============
If you are using an earlier version of OpenLP or come from another software
package, you may be able to convert your existing database to work in OpenLP
2.0. To access the Song Importer :menuselection:`File --> Import --> Song`.
You will then see the Song Importer window, then click :guilabel:`Next`.
.. image:: pics/songimporter.png
After choosing :guilabel:`Next` you can then select from the various types of
software that OpenLP will convert songs from.
.. image:: pics/songimporterchoices.png
Then click on the file folder icon to choose the file of the song database you
want to import. See the following sections for information on the different
formats that OpenLP will import.
Importing from OpenLP Version 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Converting from OpenLP Version 1 is a pretty simple process. You will first
need to locate your version 1 database file.
Windows XP::
C:\Documents and Settings\All Users\Application Data\openlp.org\Data\songs.olp
Windows Vista / Windows 7::
C:\ProgramData\openlp.org\Data\songs.olp
After clicking :guilabel:`Next` your conversion should be complete.
.. image:: pics/finishedimport.png
Then press :guilabel:`Finish` and you should now be ready to use your OpenLP
version one songs.
Importing from OpenSong
^^^^^^^^^^^^^^^^^^^^^^^
Converting from OpenSong you will need to locate your songs database. In the
later versions of OpenSong you are asked to define the location of this. The
songs will be located in a folder named :guilabel:`Songs`. This folder should
contain files with all your songs in them without a file extension. (file.xxx).
When you have located this folder you will then need to select the songs from
the folder.
.. image:: pics/selectsongs.png
On most operating systems to select all the songs, first select the first song
in the lest then press shift and select the last song in the list. After this
press :guilabel:`Next` and you should see that your import has been successful.
.. image:: pics/finishedimport.png
Press :guilabel:`Finish` and you will now be ready to use your songs imported
from OpenSong.
Importing from CCLI Song Select
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To import from CCLI Song Select you must be a CCLI Subscriber and also a
subscriber of the Song Select service. For info on that go to:
http://www.ccli.com
The first step for importing from CCLI Song Select is to log into your account.
Then search for your desired song. For this example we will be adding the song
"Amazing Grace".
.. image:: pics/songselectsongsearch.png
For the song you are searching for select `lyrics` This should take you to a
page displaying the lyrics and copyright info for your song.
.. image:: pics/songselectlyrics.png
Next, hover over the :guilabel:`Lyrics` menu from the upper right corner. Then
choose either the .txt or .usr file. You will then be asked to chose a download
location if your browser does not automatically select that for you. Select
this file from the OpenLP import window and then click :guilabel:`Next` You can
also select multiple songs for import at once on most operating systems by
selecting the first item in the list then holding shift select the last item in
the list. When finished you should see that your import has completed.
.. image:: pics/finishedimport.png
Press :guilabel:`Finish` and you will now be ready to use your songs imported
from CCLI SongSelect.

View File

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

View File

@ -158,6 +158,27 @@ class Manager(object):
log.exception(u'Object save failed')
return False
def save_objects(self, object_list, commit=True):
"""
Save a list of objects to the database
``object_list``
The list of objects to save
``commit``
Commit the session with this object
"""
try:
self.session.add_all(object_list)
if commit:
self.session.commit()
self.is_dirty = True
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Object list save failed')
return False
def get_object(self, object_class, key=None):
"""
Return the details of an object
@ -207,6 +228,22 @@ class Manager(object):
return query.order_by(order_by_ref).all()
return query.all()
def get_object_count(self, object_class, filter_clause=None):
"""
Returns a count of the number of objects in the database.
``object_class``
The type of objects to return.
``filter_clause``
The filter governing selection of objects to return. Defaults to
None.
"""
query = self.session.query(object_class)
if filter_clause is not None:
query = query.filter(filter_clause)
return query.count()
def delete_object(self, object_class, key):
"""
Delete an object from the database

View File

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

View File

@ -514,7 +514,7 @@ class MediaManagerItem(QtGui.QWidget):
self.parent.serviceManager.addServiceItem(service_item,
replace=True)
else:
#Turn off the remote edit update message indicator
# Turn off the remote edit update message indicator
QtGui.QMessageBox.information(self,
translate('OpenLP.MediaManagerItem',
'Invalid Service Item'),

View File

@ -32,7 +32,7 @@ import logging
from PyQt4 import QtWebKit
from openlp.core.lib import expand_tags, build_lyrics_format_css, \
build_lyrics_outline_css
build_lyrics_outline_css, Receiver
log = logging.getLogger(__name__)
@ -77,9 +77,9 @@ class Renderer(object):
self._rect_footer = rect_footer
self.page_width = self._rect.width()
self.page_height = self._rect.height()
if self._theme.display_shadow:
self.page_width -= int(self._theme.display_shadow_size)
self.page_height -= int(self._theme.display_shadow_size)
if self._theme.font_main_shadow:
self.page_width -= int(self._theme.font_main_shadow_size)
self.page_height -= int(self._theme.font_main_shadow_size)
self.web = QtWebKit.QWebView()
self.web.setVisible(False)
self.web.resize(self.page_width, self.page_height)
@ -92,13 +92,20 @@ class Renderer(object):
(build_lyrics_format_css(self._theme, self.page_width,
self.page_height), build_lyrics_outline_css(self._theme))
def format_slide(self, words, line_break):
def format_slide(self, words, line_break, force_page=False):
"""
Figure out how much text can appear on a slide, using the current
theme settings.
``words``
The words to be fitted on the slide.
``line_break``
Add line endings after each line of text used for bibles.
``force_page``
Flag to tell message lines in page.
"""
log.debug(u'format_slide - Start')
line_end = u''
@ -114,13 +121,19 @@ class Renderer(object):
formatted = []
html_text = u''
styled_text = u''
line_count = 0
for line in text:
if line_count != -1:
line_count += 1
styled_line = expand_tags(line) + line_end
styled_text += styled_line
html = self.page_shell + styled_text + u'</div></body></html>'
self.web.setHtml(html)
# Text too long so go to next page
if self.web_frame.contentsSize().height() > self.page_height:
if force_page and line_count > 0:
Receiver.send_message(u'theme_line_count', line_count)
line_count = -1
if html_text.endswith(u'<br>'):
html_text = html_text[:len(html_text)-4]
formatted.append(html_text)

View File

@ -67,8 +67,9 @@ class RenderManager(object):
self.service_theme = u''
self.theme_level = u''
self.override_background = None
self.themedata = None
self.theme_data = None
self.alertTab = None
self.force_page = False
def update_display(self):
"""
@ -80,7 +81,7 @@ class RenderManager(object):
self.display.imageManager = self.image_manager
self.display.setup()
self.renderer.bg_frame = None
self.themedata = None
self.theme_data = None
self.image_manager.update_display(self.width, self.height)
def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global):
@ -99,7 +100,7 @@ class RenderManager(object):
self.theme_level = theme_level
self.global_theme_data = \
self.theme_manager.getThemeData(self.global_theme)
self.themedata = None
self.theme_data = None
def set_service_theme(self, service_theme):
"""
@ -109,7 +110,7 @@ class RenderManager(object):
The service-level theme to be set.
"""
self.service_theme = service_theme
self.themedata = None
self.theme_data = None
def set_override_theme(self, theme, overrideLevels=False):
"""
@ -146,19 +147,19 @@ class RenderManager(object):
self.theme = self.service_theme
else:
self.theme = self.global_theme
if self.theme != self.renderer.theme_name or self.themedata is None \
if self.theme != self.renderer.theme_name or self.theme_data is None \
or overrideLevels:
log.debug(u'theme is now %s', self.theme)
# Force the theme to be the one passed in.
if overrideLevels:
self.themedata = theme
self.theme_data = theme
else:
self.themedata = self.theme_manager.getThemeData(self.theme)
self.theme_data = self.theme_manager.getThemeData(self.theme)
self.calculate_default(self.screens.current[u'size'])
self.renderer.set_theme(self.themedata)
self.build_text_rectangle(self.themedata)
self.image_manager.add_image(self.themedata.theme_name,
self.themedata.background_filename)
self.renderer.set_theme(self.theme_data)
self.build_text_rectangle(self.theme_data)
self.image_manager.add_image(self.theme_data.theme_name,
self.theme_data.background_filename)
return self.renderer._rect, self.renderer._rect_footer
def build_text_rectangle(self, theme):
@ -187,14 +188,19 @@ class RenderManager(object):
theme.font_footer_height - 1)
self.renderer.set_text_rectangle(main_rect, footer_rect)
def generate_preview(self, themedata):
def generate_preview(self, theme_data, force_page=False):
"""
Generate a preview of a theme.
``themedata``
``theme_data``
The theme to generated a preview for.
``force_page``
Flag to tell message lines per page need to be generated.
"""
log.debug(u'generate preview')
# save value for use in format_slide
self.force_page = force_page
# set the default image size for previews
self.calculate_default(self.screens.preview[u'size'])
verse = u'The Lord said to {r}Noah{/r}: \n' \
@ -204,23 +210,27 @@ class RenderManager(object):
'Get those children out of the muddy, muddy \n' \
'{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}' \
'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
# make big page for theme edit dialog to get line count
if self.force_page:
verse = verse + verse + verse
footer = []
footer.append(u'Arky Arky (Unknown)' )
footer.append(u'Public Domain')
footer.append(u'CCLI 123456')
# build a service item to generate preview
serviceItem = ServiceItem()
serviceItem.theme = themedata
serviceItem.theme = theme_data
serviceItem.add_from_text(u'', verse, footer)
serviceItem.render_manager = self
serviceItem.raw_footer = footer
serviceItem.render(True)
self.display.buildHtml(serviceItem)
raw_html = serviceItem.get_rendered_frame(0)
preview = self.display.text(raw_html)
# Reset the real screen size for subsequent render requests
self.calculate_default(self.screens.current[u'size'])
return preview
if not self.force_page:
self.display.buildHtml(serviceItem)
raw_html = serviceItem.get_rendered_frame(0)
preview = self.display.text(raw_html)
# Reset the real screen size for subsequent render requests
self.calculate_default(self.screens.current[u'size'])
return preview
def format_slide(self, words, line_break):
"""
@ -228,9 +238,12 @@ class RenderManager(object):
``words``
The words to go on the slides.
``line_break``
Add line endings after each line of text used for bibles.
"""
log.debug(u'format slide')
return self.renderer.format_slide(words, line_break)
return self.renderer.format_slide(words, line_break, self.force_page)
def calculate_default(self, screen):
"""

View File

@ -100,6 +100,7 @@ class ServiceItem(object):
self.bg_image_bytes = None
self.search_string = u''
self.data_string = u''
self.edit_id = None
self._new_item()
def _new_item(self):

View File

@ -28,52 +28,56 @@ Provide the theme XML and handling functions for OpenLP v2 themes.
"""
import os
import re
import logging
from xml.dom.minidom import Document
from xml.etree.ElementTree import ElementTree, XML
from lxml import etree, objectify
from openlp.core.lib import str_to_bool
log = logging.getLogger(__name__)
BLANK_THEME_XML = \
'''<?xml version="1.0" encoding="utf-8"?>
<theme version="1.0">
<name>BlankStyle</name>
<background mode="transparent"/>
<background type="solid" mode="opaque">
<color>#000000</color>
<name> </name>
<background type="image">
<filename></filename>
</background>
<background type="gradient" mode="opaque">
<background type="gradient">
<startColor>#000000</startColor>
<endColor>#000000</endColor>
<direction>vertical</direction>
</background>
<background type="image" mode="opaque">
<filename></filename>
<background type="solid">
<color>#000000</color>
</background>
<font type="main">
<name>Arial</name>
<color>#000000</color>
<proportion>30</proportion>
<weight>Normal</weight>
<color>#FFFFFF</color>
<size>30</size>
<bold>False</bold>
<italics>False</italics>
<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"/>
</font>
<font type="footer">
<name>Arial</name>
<color>#000000</color>
<proportion>12</proportion>
<weight>Normal</weight>
<color>#FFFFFF</color>
<size>12</size>
<bold>False</bold>
<italics>False</italics>
<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"/>
</font>
<display>
<shadow color="#000000" size="5">True</shadow>
<outline color="#000000" size="2">False</outline>
<horizontalAlign>0</horizontalAlign>
<verticalAlign>0</verticalAlign>
<wrapStyle>0</wrapStyle>
<slideTransition>False</slideTransition>
</display>
</theme>
@ -87,10 +91,76 @@ class ThemeLevel(object):
Service = 2
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',
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'vertical_align', u'wrap_style']
@ -104,6 +174,7 @@ class ThemeXML(object):
"""
# Create the minidom document
self.theme_xml = Document()
self.parse_xml(BLANK_THEME_XML)
def extend_image_filename(self, path):
"""
@ -112,19 +183,21 @@ class ThemeXML(object):
``path``
The path name to be added.
"""
if self.background_filename and path:
self.theme_name = self.theme_name.strip()
self.background_filename = self.background_filename.strip()
self.background_filename = os.path.join(path, self.theme_name,
self.background_filename)
if self.background_type == u'image':
if self.background_filename and path:
self.theme_name = self.theme_name.strip()
self.background_filename = self.background_filename.strip()
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.
"""
self.theme_xml = Document()
self.theme = self.theme_xml.createElement(u'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')
text_node = self.theme_xml.createTextNode(name)
self.name.appendChild(text_node)
@ -146,10 +219,9 @@ class ThemeXML(object):
The color of the background.
"""
background = self.theme_xml.createElement(u'background')
background.setAttribute(u'mode', u'opaque')
background.setAttribute(u'type', u'solid')
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):
"""
@ -165,15 +237,14 @@ class ThemeXML(object):
The direction of the gradient.
"""
background = self.theme_xml.createElement(u'background')
background.setAttribute(u'mode', u'opaque')
background.setAttribute(u'type', u'gradient')
self.theme.appendChild(background)
# Create startColor element
self.child_element(background, u'startColor', startcolor)
self.child_element(background, u'startColor', unicode(startcolor))
# Create endColor element
self.child_element(background, u'endColor', endcolor)
self.child_element(background, u'endColor', unicode(endcolor))
# Create direction element
self.child_element(background, u'direction', direction)
self.child_element(background, u'direction', unicode(direction))
def add_background_image(self, filename):
"""
@ -183,15 +254,15 @@ class ThemeXML(object):
The file name of the image.
"""
background = self.theme_xml.createElement(u'background')
background.setAttribute(u'mode', u'opaque')
background.setAttribute(u'type', u'image')
self.theme.appendChild(background)
#Create Filename element
# Create Filename element
self.child_element(background, u'filename', filename)
def add_font(self, name, color, proportion, override, fonttype=u'main',
weight=u'Normal', italics=u'False', line_adjustment=0,
xpos=0, ypos=0, width=0, height=0):
def add_font(self, name, color, size, override, fonttype=u'main',
bold=u'False', italics=u'False', line_adjustment=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.
@ -201,7 +272,7 @@ class ThemeXML(object):
``color``
The colour of the font.
``proportion``
``size``
The size of the font.
``override``
@ -227,45 +298,6 @@ class ThemeXML(object):
``height``
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``
Whether or not to show an outline.
@ -273,53 +305,88 @@ class ThemeXML(object):
``outline_color``
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``
The horizontal alignment of the text.
``vertical``
The vertical alignment of the text.
``wrap``
Wrap style.
``transition``
Whether the slide transition is active.
"""
background = self.theme_xml.createElement(u'display')
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
element = self.theme_xml.createElement(u'horizontalAlign')
value = self.theme_xml.createTextNode(horizontal)
value = self.theme_xml.createTextNode(unicode(horizontal))
element.appendChild(value)
background.appendChild(element)
# Vertical alignment
element = self.theme_xml.createElement(u'verticalAlign')
value = self.theme_xml.createTextNode(vertical)
element.appendChild(value)
background.appendChild(element)
# Wrap style
element = self.theme_xml.createElement(u'wrapStyle')
value = self.theme_xml.createTextNode(wrap)
value = self.theme_xml.createTextNode(unicode(vertical))
element.appendChild(value)
background.appendChild(element)
# Slide Transition
element = self.theme_xml.createElement(u'slideTransition')
value = self.theme_xml.createTextNode(transition)
value = self.theme_xml.createTextNode(unicode(transition))
element.appendChild(value)
background.appendChild(element)
@ -342,12 +409,14 @@ class ThemeXML(object):
"""
Print out the XML string.
"""
self._build_xml_from_attrs()
return self.theme_xml.toxml(u'utf-8').decode(u'utf-8')
def extract_formatted_xml(self):
"""
Pull out the XML string formatted for human consumption
"""
self._build_xml_from_attrs()
return self.theme_xml.toprettyxml(indent=u' ', newl=u'\n',
encoding=u'utf-8')
@ -358,8 +427,7 @@ class ThemeXML(object):
``xml``
The XML string to parse.
"""
self.parse_xml(BLANK_THEME_XML)
self.parse_xml(xml)
self.parse_xml(unicode(xml))
def parse_xml(self, xml):
"""
@ -368,51 +436,95 @@ class ThemeXML(object):
``xml``
The XML string to parse.
"""
theme_xml = ElementTree(element=XML(xml.encode(u'ascii',
u'xmlcharrefreplace')))
# remove encoding string
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()
master = u''
for element in xml_iter:
if not isinstance(element.text, unicode):
element.text = unicode(str(element.text), u'utf-8')
if element.getchildren():
master = element.tag + u'_'
parent = element.getparent()
master = u''
if parent is not None:
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:
# background transparent tags have no children so special case
if element.tag == u'background':
for e in element.attrib.iteritems():
self._create_attr(element.tag , e[0], e[1])
if element.attrib:
for e in element.attrib.iteritems():
if master == u'font_' and e[0] == u'type':
master += e[1] + u'_'
elif master == u'display_' and (element.tag == u'shadow'
or element.tag == u'outline'):
self._create_attr(master, element.tag, element.text)
self._create_attr(master, element.tag + u'_'+ e[0],
e[1])
else:
field = master + e[0]
self._create_attr(master, e[0], e[1])
if element.tag == u'name':
self._create_attr(u'theme', element.tag, element.text)
def _translate_tags(self, master, element, value):
"""
Clean up XML removing and redefining tags
"""
master = master.strip().lstrip()
element = element.strip().lstrip()
value = unicode(value).strip().lstrip()
if master == u'display':
if element == u'wrapStyle':
return True, None, None, None
if element.startswith(u'shadow') or element.startswith(u'outline'):
master = u'font_main'
# fix bold font
if element == u'weight':
element = u'bold'
if value == u'Normal':
value = False
else:
if element.tag:
element.text = element.text.strip().lstrip()
self._create_attr(master , element.tag, element.text)
value = True
if element == u'proportion':
element = u'size'
return False, master, element, value
def _create_attr(self, master , element, value):
"""
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)
tag = master + u'_' + field
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:
setattr(self, master + field, int(value))
setattr(self, tag, int(value))
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.
if value == u'None':
value = u''
setattr(self, master + field, unicode(value))
setattr(self, tag, unicode(value).strip().lstrip())
def __str__(self):
"""
@ -431,3 +543,58 @@ class ThemeXML(object):
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()
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
Screen = 3
from themeform import ThemeForm
from filerenameform import FileRenameForm
from maindisplay import MainDisplay
from servicenoteform import ServiceNoteForm
from serviceitemeditform import ServiceItemEditForm
from screen import ScreenList
from amendthemeform import AmendThemeForm
from slidecontroller import SlideController
from splashscreen import SplashScreen
from generaltab import GeneralTab
@ -58,4 +58,4 @@ from thememanager import ThemeManager
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm',
'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.setObjectName(u'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.expandServiceItemCheckBox = QtGui.QCheckBox(self.uiGroupBox)
self.expandServiceItemCheckBox.setObjectName(

View File

@ -90,6 +90,16 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtCore.QObject.connect(self.fontMainSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
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.SIGNAL(u'editingFinished()'),
self.onFontFooterSizeSpinBoxChanged)
@ -118,12 +128,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
QtCore.QObject.connect(self.fontFooterHeightSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
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
QtCore.QObject.connect(self.fontMainDefaultCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
@ -525,7 +530,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else:
self.gradientComboBox.setCurrentIndex(2)
# Font Main Tab
self.fontMainComboBox.setCurrentFont(
self.mainFontComboBox.setCurrentFont(
QtGui.QFont(self.theme.font_main_name))
self.fontMainSizeSpinBox.setValue(self.theme.font_main_proportion)
if not self.theme.font_main_italics and \

View File

@ -36,6 +36,7 @@ from openlp.core.ui import HideMode
log = logging.getLogger(__name__)
#http://www.steveheffernan.com/html5-video-player/demo-video-player.html
#http://html5demos.com/two-videos
class DisplayWidget(QtGui.QGraphicsView):
"""

View File

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

View File

@ -116,6 +116,7 @@ class ServiceManager(QtGui.QWidget):
self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0)
self.layout.setMargin(0)
self.expandTabs = False
# Create the top toolbar
self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton(
@ -203,13 +204,13 @@ class ServiceManager(QtGui.QWidget):
self.orderToolbar.addSeparator()
self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Expand all'),
u':/services/service_top.png',
u':/services/service_expand_all.png',
translate('OpenLP.ServiceManager',
'Expand all the service items.'),
self.onExpandAll)
self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Collapse all'),
u':/services/service_bottom.png',
u':/services/service_collapse_all.png',
translate('OpenLP.ServiceManager',
'Collapse all the service items.'),
self.onCollapseAll)
@ -307,7 +308,7 @@ class ServiceManager(QtGui.QWidget):
self.maintainAction.setVisible(False)
self.notesAction.setVisible(False)
if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit)\
and hasattr(serviceItem[u'service_item'], u'editId'):
and serviceItem[u'service_item'].edit_id:
self.editAction.setVisible(True)
if serviceItem[u'service_item']\
.is_capable(ItemCapabilities.AllowsMaintain):
@ -863,7 +864,7 @@ class ServiceManager(QtGui.QWidget):
editId, uuid = message.split(u':')
for item in self.serviceItems:
if item[u'service_item']._uuid == uuid:
item[u'service_item'].editId = editId
item[u'service_item'].edit_id = editId
def replaceServiceItem(self, newItem):
"""
@ -872,7 +873,7 @@ class ServiceManager(QtGui.QWidget):
"""
newItem.render()
for itemcount, item in enumerate(self.serviceItems):
if item[u'service_item'].editId == newItem.editId and \
if item[u'service_item'].edit_id == newItem.edit_id and \
item[u'service_item'].name == newItem.name:
newItem.merge(item[u'service_item'])
item[u'service_item'] = newItem
@ -890,8 +891,8 @@ class ServiceManager(QtGui.QWidget):
``expand``
Override the default expand settings. (Tristate)
"""
log.debug(u'addServiceItem')
if expand == None:
# if not passed set to config value
if expand is None:
expand = self.expandTabs
sitem = self.findServiceItem()[0]
item.render()
@ -982,7 +983,7 @@ class ServiceManager(QtGui.QWidget):
.is_capable(ItemCapabilities.AllowsEdit):
Receiver.send_message(u'%s_edit' %
self.serviceItems[item][u'service_item'].name.lower(), u'L:%s' %
self.serviceItems[item][u'service_item'].editId )
self.serviceItems[item][u'service_item'].edit_id )
def findServiceItem(self):
"""

View File

@ -942,7 +942,7 @@ class SlideController(QtGui.QWidget):
"""
self.songEdit = True
Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(),
u'P:%s' % self.serviceItem.editId)
u'P:%s' % self.serviceItem.edit_id)
def onGoLive(self):
"""

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

@ -0,0 +1,650 @@
# -*- 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, \
Receiver
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)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_line_count'),
self.updateLinesText)
QtCore.QObject.connect(self.mainSizeSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'),
self.calculateLines)
QtCore.QObject.connect(self.mainSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.calculateLines)
QtCore.QObject.connect(self.lineSpacingSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'),
self.calculateLines)
QtCore.QObject.connect(self.lineSpacingSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.calculateLines)
QtCore.QObject.connect(self.outlineSizeSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'),
self.calculateLines)
QtCore.QObject.connect(self.outlineSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.calculateLines)
QtCore.QObject.connect(self.shadowSizeSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'),
self.calculateLines)
QtCore.QObject.connect(self.shadowSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.calculateLines)
QtCore.QObject.connect(self.mainFontComboBox,
QtCore.SIGNAL(u'activated(int)'),
self.calculateLines)
def pageChanged(self, pageId):
"""
Detects Page changes and updates as approprate.
"""
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 calculateLines(self):
"""
Calculate the number of lines on a page by rendering text
"""
# Do not trigger on start up
if self.page != 0:
self.updateTheme()
frame = self.thememanager.generateImage(self.theme, True)
def updateLinesText(self, lines):
"""
Updates the lines on a page on the wizard
"""
self.mainLineCountLabel.setText(unicode(translate('OpenLP.ThemeForm', \
'(%d lines per slide)' % int(lines))))
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)
self.calculateLines()
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)
self.calculateLines()
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)
self.page = 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
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None':
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeForm', 'Theme Name Invalid'),
translate('OpenLP.ThemeForm',
'Invalid theme name. '
'Please enter one.'),
(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok)
return
saveFrom = None
saveTo = None
if self.theme.background_type == \
BackgroundType.to_string(BackgroundType.Image):
filename = \
os.path.split(unicode(self.theme.background_filename))[1]
saveTo = os.path.join(self.path, self.theme.theme_name, filename)
saveFrom = self.theme.background_filename
if self.thememanager.saveTheme(self.theme, saveFrom, saveTo):
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 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.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
log = logging.getLogger(__name__)
@ -52,7 +53,7 @@ class ThemeManager(QtGui.QWidget):
self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0)
self.layout.setMargin(0)
self.amendThemeForm = AmendThemeForm(self)
self.themeForm = ThemeForm(self)
self.fileRenameForm = FileRenameForm(self)
self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton(
@ -125,7 +126,7 @@ class ThemeManager(QtGui.QWidget):
self.checkThemesExists(self.path)
self.thumbPath = os.path.join(self.path, u'thumbnails')
self.checkThemesExists(self.thumbPath)
self.amendThemeForm.path = self.path
self.themeForm.path = self.path
self.oldBackgroundImage = None
self.editingDefault = False
# Last little bits of setting up
@ -180,7 +181,7 @@ class ThemeManager(QtGui.QWidget):
'%s (default)')) % newName
self.themeListWidget.item(count).setText(name)
def changeGlobalFromScreen(self, index = -1):
def changeGlobalFromScreen(self, index=-1):
"""
Change the global theme when a theme is double clicked upon in the
Theme Manager list
@ -213,10 +214,10 @@ class ThemeManager(QtGui.QWidget):
Loads a new theme with the default settings and then launches the theme
editing form for the user to make their customisations.
"""
theme = self.createThemeFromXml(self.baseTheme(), self.path)
self.amendThemeForm.loadTheme(theme)
theme = ThemeXML()
self.saveThemeName = u''
self.amendThemeForm.exec_()
self.themeForm.theme = theme
self.themeForm.exec_()
def onRenameTheme(self):
"""
@ -242,67 +243,23 @@ class ThemeManager(QtGui.QWidget):
self.saveThemeName = u''
if self.fileRenameForm.exec_():
newThemeName = unicode(self.fileRenameForm.FileNameEdit.text())
oldThemeData = self.getThemeData(oldThemeName)
self.cloneThemeData(oldThemeData, newThemeName)
themeData = self.getThemeData(oldThemeName)
self.cloneThemeData(themeData, newThemeName)
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')
new_theme = ThemeXML()
new_theme.new_document(newThemeName)
save_from = None
save_to = None
if oldThemeData.background_type == u'solid':
new_theme.add_background_solid(
unicode(oldThemeData.background_color))
elif oldThemeData.background_type == u'gradient':
new_theme.add_background_gradient(
unicode(oldThemeData.background_start_color),
unicode(oldThemeData.background_end_color),
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)
saveTo = None
saveFrom = None
if themeData.background_type == u'image':
saveTo = os.path.join(self.path, newThemeName,
os.path.split(unicode(themeData.background_filename))[1])
saveFrom = themeData.background_filename
themeData.theme_name = newThemeName
self.saveTheme(themeData, saveFrom, saveTo)
def onEditTheme(self):
"""
@ -320,10 +277,10 @@ class ThemeManager(QtGui.QWidget):
unicode(item.data(QtCore.Qt.UserRole).toString()))
if theme.background_type == u'image':
self.oldBackgroundImage = theme.background_filename
self.amendThemeForm.loadTheme(theme)
self.saveThemeName = unicode(
item.data(QtCore.Qt.UserRole).toString())
self.amendThemeForm.exec_()
self.themeForm.theme = theme
self.themeForm.exec_()
def onDeleteTheme(self):
"""
@ -340,7 +297,8 @@ class ThemeManager(QtGui.QWidget):
# confirm deletion
answer = QtGui.QMessageBox.question(self,
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.No), QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
@ -462,6 +420,7 @@ class ThemeManager(QtGui.QWidget):
self.themelist = []
self.themeListWidget.clear()
dirList = os.listdir(self.path)
dirList.sort()
for name in dirList:
if name.endswith(u'.png'):
# check to see file is in theme root directory
@ -500,20 +459,21 @@ class ThemeManager(QtGui.QWidget):
"""
return self.themelist
def getThemeData(self, themename):
def getThemeData(self, themeName):
"""
Returns a theme object from an XML file
``themename``
``themeName``
Name of the theme to load from file
"""
log.debug(u'getthemedata for theme %s', themename)
xml_file = os.path.join(self.path, unicode(themename),
unicode(themename) + u'.xml')
xml = get_text_file_string(xml_file)
log.debug(u'getthemedata for theme %s', themeName)
xmlFile = os.path.join(self.path, unicode(themeName),
unicode(themeName) + u'.xml')
xml = get_text_file_string(xmlFile)
if not xml:
xml = self.baseTheme()
return self.createThemeFromXml(xml, self.path)
return self.baseTheme()
else:
return self.createThemeFromXml(xml, self.path)
def checkThemesExists(self, dir):
"""
@ -584,7 +544,8 @@ class ThemeManager(QtGui.QWidget):
outfile = open(fullpath, u'wb')
outfile.write(zip.read(file))
if filexml:
self.generateAndSaveImage(dir, themename, filexml)
theme = self.createThemeFromXml(filexml, self.path)
self.generateAndSaveImage(dir, themename, theme)
else:
QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'),
@ -631,50 +592,59 @@ class ThemeManager(QtGui.QWidget):
"""
theme = Theme(xml_data)
newtheme = ThemeXML()
newtheme.new_document(theme.Name)
newtheme.theme_name = theme.Name
if theme.BackgroundType == 0:
newtheme.add_background_solid(unicode(
theme.BackgroundParameter1.name()))
newtheme.background_type = \
BackgroundType.to_string(BackgroundType.Solid)
newtheme.background_color = \
unicode(theme.BackgroundParameter1.name())
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:
direction = u'horizontal'
newtheme.add_background_gradient(
unicode(theme.BackgroundParameter1.name()),
unicode(theme.BackgroundParameter2.name()), direction)
newtheme.background_direction = \
BackgroundGradientType. \
to_string(BackgroundGradientType.Horizontal)
newtheme.background_start_color = \
unicode(theme.BackgroundParameter1.name())
newtheme.background_end_color = \
unicode(theme.BackgroundParameter2.name())
else:
newtheme.add_background_image(unicode(theme.BackgroundParameter1))
newtheme.add_font(unicode(theme.FontName),
unicode(theme.FontColor.name()),
unicode(theme.FontProportion * 3), u'False')
newtheme.add_font(unicode(theme.FontName),
unicode(theme.FontColor.name()),
unicode(12), u'False', u'footer')
outline = False
shadow = False
newtheme.background_type = \
BackgroundType.to_string(BackgroundType.Image)
newtheme.background_filename = unicode(theme.BackgroundParameter1)
newtheme.font_main_name = theme.FontName
newtheme.font_main_color = unicode(theme.FontColor.name())
newtheme.font_main_size = theme.FontProportion * 3
newtheme.font_footer_name = theme.FontName
newtheme.font_footer_color = unicode(theme.FontColor.name())
newtheme.font_main_shadow = False
if theme.Shadow == 1:
shadow = True
newtheme.font_main_shadow = True
newtheme.font_main_shadow_color = unicode(theme.ShadowColor.name())
if theme.Outline == 1:
outline = True
newtheme.font_main_outline = True
newtheme.font_main_outline_color = unicode(theme.OutlineColor.name())
vAlignCorrection = 0
if theme.VerticalAlign == 2:
vAlignCorrection = 1
elif theme.VerticalAlign == 1:
vAlignCorrection = 2
newtheme.add_display(unicode(shadow),
unicode(theme.ShadowColor.name()),
unicode(outline), unicode(theme.OutlineColor.name()),
unicode(theme.HorizontalAlign), unicode(vAlignCorrection),
unicode(theme.WrapStyle), unicode(0))
newtheme.display_horizontal_align = theme.HorizontalAlign
newtheme.display_vertical_align = vAlignCorrection
return newtheme.extract_xml()
def saveTheme(self, name, theme_xml, theme_pretty_xml, image_from,
image_to):
def saveTheme(self, theme, imageFrom, imageTo):
"""
Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list
"""
log.debug(u'saveTheme %s %s', name, theme_xml)
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)
if not os.path.exists(theme_dir):
os.mkdir(os.path.join(self.path, name))
@ -700,8 +670,8 @@ class ThemeManager(QtGui.QWidget):
self.deleteTheme(self.saveThemeName)
if result == QtGui.QMessageBox.Yes:
# Save the theme, overwriting the existing theme if necessary.
if image_to and self.oldBackgroundImage and \
image_to != self.oldBackgroundImage:
if imageTo and self.oldBackgroundImage and \
imageTo != self.oldBackgroundImage:
try:
os.remove(self.oldBackgroundImage)
except OSError:
@ -715,15 +685,15 @@ class ThemeManager(QtGui.QWidget):
finally:
if outfile:
outfile.close()
if image_from and image_from != image_to:
if imageFrom and imageFrom != imageTo:
try:
encoding = get_filesystem_encoding()
shutil.copyfile(
unicode(image_from).encode(encoding),
unicode(image_to).encode(encoding))
unicode(imageFrom).encode(encoding),
unicode(imageTo).encode(encoding))
except IOError:
log.exception(u'Failed to save theme image')
self.generateAndSaveImage(self.path, name, theme_xml)
self.generateAndSaveImage(self.path, name, theme)
self.loadThemes()
# Check if we need to set a new service theme
if editedServiceTheme:
@ -748,14 +718,15 @@ class ThemeManager(QtGui.QWidget):
self.global_theme)
self.editingDefault = False
self.pushThemes()
return True
else:
# Don't close the dialog - allow the user to change the name of
# the theme or to cancel the theme dialog completely.
return False
def generateAndSaveImage(self, dir, name, theme_xml):
log.debug(u'generateAndSaveImage %s %s %s', dir, name, theme_xml)
theme = self.createThemeFromXml(theme_xml, dir)
def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s', dir, name)
theme_xml = theme.extract_xml()
frame = self.generateImage(theme)
samplepathname = os.path.join(self.path, name + u'.png')
if os.path.exists(samplepathname):
@ -767,12 +738,18 @@ class ThemeManager(QtGui.QWidget):
pixmap.save(thumb, u'png')
log.debug(u'Theme image written to %s', samplepathname)
def generateImage(self, themedata):
def generateImage(self, themeData, forcePage=False):
"""
Call the RenderManager to build a Sample Image
``themeData``
The theme to generated a preview for.
``forcePage``
Flag to tell message lines per page need to be generated.
"""
log.debug(u'generateImage \n%s ', themedata)
return self.parent.RenderManager.generate_preview(themedata)
log.debug(u'generateImage \n%s ', themeData)
return self.parent.RenderManager.generate_preview(themeData, forcePage)
def getPreviewImage(self, theme):
"""
@ -791,25 +768,16 @@ class ThemeManager(QtGui.QWidget):
"""
log.debug(u'base theme created')
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
def createThemeFromXml(self, theme_xml, path):
def createThemeFromXml(self, themeXml, path):
"""
Return a theme object using information parsed from XML
``theme_xml``
``themeXml``
The XML data to load into the theme
"""
theme = ThemeXML()
theme.parse(theme_xml)
theme.parse(themeXml)
theme.extend_image_filename(path)
return theme

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

@ -213,7 +213,7 @@ class BGExtract(object):
finally:
if not page:
return None
cleaner = [(re.compile('&nbsp;|<br />'), lambda match: '')]
cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')]
soup = None
try:
soup = BeautifulSoup(page, markupMassage=cleaner)

View File

@ -165,7 +165,7 @@ class CustomMediaItem(MediaManagerItem):
customSlide = self.parent.manager.get_object(CustomSlide, item_id)
title = customSlide.title
credit = customSlide.credits
service_item.editId = item_id
service_item.edit_id = item_id
theme = customSlide.theme_name
if theme:
service_item.theme = theme

View File

@ -125,6 +125,8 @@ class MediaMediaItem(MediaManagerItem):
service_item.title = unicode(
translate('MediaPlugin.MediaItem', 'Media'))
service_item.add_capability(ItemCapabilities.RequiresMedia)
# force a nonexistent theme
service_item.theme = -1
frame = u':/media/image_clapperboard.png'
(path, name) = os.path.split(filename)
service_item.add_from_command(path, name, frame)

View File

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

View File

@ -192,6 +192,7 @@ class SongMediaItem(MediaManagerItem):
Handle the exit from the edit dialog and trigger remote updates
of songs
"""
log.debug(u'onSongListLoad')
# Called to redisplay the song list screen edit from a search
# or from the exit of the Song edit dialog. If remote editing is active
# Trigger it and clean up so it will not update again.
@ -259,6 +260,7 @@ class SongMediaItem(MediaManagerItem):
Receiver.send_message(u'songs_load_list')
def onNewClick(self):
log.debug(u'onNewClick')
self.edit_song_form.newSong()
self.edit_song_form.exec_()
@ -266,6 +268,7 @@ class SongMediaItem(MediaManagerItem):
self.song_maintenance_form.exec_()
def onRemoteEditClear(self):
log.debug(u'onRemoteEditClear')
self.remoteTriggered = None
self.remoteSong = -1
@ -275,6 +278,7 @@ class SongMediaItem(MediaManagerItem):
the Song Id in the payload along with an indicator to say which
type of display is required.
"""
log.debug(u'onRemoteEdit %s' % songid)
fields = songid.split(u':')
valid = self.parent.manager.get_object(Song, fields[1])
if valid:
@ -287,6 +291,7 @@ class SongMediaItem(MediaManagerItem):
"""
Edit a song
"""
log.debug(u'onEditClick')
if check_item_selected(self.listView,
translate('SongsPlugin.MediaItem',
'You must select an item to edit.')):
@ -324,6 +329,7 @@ class SongMediaItem(MediaManagerItem):
self.onSearchTextButtonClick()
def generateSlideData(self, service_item, item=None):
log.debug(u'generateSlideData (%s:%s)' % (service_item, item))
raw_footer = []
author_list = u''
author_audit = []
@ -345,7 +351,7 @@ class SongMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.AddIfNewItem)
song = self.parent.manager.get_object(Song, item_id)
service_item.theme = song.theme_name
service_item.editId = item_id
service_item.edit_id = item_id
if song.lyrics.startswith(u'<?xml version='):
songXML = SongXMLParser(song.lyrics)
verseList = songXML.get_verses()
@ -357,7 +363,7 @@ class SongMediaItem(MediaManagerItem):
service_item.add_from_text(
verse[1][:30], unicode(verse[1]), verseTag)
else:
#Loop through the verse list and expand the song accordingly.
# Loop through the verse list and expand the song accordingly.
for order in song.verse_order.upper().split(u' '):
if len(order) == 0:
break
@ -397,12 +403,13 @@ class SongMediaItem(MediaManagerItem):
"""
Triggered by a song being loaded by the service item
"""
log.debug(u'serviceLoad')
if item.data_string:
search_results = self.parent.manager.get_all_objects(Song,
Song.search_title.like(u'%' +
item.data_string[u'title'].split(u'@')[0] + u'%'),
Song.search_title.asc())
author_list = item.data_string[u'authors'].split(u',')
author_list = item.data_string[u'authors'].split(u', ')
editId = 0
uuid = 0
if search_results:
@ -417,4 +424,3 @@ class SongMediaItem(MediaManagerItem):
if editId != 0:
Receiver.send_message(u'service_item_update',
u'%s:%s' %(editId, uuid))

View File

@ -25,6 +25,7 @@
###############################################################################
import logging
import re
from PyQt4 import QtCore, QtGui
@ -55,6 +56,7 @@ class SongsPlugin(Plugin):
self.manager = Manager(u'songs', init_schema)
self.icon_path = u':/plugins/plugin_songs.png'
self.icon = build_icon(self.icon_path)
self.whitespace = re.compile(r'\W+')
def getSettingsTab(self):
visible_name = self.getString(StringContent.VisibleName)
@ -63,6 +65,7 @@ class SongsPlugin(Plugin):
def initialise(self):
log.info(u'Songs Initialising')
Plugin.initialise(self)
self.toolsReindexItem.setVisible(True)
self.mediaItem.displayResultsSong(
self.manager.get_all_objects(Song, order_by_ref=Song.search_title))
@ -106,6 +109,57 @@ class SongsPlugin(Plugin):
# No menu items for now.
pass
def addToolsMenuItem(self, tools_menu):
"""
Give the alerts plugin the opportunity to add items to the
**Tools** menu.
``tools_menu``
The actual **Tools** menu item, so that your actions can
use it as their parent.
"""
log.info(u'add tools menu')
self.toolsReindexItem = QtGui.QAction(tools_menu)
self.toolsReindexItem.setIcon(build_icon(u':/plugins/plugin_songs.png'))
self.toolsReindexItem.setObjectName(u'toolsReindexItem')
self.toolsReindexItem.setText(
translate('SongsPlugin', '&Re-index Songs'))
self.toolsReindexItem.setStatusTip(
translate('SongsPlugin', 'Re-index the songs database to improve '
'searching and ordering.'))
tools_menu.addAction(self.toolsReindexItem)
QtCore.QObject.connect(self.toolsReindexItem,
QtCore.SIGNAL(u'triggered()'), self.onToolsReindexItemTriggered)
self.toolsReindexItem.setVisible(False)
def onToolsReindexItemTriggered(self):
"""
Rebuild the search title of each song.
"""
maxSongs = self.manager.get_object_count(Song)
progressDialog = QtGui.QProgressDialog(
translate('SongsPlugin', 'Reindexing songs...'),
translate('SongsPlugin', 'Cancel'),
0, maxSongs + 1, self.formparent)
progressDialog.setWindowModality(QtCore.Qt.WindowModal)
songs = self.manager.get_all_objects(Song)
counter = 0
for song in songs:
counter += 1
if song.title is None:
song.title = u''
if song.alternate_title is None:
song.alternate_title = u''
song.search_title = self.whitespace.sub(u' ', \
song.title.lower()) + u' ' + \
self.whitespace.sub(u' ', song.alternate_title.lower())
progressDialog.setValue(counter)
self.manager.save_objects(songs)
counter += 1
progressDialog.setValue(counter)
self.mediaItem.displayResultsSong(
self.manager.get_all_objects(Song, order_by_ref=Song.search_title))
def onSongImportItemClicked(self):
if self.mediaItem:
self.mediaItem.onImportClick()
@ -206,4 +260,6 @@ class SongsPlugin(Plugin):
"""
log.info(u'Songs Finalising')
self.manager.finalise()
self.toolsReindexItem.setVisible(False)
Plugin.finalise(self)

File diff suppressed because it is too large Load Diff

View File

@ -83,6 +83,8 @@
<file>wizard_importbible.bmp</file>
</qresource>
<qresource prefix="services">
<file>service_collapse_all.png</file>
<file>service_expand_all.png</file>
<file>service_notes.png</file>
<file>service_item_notes.png</file>
<file>service_bottom.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B