HEAD 1127

This commit is contained in:
M2j 2010-12-08 09:25:28 +01:00
commit 3ad231940c
69 changed files with 3944 additions and 2847 deletions

View File

@ -48,7 +48,7 @@ Service Manger
-------------- --------------
The service manager contains the media items in your service file. This is the 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. services files.
.. image:: pics/servicemanager.png .. image:: pics/servicemanager.png

View File

@ -14,6 +14,8 @@ Contents:
introduction introduction
glossary glossary
dualmonitors dualmonitors
mediamanager
songs
Indices and tables 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 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

@ -38,48 +38,51 @@ log = logging.getLogger(__name__)
# TODO make external and configurable in alpha 4 via a settings dialog # TODO make external and configurable in alpha 4 via a settings dialog
html_expands = [] html_expands = []
html_expands.append({u'desc':u'Red', u'start tag':u'{r}', html_expands.append({u'desc': u'Red', u'start tag': u'{r}',
u'start html':u'<span style="-webkit-text-fill-color:red">', u'start html': u'<span style="-webkit-text-fill-color:red">',
u'end tag':u'{/r}', u'end html':u'</span>', u'protected':False}) u'end tag': u'{/r}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc':u'Black', u'start tag':u'{b}', html_expands.append({u'desc': u'Black', u'start tag': u'{b}',
u'start html':u'<span style="-webkit-text-fill-color:black">', u'start html': u'<span style="-webkit-text-fill-color:black">',
u'end tag':u'{/b}', u'end html':u'</span>', u'protected':False}) u'end tag': u'{/b}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc':u'Blue', u'start tag':u'{bl}', html_expands.append({u'desc': u'Blue', u'start tag': u'{bl}',
u'start html':u'<span style="-webkit-text-fill-color:blue">', u'start html': u'<span style="-webkit-text-fill-color:blue">',
u'end tag':u'{/bl}', u'end html':u'</span>', u'protected':False}) u'end tag': u'{/bl}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc':u'Yellow', u'start tag':u'{y}', html_expands.append({u'desc': u'Yellow', u'start tag': u'{y}',
u'start html':u'<span style="-webkit-text-fill-color:yellow">', u'start html': u'<span style="-webkit-text-fill-color:yellow">',
u'end tag':u'{/y}', u'end html':u'</span>', u'protected':False}) u'end tag': u'{/y}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc':u'Green', u'start tag':u'{g}', html_expands.append({u'desc': u'Green', u'start tag': u'{g}',
u'start html':u'<span style="-webkit-text-fill-color:green">', u'start html': u'<span style="-webkit-text-fill-color:green">',
u'end tag':u'{/g}', u'end html':u'</span>', u'protected':False}) u'end tag': u'{/g}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc':u'Pink', u'start tag':u'{pk}', html_expands.append({u'desc': u'Pink', u'start tag': u'{pk}',
u'start html':u'<span style="-webkit-text-fill-color:#CC33CC">', u'start html': u'<span style="-webkit-text-fill-color:#CC33CC">',
u'end tag':u'{/pk}', u'end html':u'</span>', u'protected':False}) u'end tag': u'{/pk}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc':u'Orange', u'start tag':u'{o}', html_expands.append({u'desc': u'Orange', u'start tag': u'{o}',
u'start html':u'<span style="-webkit-text-fill-color:#CC0033">', u'start html': u'<span style="-webkit-text-fill-color:#CC0033">',
u'end tag':u'{/o}', u'end html':u'</span>', u'protected':False}) u'end tag': u'{/o}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc':u'Purple', u'start tag':u'{pp}', html_expands.append({u'desc': u'Purple', u'start tag': u'{pp}',
u'start html':u'<span style="-webkit-text-fill-color:#9900FF">', u'start html': u'<span style="-webkit-text-fill-color:#9900FF">',
u'end tag':u'{/pp}', u'end html':u'</span>', u'protected':False}) u'end tag': u'{/pp}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc':u'White', u'start tag':u'{w}', html_expands.append({u'desc': u'White', u'start tag': u'{w}',
u'start html':u'<span style="-webkit-text-fill-color:white">', u'start html': u'<span style="-webkit-text-fill-color:white">',
u'end tag':u'{/w}', u'end html':u'</span>', u'protected':False}) u'end tag': u'{/w}', u'end html': u'</span>', u'protected': False})
html_expands.append({u'desc':u'Superscript', u'start tag':u'{su}', html_expands.append({u'desc': u'Superscript', u'start tag': u'{su}',
u'start html':u'<sup>', u'end tag':u'{/su}', u'end html':u'</sup>', u'start html': u'<sup>', u'end tag': u'{/su}', u'end html': u'</sup>',
u'protected':True}) u'protected': True})
html_expands.append({u'desc':u'Subscript', u'start tag':u'{sb}', html_expands.append({u'desc': u'Subscript', u'start tag': u'{sb}',
u'start html':u'<sub>', u'end tag':u'{/sb}', u'end html':u'</sub>', u'start html': u'<sub>', u'end tag': u'{/sb}', u'end html': u'</sub>',
u'protected':True}) u'protected': True})
html_expands.append({u'desc':u'Paragraph', u'start tag':u'{p}', html_expands.append({u'desc': u'Paragraph', u'start tag': u'{p}',
u'start html':u'<p>', u'end tag':u'{/p}', u'end html':u'</p>', u'start html': u'<p>', u'end tag': u'{/p}', u'end html': u'</p>',
u'protected':True}) u'protected': True})
html_expands.append({u'desc':u'Bold', u'start tag':u'{st}', html_expands.append({u'desc': u'Bold', u'start tag': u'{st}',
u'start html':u'<strong>', u'end tag':u'{/st}', u'end html':u'</strong>', u'start html': u'<strong>', u'end tag': u'{/st}', u'end html': u'</strong>',
u'protected':True}) u'protected': True})
html_expands.append({u'desc':u'Italics', u'start tag':u'{it}', html_expands.append({u'desc': u'Italics', u'start tag': u'{it}',
u'start html':u'<em>', u'end tag':u'{/it}', u'end html':u'</em>', u'start html': u'<em>', u'end tag': u'{/it}', u'end html': u'</em>',
u'protected':True}) u'protected': True})
html_expands.append({u'desc': u'Underline', u'start tag': u'{u}',
u'start html': u'<span style="text-decoration: underline;">',
u'end tag': u'{/u}', u'end html': u'</span>', u'protected': True})
def translate(context, text, comment=None): def translate(context, text, comment=None):
""" """
@ -303,6 +306,8 @@ def expand_tags(text):
text = text.replace(tag[u'end tag'], tag[u'end html']) text = text.replace(tag[u'end tag'], tag[u'end html'])
return text return text
from theme import ThemeLevel, ThemeXML, BackgroundGradientType, \
BackgroundType, HorizontalType, VerticalType
from spelltextedit import SpellTextEdit from spelltextedit import SpellTextEdit
from eventreceiver import Receiver from eventreceiver import Receiver
from imagemanager import ImageManager from imagemanager import ImageManager
@ -317,7 +322,6 @@ from htmlbuilder import build_html, build_lyrics_format_css, \
build_lyrics_outline_css build_lyrics_outline_css
from toolbar import OpenLPToolbar from toolbar import OpenLPToolbar
from dockwidget import OpenLPDockWidget from dockwidget import OpenLPDockWidget
from theme import ThemeLevel, ThemeXML
from renderer import Renderer from renderer import Renderer
from rendermanager import RenderManager from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem from mediamanageritem import MediaManagerItem

View File

@ -158,6 +158,27 @@ class Manager(object):
log.exception(u'Object save failed') log.exception(u'Object save failed')
return False 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): def get_object(self, object_class, key=None):
""" """
Return the details of an object Return the details of an object
@ -207,6 +228,22 @@ class Manager(object):
return query.order_by(order_by_ref).all() return query.order_by(order_by_ref).all()
return query.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): def delete_object(self, object_class, key):
""" """
Delete an object from the database Delete an object from the database
@ -257,4 +294,5 @@ class Manager(object):
""" """
if self.is_dirty: if self.is_dirty:
engine = create_engine(self.db_url) engine = create_engine(self.db_url)
engine.execute("vacuum") if self.db_url.startswith(u'sqlite'):
engine.execute("vacuum")

View File

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

View File

@ -46,13 +46,13 @@ class ImageThread(QtCore.QThread):
""" """
def __init__(self, manager): def __init__(self, manager):
QtCore.QThread.__init__(self, None) QtCore.QThread.__init__(self, None)
self.image_mamager = manager self.imageManager = manager
def run(self): def run(self):
""" """
Run the thread. Run the thread.
""" """
self.image_mamager.process() self.imageManager.process()
class Image(object): class Image(object):

View File

@ -320,15 +320,9 @@ class MediaManagerItem(QtGui.QWidget):
translate('OpenLP.MediaManagerItem', translate('OpenLP.MediaManagerItem',
'&Add to selected Service Item'), '&Add to selected Service Item'),
self.onAddEditClick)) self.onAddEditClick))
if QtCore.QSettings().value(u'advanced/double click live', QtCore.QObject.connect(self.listView,
QtCore.QVariant(False)).toBool(): QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
QtCore.QObject.connect(self.listView, self.onClickPressed)
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onLiveClick)
else:
QtCore.QObject.connect(self.listView,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
self.onPreviewClick)
def initialise(self): def initialise(self):
""" """
@ -426,10 +420,20 @@ class MediaManagerItem(QtGui.QWidget):
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to ' raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to '
u'be defined by the plugin') u'be defined by the plugin')
def generateSlideData(self, service_item, item=None): def generateSlideData(self, serviceItem, item=None, xmlVersion=False):
raise NotImplementedError(u'MediaManagerItem.generateSlideData needs ' raise NotImplementedError(u'MediaManagerItem.generateSlideData needs '
u'to be defined by the plugin') u'to be defined by the plugin')
def onClickPressed(self):
"""
Allows the list click action to be determined dynamically
"""
if QtCore.QSettings().value(u'advanced/double click live',
QtCore.QVariant(False)).toBool():
self.onLiveClick()
else:
self.onPreviewClick()
def onPreviewClick(self): def onPreviewClick(self):
""" """
Preview an item by building a service item then adding that service Preview an item by building a service item then adding that service
@ -442,10 +446,10 @@ class MediaManagerItem(QtGui.QWidget):
'You must select one or more items to preview.')) 'You must select one or more items to preview.'))
else: else:
log.debug(self.plugin.name + u' Preview requested') log.debug(self.plugin.name + u' Preview requested')
service_item = self.buildServiceItem() serviceItem = self.buildServiceItem()
if service_item: if serviceItem:
service_item.from_plugin = True serviceItem.from_plugin = True
self.parent.previewController.addServiceItem(service_item) self.parent.previewController.addServiceItem(serviceItem)
def onLiveClick(self): def onLiveClick(self):
""" """
@ -459,10 +463,10 @@ class MediaManagerItem(QtGui.QWidget):
'You must select one or more items to send live.')) 'You must select one or more items to send live.'))
else: else:
log.debug(self.plugin.name + u' Live requested') log.debug(self.plugin.name + u' Live requested')
service_item = self.buildServiceItem() serviceItem = self.buildServiceItem()
if service_item: if serviceItem:
service_item.from_plugin = True serviceItem.from_plugin = True
self.parent.liveController.addServiceItem(service_item) self.parent.liveController.addServiceItem(serviceItem)
def onAddClick(self): def onAddClick(self):
""" """
@ -474,22 +478,22 @@ class MediaManagerItem(QtGui.QWidget):
translate('OpenLP.MediaManagerItem', translate('OpenLP.MediaManagerItem',
'You must select one or more items.')) 'You must select one or more items.'))
else: else:
# Is it posssible to process multiple list items to generate multiple # Is it posssible to process multiple list items to generate
# service items? # multiple service items?
if self.singleServiceItem or self.remoteTriggered: if self.singleServiceItem or self.remoteTriggered:
log.debug(self.plugin.name + u' Add requested') log.debug(self.plugin.name + u' Add requested')
service_item = self.buildServiceItem() serviceItem = self.buildServiceItem(None, True)
if service_item: if serviceItem:
service_item.from_plugin = False serviceItem.from_plugin = False
self.parent.serviceManager.addServiceItem(service_item, self.parent.serviceManager.addServiceItem(serviceItem,
replace=self.remoteTriggered) replace=self.remoteTriggered)
else: else:
items = self.listView.selectedIndexes() items = self.listView.selectedIndexes()
for item in items: for item in items:
service_item = self.buildServiceItem(item) serviceItem = self.buildServiceItem(item, True)
if service_item: if serviceItem:
service_item.from_plugin = False serviceItem.from_plugin = False
self.parent.serviceManager.addServiceItem(service_item) self.parent.serviceManager.addServiceItem(serviceItem)
def onAddEditClick(self): def onAddEditClick(self):
""" """
@ -502,36 +506,36 @@ class MediaManagerItem(QtGui.QWidget):
'You must select one or more items')) 'You must select one or more items'))
else: else:
log.debug(self.plugin.name + u' Add requested') log.debug(self.plugin.name + u' Add requested')
service_item = self.parent.serviceManager.getServiceItem() serviceItem = self.parent.serviceManager.getServiceItem()
if not service_item: if not serviceItem:
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
translate('OpenLP.MediaManagerItem', translate('OpenLP.MediaManagerItem',
'No Service Item Selected'), 'No Service Item Selected'),
translate('OpenLP.MediaManagerItem', translate('OpenLP.MediaManagerItem',
'You must select an existing service item to add to.')) 'You must select an existing service item to add to.'))
elif self.title.lower() == service_item.name.lower(): elif self.title.lower() == serviceItem.name.lower():
self.generateSlideData(service_item) self.generateSlideData(serviceItem)
self.parent.serviceManager.addServiceItem(service_item, self.parent.serviceManager.addServiceItem(serviceItem,
replace=True) replace=True)
else: else:
#Turn off the remote edit update message indicator # Turn off the remote edit update message indicator
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
translate('OpenLP.MediaManagerItem', translate('OpenLP.MediaManagerItem',
'Invalid Service Item'), 'Invalid Service Item'),
unicode(translate('OpenLP.MediaManagerItem', unicode(translate('OpenLP.MediaManagerItem',
'You must select a %s service item.')) % self.title) 'You must select a %s service item.')) % self.title)
def buildServiceItem(self, item=None): def buildServiceItem(self, item=None, xmlVersion=False):
""" """
Common method for generating a service item Common method for generating a service item
""" """
service_item = ServiceItem(self.parent) serviceItem = ServiceItem(self.parent)
if self.serviceItemIconName: if self.serviceItemIconName:
service_item.add_icon(self.serviceItemIconName) serviceItem.add_icon(self.serviceItemIconName)
else: else:
service_item.add_icon(self.parent.icon_path) serviceItem.add_icon(self.parent.icon_path)
if self.generateSlideData(service_item, item): if self.generateSlideData(serviceItem, item, xmlVersion):
return service_item return serviceItem
else: else:
return None return None

View File

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

View File

@ -67,8 +67,9 @@ class RenderManager(object):
self.service_theme = u'' self.service_theme = u''
self.theme_level = u'' self.theme_level = u''
self.override_background = None self.override_background = None
self.themedata = None self.theme_data = None
self.alertTab = None self.alertTab = None
self.force_page = False
def update_display(self): def update_display(self):
""" """
@ -80,7 +81,7 @@ class RenderManager(object):
self.display.imageManager = self.image_manager self.display.imageManager = self.image_manager
self.display.setup() self.display.setup()
self.renderer.bg_frame = None self.renderer.bg_frame = None
self.themedata = None self.theme_data = None
self.image_manager.update_display(self.width, self.height) self.image_manager.update_display(self.width, self.height)
def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global): def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global):
@ -99,7 +100,7 @@ class RenderManager(object):
self.theme_level = theme_level self.theme_level = theme_level
self.global_theme_data = \ self.global_theme_data = \
self.theme_manager.getThemeData(self.global_theme) self.theme_manager.getThemeData(self.global_theme)
self.themedata = None self.theme_data = None
def set_service_theme(self, service_theme): def set_service_theme(self, service_theme):
""" """
@ -109,7 +110,7 @@ class RenderManager(object):
The service-level theme to be set. The service-level theme to be set.
""" """
self.service_theme = service_theme self.service_theme = service_theme
self.themedata = None self.theme_data = None
def set_override_theme(self, theme, overrideLevels=False): def set_override_theme(self, theme, overrideLevels=False):
""" """
@ -146,19 +147,19 @@ class RenderManager(object):
self.theme = self.service_theme self.theme = self.service_theme
else: else:
self.theme = self.global_theme 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: or overrideLevels:
log.debug(u'theme is now %s', self.theme) log.debug(u'theme is now %s', self.theme)
# Force the theme to be the one passed in. # Force the theme to be the one passed in.
if overrideLevels: if overrideLevels:
self.themedata = theme self.theme_data = theme
else: 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.calculate_default(self.screens.current[u'size'])
self.renderer.set_theme(self.themedata) self.renderer.set_theme(self.theme_data)
self.build_text_rectangle(self.themedata) self.build_text_rectangle(self.theme_data)
self.image_manager.add_image(self.themedata.theme_name, self.image_manager.add_image(self.theme_data.theme_name,
self.themedata.background_filename) self.theme_data.background_filename)
return self.renderer._rect, self.renderer._rect_footer return self.renderer._rect, self.renderer._rect_footer
def build_text_rectangle(self, theme): def build_text_rectangle(self, theme):
@ -187,14 +188,19 @@ class RenderManager(object):
theme.font_footer_height - 1) theme.font_footer_height - 1)
self.renderer.set_text_rectangle(main_rect, footer_rect) 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. Generate a preview of a theme.
``themedata`` ``theme_data``
The theme to generated a preview for. 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') log.debug(u'generate preview')
# save value for use in format_slide
self.force_page = force_page
# set the default image size for previews # set the default image size for previews
self.calculate_default(self.screens.preview[u'size']) self.calculate_default(self.screens.preview[u'size'])
verse = u'The Lord said to {r}Noah{/r}: \n' \ 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' \ '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}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' '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 = []
footer.append(u'Arky Arky (Unknown)' ) footer.append(u'Arky Arky (Unknown)' )
footer.append(u'Public Domain') footer.append(u'Public Domain')
footer.append(u'CCLI 123456') footer.append(u'CCLI 123456')
# build a service item to generate preview # build a service item to generate preview
serviceItem = ServiceItem() serviceItem = ServiceItem()
serviceItem.theme = themedata serviceItem.theme = theme_data
serviceItem.add_from_text(u'', verse, footer) serviceItem.add_from_text(u'', verse, footer)
serviceItem.render_manager = self serviceItem.render_manager = self
serviceItem.raw_footer = footer serviceItem.raw_footer = footer
serviceItem.render(True) serviceItem.render(True)
self.display.buildHtml(serviceItem) if not self.force_page:
raw_html = serviceItem.get_rendered_frame(0) self.display.buildHtml(serviceItem)
preview = self.display.text(raw_html) raw_html = serviceItem.get_rendered_frame(0)
# Reset the real screen size for subsequent render requests preview = self.display.text(raw_html)
self.calculate_default(self.screens.current[u'size']) # Reset the real screen size for subsequent render requests
return preview self.calculate_default(self.screens.current[u'size'])
return preview
def format_slide(self, words, line_break): def format_slide(self, words, line_break):
""" """
@ -228,9 +238,12 @@ class RenderManager(object):
``words`` ``words``
The words to go on the slides. 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') 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): def calculate_default(self, screen):
""" """

View File

@ -100,6 +100,8 @@ class ServiceItem(object):
self.bg_image_bytes = None self.bg_image_bytes = None
self.search_string = u'' self.search_string = u''
self.data_string = u'' self.data_string = u''
self.edit_id = None
self.xml_version = None
self._new_item() self._new_item()
def _new_item(self): def _new_item(self):
@ -251,7 +253,8 @@ class ServiceItem(object):
u'from_plugin': self.from_plugin, u'from_plugin': self.from_plugin,
u'capabilities': self.capabilities, u'capabilities': self.capabilities,
u'search': self.search_string, u'search': self.search_string,
u'data': self.data_string u'data': self.data_string,
u'xml_version': self.xml_version
} }
service_data = [] service_data = []
if self.service_item_type == ServiceItemType.Text: if self.service_item_type == ServiceItemType.Text:
@ -293,6 +296,8 @@ class ServiceItem(object):
if u'search' in header: if u'search' in header:
self.search_string = header[u'search'] self.search_string = header[u'search']
self.data_string = header[u'data'] self.data_string = header[u'data']
if u'xml_version' in header:
self.xml_version = header[u'xml_version']
if self.service_item_type == ServiceItemType.Text: if self.service_item_type == ServiceItemType.Text:
for slide in serviceitem[u'serviceitem'][u'data']: for slide in serviceitem[u'serviceitem'][u'data']:
self._raw_frames.append(slide) self._raw_frames.append(slide)

View File

@ -87,8 +87,12 @@ class SettingsTab(QtGui.QWidget):
""" """
pass pass
def postSetUp(self): def postSetUp(self, postUpdate=False):
""" """
Changes which need to be made after setup of application Changes which need to be made after setup of application
``postUpdate``
Indicates if called before or after updates.
""" """
pass pass

View File

@ -33,12 +33,15 @@ except ImportError:
enchant_available = False enchant_available = False
# based on code from # based on code from
# http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/ # http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import html_expands, translate from openlp.core.lib import html_expands, translate
class SpellTextEdit(QtGui.QPlainTextEdit): class SpellTextEdit(QtGui.QPlainTextEdit):
"""
Spell checking widget based on QPlanTextEdit.
"""
def __init__(self, *args): def __init__(self, *args):
QtGui.QPlainTextEdit.__init__(self, *args) QtGui.QPlainTextEdit.__init__(self, *args)
# Default dictionary based on the current locale. # Default dictionary based on the current locale.
@ -60,7 +63,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
QtGui.QPlainTextEdit.mousePressEvent(self, event) QtGui.QPlainTextEdit.mousePressEvent(self, event)
def contextMenuEvent(self, event): def contextMenuEvent(self, event):
popup_menu = self.createStandardContextMenu() popupMenu = self.createStandardContextMenu()
# Select the word under the cursor. # Select the word under the cursor.
cursor = self.textCursor() cursor = self.textCursor()
# only select text if not already selected # only select text if not already selected
@ -81,17 +84,17 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
# Only add the spelling suggests to the menu if there are # Only add the spelling suggests to the menu if there are
# suggestions. # suggestions.
if len(spell_menu.actions()) != 0: if len(spell_menu.actions()) != 0:
popup_menu.insertSeparator(popup_menu.actions()[0]) popupMenu.insertSeparator(popupMenu.actions()[0])
popup_menu.insertMenu(popup_menu.actions()[0], spell_menu) popupMenu.insertMenu(popupMenu.actions()[0], spell_menu)
tag_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit', tagMenu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
'Formatting Tags')) 'Formatting Tags'))
for html in html_expands: for html in html_expands:
action = SpellAction( html[u'desc'], tag_menu) action = SpellAction( html[u'desc'], tagMenu)
action.correct.connect(self.htmlTag) action.correct.connect(self.htmlTag)
tag_menu.addAction(action) tagMenu.addAction(action)
popup_menu.insertSeparator(popup_menu.actions()[0]) popupMenu.insertSeparator(popupMenu.actions()[0])
popup_menu.insertMenu(popup_menu.actions()[0], tag_menu) popupMenu.insertMenu(popupMenu.actions()[0], tagMenu)
popup_menu.exec_(event.globalPos()) popupMenu.exec_(event.globalPos())
def correctWord(self, word): def correctWord(self, word):
""" """

View File

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

View File

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

View File

@ -81,6 +81,10 @@ class AdvancedTab(SettingsTab):
self.doubleClickLiveCheckBox = QtGui.QCheckBox(self.uiGroupBox) self.doubleClickLiveCheckBox = QtGui.QCheckBox(self.uiGroupBox)
self.doubleClickLiveCheckBox.setObjectName(u'doubleClickLiveCheckBox') self.doubleClickLiveCheckBox.setObjectName(u'doubleClickLiveCheckBox')
self.uiLayout.addWidget(self.doubleClickLiveCheckBox) self.uiLayout.addWidget(self.doubleClickLiveCheckBox)
# self.expandServiceItemCheckBox = QtGui.QCheckBox(self.uiGroupBox)
# self.expandServiceItemCheckBox.setObjectName(
# u'expandServiceItemCheckBox')
# self.uiLayout.addWidget(self.expandServiceItemCheckBox)
self.leftLayout.addWidget(self.uiGroupBox) self.leftLayout.addWidget(self.uiGroupBox)
self.expandServiceItemCheckBox = QtGui.QCheckBox(self.uiGroupBox) self.expandServiceItemCheckBox = QtGui.QCheckBox(self.uiGroupBox)
self.expandServiceItemCheckBox.setObjectName( self.expandServiceItemCheckBox.setObjectName(
@ -143,7 +147,7 @@ class AdvancedTab(SettingsTab):
self.mediaPluginCheckBox.setText(translate('OpenLP.AdvancedTab', self.mediaPluginCheckBox.setText(translate('OpenLP.AdvancedTab',
'Remember active media manager tab on startup')) 'Remember active media manager tab on startup'))
self.doubleClickLiveCheckBox.setText(translate('OpenLP.AdvancedTab', self.doubleClickLiveCheckBox.setText(translate('OpenLP.AdvancedTab',
'Double-click to send items straight to live (requires restart)')) 'Double-click to send items straight to live'))
self.expandServiceItemCheckBox.setText(translate('OpenLP.AdvancedTab', self.expandServiceItemCheckBox.setText(translate('OpenLP.AdvancedTab',
'Expand new service items on creation')) 'Expand new service items on creation'))
# self.sharedDirGroupBox.setTitle( # self.sharedDirGroupBox.setTitle(

View File

@ -1,799 +0,0 @@
# -*- 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 build_icon, translate
class Ui_AmendThemeDialog(object):
def setupUi(self, amendThemeDialog):
amendThemeDialog.setObjectName(u'amendThemeDialog')
amendThemeDialog.setWindowModality(QtCore.Qt.ApplicationModal)
amendThemeDialog.resize(586, 651)
icon = build_icon(u':/icon/openlp-logo-16x16.png')
amendThemeDialog.setWindowIcon(icon)
amendThemeDialog.setModal(True)
self.amendThemeLayout = QtGui.QVBoxLayout(amendThemeDialog)
self.amendThemeLayout.setSpacing(8)
self.amendThemeLayout.setMargin(8)
self.amendThemeLayout.setObjectName(u'amendThemeLayout')
self.themeNameWidget = QtGui.QWidget(amendThemeDialog)
self.themeNameWidget.setObjectName(u'themeNameWidget')
self.themeNameLayout = QtGui.QHBoxLayout(self.themeNameWidget)
self.themeNameLayout.setSpacing(8)
self.themeNameLayout.setMargin(0)
self.themeNameLayout.setObjectName(u'themeNameLayout')
self.themeNameLabel = QtGui.QLabel(self.themeNameWidget)
self.themeNameLabel.setObjectName(u'themeNameLabel')
self.themeNameLayout.addWidget(self.themeNameLabel)
self.themeNameEdit = QtGui.QLineEdit(self.themeNameWidget)
self.themeNameEdit.setObjectName(u'themeNameEdit')
self.themeNameLabel.setBuddy(self.themeNameEdit)
self.themeNameLayout.addWidget(self.themeNameEdit)
self.amendThemeLayout.addWidget(self.themeNameWidget)
self.contentWidget = QtGui.QWidget(amendThemeDialog)
self.contentWidget.setObjectName(u'contentWidget')
self.contentLayout = QtGui.QHBoxLayout(self.contentWidget)
self.contentLayout.setSpacing(8)
self.contentLayout.setMargin(0)
self.contentLayout.setObjectName(u'contentLayout')
self.themeTabWidget = QtGui.QTabWidget(self.contentWidget)
self.themeTabWidget.setObjectName(u'themeTabWidget')
self.backgroundTab = QtGui.QWidget()
self.backgroundTab.setObjectName(u'backgroundTab')
self.backgroundLayout = QtGui.QFormLayout(self.backgroundTab)
self.backgroundLayout.setMargin(8)
self.backgroundLayout.setSpacing(8)
self.backgroundLayout.setObjectName(u'backgroundLayout')
self.backgroundTypeLabel = QtGui.QLabel(self.backgroundTab)
self.backgroundTypeLabel.setObjectName(u'backgroundTypeLabel')
self.backgroundLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.backgroundTypeLabel)
self.backgroundTypeComboBox = QtGui.QComboBox(self.backgroundTab)
self.backgroundTypeComboBox.setObjectName(u'backgroundTypeComboBox')
self.backgroundTypeComboBox.addItem(QtCore.QString())
self.backgroundTypeComboBox.addItem(QtCore.QString())
self.backgroundTypeComboBox.addItem(QtCore.QString())
self.backgroundLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.backgroundTypeComboBox)
self.color1Label = QtGui.QLabel(self.backgroundTab)
self.color1Label.setObjectName(u'color1Label')
self.backgroundLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.color1Label)
self.color1PushButton = QtGui.QPushButton(self.backgroundTab)
self.color1PushButton.setObjectName(u'color1PushButton')
self.backgroundLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.color1PushButton)
self.color2Label = QtGui.QLabel(self.backgroundTab)
self.color2Label.setObjectName(u'color2Label')
self.backgroundLayout.setWidget(3, QtGui.QFormLayout.LabelRole,
self.color2Label)
self.color2PushButton = QtGui.QPushButton(self.backgroundTab)
self.color2PushButton.setObjectName(u'color2PushButton')
self.backgroundLayout.setWidget(3, QtGui.QFormLayout.FieldRole,
self.color2PushButton)
self.imageLabel = QtGui.QLabel(self.backgroundTab)
self.imageLabel.setObjectName(u'imageLabel')
self.backgroundLayout.setWidget(4, QtGui.QFormLayout.LabelRole,
self.imageLabel)
self.gradientLabel = QtGui.QLabel(self.backgroundTab)
self.gradientLabel.setObjectName(u'gradientLabel')
self.backgroundLayout.setWidget(6, QtGui.QFormLayout.LabelRole,
self.gradientLabel)
self.gradientComboBox = QtGui.QComboBox(self.backgroundTab)
self.gradientComboBox.setObjectName(u'gradientComboBox')
self.gradientComboBox.addItem(QtCore.QString())
self.gradientComboBox.addItem(QtCore.QString())
self.gradientComboBox.addItem(QtCore.QString())
self.backgroundLayout.setWidget(6, QtGui.QFormLayout.FieldRole,
self.gradientComboBox)
self.imageFilenameWidget = QtGui.QWidget(self.backgroundTab)
self.imageFilenameWidget.setObjectName(u'imageFilenameWidget')
self.horizontalLayout2 = QtGui.QHBoxLayout(self.imageFilenameWidget)
self.horizontalLayout2.setSpacing(0)
self.horizontalLayout2.setMargin(0)
self.horizontalLayout2.setObjectName(u'horizontalLayout2')
self.imageLineEdit = QtGui.QLineEdit(self.imageFilenameWidget)
self.imageLineEdit.setObjectName(u'imageLineEdit')
self.horizontalLayout2.addWidget(self.imageLineEdit)
self.imageToolButton = QtGui.QToolButton(self.imageFilenameWidget)
self.imageToolButton.setIcon(build_icon(u':/general/general_open.png'))
self.imageToolButton.setObjectName(u'imageToolButton')
self.imageToolButton.setAutoRaise(True)
self.horizontalLayout2.addWidget(self.imageToolButton)
self.backgroundLayout.setWidget(4, QtGui.QFormLayout.FieldRole,
self.imageFilenameWidget)
self.themeTabWidget.addTab(self.backgroundTab, u'')
self.fontMainTab = QtGui.QWidget()
self.fontMainTab.setObjectName(u'fontMainTab')
self.fontMainLayout = QtGui.QHBoxLayout(self.fontMainTab)
self.fontMainLayout.setSpacing(8)
self.fontMainLayout.setMargin(8)
self.fontMainLayout.setObjectName(u'fontMainLayout')
self.mainLeftWidget = QtGui.QWidget(self.fontMainTab)
self.mainLeftWidget.setObjectName(u'mainLeftWidget')
self.mainLeftLayout = QtGui.QVBoxLayout(self.mainLeftWidget)
self.mainLeftLayout.setSpacing(8)
self.mainLeftLayout.setMargin(0)
self.mainLeftLayout.setObjectName(u'mainLeftLayout')
self.fontMainGroupBox = QtGui.QGroupBox(self.mainLeftWidget)
self.fontMainGroupBox.setObjectName(u'fontMainGroupBox')
self.mainFontLayout = QtGui.QFormLayout(self.fontMainGroupBox)
self.mainFontLayout.setFormAlignment(QtCore.Qt.AlignLeading |
QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.mainFontLayout.setMargin(8)
self.mainFontLayout.setSpacing(8)
self.mainFontLayout.setObjectName(u'mainFontLayout')
self.fontMainlabel = QtGui.QLabel(self.fontMainGroupBox)
self.fontMainlabel.setObjectName(u'fontMainlabel')
self.mainFontLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.fontMainlabel)
self.fontMainComboBox = QtGui.QFontComboBox(self.fontMainGroupBox)
self.fontMainComboBox.setObjectName(u'fontMainComboBox')
self.mainFontLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.fontMainComboBox)
self.fontMainColorLabel = QtGui.QLabel(self.fontMainGroupBox)
self.fontMainColorLabel.setObjectName(u'fontMainColorLabel')
self.mainFontLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.fontMainColorLabel)
self.fontMainColorPushButton = QtGui.QPushButton(self.fontMainGroupBox)
self.fontMainColorPushButton.setObjectName(u'fontMainColorPushButton')
self.mainFontLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.fontMainColorPushButton)
self.fontMainSize = QtGui.QLabel(self.fontMainGroupBox)
self.fontMainSize.setObjectName(u'fontMainSize')
self.mainFontLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.fontMainSize)
self.fontMainSizeSpinBox = QtGui.QSpinBox(self.fontMainGroupBox)
defaultSizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Fixed)
defaultSizePolicy.setHeightForWidth(
self.fontMainSizeSpinBox.sizePolicy().hasHeightForWidth())
self.fontMainSizeSpinBox.setSizePolicy(defaultSizePolicy)
self.fontMainSizeSpinBox.setMinimumSize(QtCore.QSize(70, 0))
self.fontMainSizeSpinBox.setProperty(u'value', QtCore.QVariant(16))
self.fontMainSizeSpinBox.setMaximum(999)
self.fontMainSizeSpinBox.setObjectName(u'fontMainSizeSpinBox')
self.mainFontLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.fontMainSizeSpinBox)
self.fontMainWeightComboBox = QtGui.QComboBox(self.fontMainGroupBox)
self.fontMainWeightComboBox.setObjectName(u'fontMainWeightComboBox')
self.fontMainWeightComboBox.addItem(QtCore.QString())
self.fontMainWeightComboBox.addItem(QtCore.QString())
self.fontMainWeightComboBox.addItem(QtCore.QString())
self.fontMainWeightComboBox.addItem(QtCore.QString())
self.mainFontLayout.setWidget(3, QtGui.QFormLayout.FieldRole,
self.fontMainWeightComboBox)
self.fontMainWeightLabel = QtGui.QLabel(self.fontMainGroupBox)
self.fontMainWeightLabel.setObjectName(u'fontMainWeightLabel')
self.mainFontLayout.setWidget(3, QtGui.QFormLayout.LabelRole,
self.fontMainWeightLabel)
self.mainLeftLayout.addWidget(self.fontMainGroupBox)
self.fontMainWrapLineAdjustmentLabel = QtGui.QLabel(
self.fontMainGroupBox)
self.fontMainWrapLineAdjustmentLabel.setObjectName(
u'fontMainWrapLineAdjustmentLabel')
self.mainFontLayout.setWidget(4, QtGui.QFormLayout.LabelRole,
self.fontMainWrapLineAdjustmentLabel)
self.fontMainLineAdjustmentSpinBox = QtGui.QSpinBox(
self.fontMainGroupBox)
self.fontMainLineAdjustmentSpinBox.setObjectName(
u'fontMainLineAdjustmentSpinBox')
self.fontMainLineAdjustmentSpinBox.setMinimum(-99)
self.mainFontLayout.setWidget(4, QtGui.QFormLayout.FieldRole,
self.fontMainLineAdjustmentSpinBox)
self.fontMainLinesPageLabel = QtGui.QLabel(self.fontMainGroupBox)
self.fontMainLinesPageLabel.setObjectName(u'fontMainLinesPageLabel')
self.mainFontLayout.addRow(self.fontMainLinesPageLabel)
spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.mainLeftLayout.addItem(spacerItem1)
self.fontMainLayout.addWidget(self.mainLeftWidget)
self.mainRightWidget = QtGui.QWidget(self.fontMainTab)
self.mainRightWidget.setObjectName(u'mainRightWidget')
self.mainRightLayout = QtGui.QVBoxLayout(self.mainRightWidget)
self.mainRightLayout.setSpacing(8)
self.mainRightLayout.setMargin(0)
self.mainRightLayout.setObjectName(u'mainRightLayout')
self.mainLocationGroupBox = QtGui.QGroupBox(self.mainRightWidget)
self.mainLocationGroupBox.setObjectName(u'mainLocationGroupBox')
self.mainLocationLayout = QtGui.QFormLayout(self.mainLocationGroupBox)
self.mainLocationLayout.setMargin(8)
self.mainLocationLayout.setSpacing(8)
self.mainLocationLayout.setObjectName(u'mainLocationLayout')
self.defaultLocationLabel = QtGui.QLabel(self.mainLocationGroupBox)
self.defaultLocationLabel.setObjectName(u'defaultLocationLabel')
self.mainLocationLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.defaultLocationLabel)
self.fontMainDefaultCheckBox = QtGui.QCheckBox(
self.mainLocationGroupBox)
self.fontMainDefaultCheckBox.setTristate(False)
self.fontMainDefaultCheckBox.setObjectName(u'fontMainDefaultCheckBox')
self.mainLocationLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.fontMainDefaultCheckBox)
self.fontMainXLabel = QtGui.QLabel(self.mainLocationGroupBox)
self.fontMainXLabel.setObjectName(u'fontMainXLabel')
self.mainLocationLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.fontMainXLabel)
self.fontMainYLabel = QtGui.QLabel(self.mainLocationGroupBox)
self.fontMainYLabel.setObjectName(u'fontMainYLabel')
self.mainLocationLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.fontMainYLabel)
self.fontMainWidthLabel = QtGui.QLabel(self.mainLocationGroupBox)
self.fontMainWidthLabel.setObjectName(u'fontMainWidthLabel')
self.mainLocationLayout.setWidget(3, QtGui.QFormLayout.LabelRole,
self.fontMainWidthLabel)
self.fontMainHeightLabel = QtGui.QLabel(self.mainLocationGroupBox)
self.fontMainHeightLabel.setObjectName(u'fontMainHeightLabel')
self.mainLocationLayout.setWidget(4, QtGui.QFormLayout.LabelRole,
self.fontMainHeightLabel)
self.fontMainXSpinBox = QtGui.QSpinBox(self.mainLocationGroupBox)
defaultSizePolicy.setHeightForWidth(
self.fontMainXSpinBox.sizePolicy().hasHeightForWidth())
self.fontMainXSpinBox.setSizePolicy(defaultSizePolicy)
self.fontMainXSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.fontMainXSpinBox.setProperty(u'value', QtCore.QVariant(0))
self.fontMainXSpinBox.setMaximum(9999)
self.fontMainXSpinBox.setObjectName(u'fontMainXSpinBox')
self.mainLocationLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.fontMainXSpinBox)
self.fontMainYSpinBox = QtGui.QSpinBox(self.mainLocationGroupBox)
defaultSizePolicy.setHeightForWidth(
self.fontMainYSpinBox.sizePolicy().hasHeightForWidth())
self.fontMainYSpinBox.setSizePolicy(defaultSizePolicy)
self.fontMainYSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.fontMainYSpinBox.setMaximum(9999)
self.fontMainYSpinBox.setObjectName(u'fontMainYSpinBox')
self.mainLocationLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.fontMainYSpinBox)
self.fontMainWidthSpinBox = QtGui.QSpinBox(self.mainLocationGroupBox)
defaultSizePolicy.setHeightForWidth(
self.fontMainWidthSpinBox.sizePolicy().hasHeightForWidth())
self.fontMainWidthSpinBox.setSizePolicy(defaultSizePolicy)
self.fontMainWidthSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.fontMainWidthSpinBox.setMaximum(9999)
self.fontMainWidthSpinBox.setObjectName(u'fontMainWidthSpinBox')
self.mainLocationLayout.setWidget(3, QtGui.QFormLayout.FieldRole,
self.fontMainWidthSpinBox)
self.fontMainHeightSpinBox = QtGui.QSpinBox(self.mainLocationGroupBox)
defaultSizePolicy.setHeightForWidth(
self.fontMainHeightSpinBox.sizePolicy().hasHeightForWidth())
self.fontMainHeightSpinBox.setSizePolicy(defaultSizePolicy)
self.fontMainHeightSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.fontMainHeightSpinBox.setMaximum(9999)
self.fontMainHeightSpinBox.setObjectName(u'fontMainHeightSpinBox')
self.mainLocationLayout.setWidget(4, QtGui.QFormLayout.FieldRole,
self.fontMainHeightSpinBox)
self.mainRightLayout.addWidget(self.mainLocationGroupBox)
spacerItem2 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.mainRightLayout.addItem(spacerItem2)
self.fontMainLayout.addWidget(self.mainRightWidget)
self.themeTabWidget.addTab(self.fontMainTab, u'')
self.fontFooterTab = QtGui.QWidget()
self.fontFooterTab.setObjectName(u'fontFooterTab')
self.fontFooterLayout = QtGui.QHBoxLayout(self.fontFooterTab)
self.fontFooterLayout.setSpacing(8)
self.fontFooterLayout.setMargin(8)
self.fontFooterLayout.setObjectName(u'fontFooterLayout')
self.footerLeftWidget = QtGui.QWidget(self.fontFooterTab)
self.footerLeftWidget.setObjectName(u'footerLeftWidget')
self.footerLeftLayout = QtGui.QVBoxLayout(self.footerLeftWidget)
self.footerLeftLayout.setSpacing(8)
self.footerLeftLayout.setMargin(0)
self.footerLeftLayout.setObjectName(u'footerLeftLayout')
self.footerFontGroupBox = QtGui.QGroupBox(self.footerLeftWidget)
self.footerFontGroupBox.setObjectName(u'footerFontGroupBox')
self.footerFontLayout = QtGui.QFormLayout(self.footerFontGroupBox)
self.footerFontLayout.setFieldGrowthPolicy(
QtGui.QFormLayout.ExpandingFieldsGrow)
self.footerFontLayout.setFormAlignment(QtCore.Qt.AlignLeading |
QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.footerFontLayout.setMargin(8)
self.footerFontLayout.setSpacing(8)
self.footerFontLayout.setObjectName(u'footerFontLayout')
self.fontFooterLabel = QtGui.QLabel(self.footerFontGroupBox)
self.fontFooterLabel.setObjectName(u'fontFooterLabel')
self.footerFontLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.fontFooterLabel)
self.fontFooterComboBox = QtGui.QFontComboBox(self.footerFontGroupBox)
self.fontFooterComboBox.setObjectName(u'fontFooterComboBox')
self.footerFontLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.fontFooterComboBox)
self.fontFooterColorLabel = QtGui.QLabel(self.footerFontGroupBox)
self.fontFooterColorLabel.setObjectName(u'fontFooterColorLabel')
self.footerFontLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.fontFooterColorLabel)
self.fontFooterColorPushButton = QtGui.QPushButton(
self.footerFontGroupBox)
self.fontFooterColorPushButton.setObjectName(
u'fontFooterColorPushButton')
self.footerFontLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.fontFooterColorPushButton)
self.fontFooterSizeLabel = QtGui.QLabel(self.footerFontGroupBox)
self.fontFooterSizeLabel.setObjectName(u'fontFooterSizeLabel')
self.footerFontLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.fontFooterSizeLabel)
self.fontFooterSizeSpinBox = QtGui.QSpinBox(self.footerFontGroupBox)
defaultSizePolicy.setHeightForWidth(
self.fontFooterSizeSpinBox.sizePolicy().hasHeightForWidth())
self.fontFooterSizeSpinBox.setSizePolicy(defaultSizePolicy)
self.fontFooterSizeSpinBox.setMinimumSize(QtCore.QSize(70, 0))
self.fontFooterSizeSpinBox.setProperty(u'value', QtCore.QVariant(10))
self.fontFooterSizeSpinBox.setMaximum(999)
self.fontFooterSizeSpinBox.setObjectName(u'fontFooterSizeSpinBox')
self.footerFontLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.fontFooterSizeSpinBox)
self.fontFooterWeightComboBox = QtGui.QComboBox(self.footerFontGroupBox)
self.fontFooterWeightComboBox.setObjectName(u'fontFooterWeightComboBox')
self.fontFooterWeightComboBox.addItem(QtCore.QString())
self.fontFooterWeightComboBox.addItem(QtCore.QString())
self.fontFooterWeightComboBox.addItem(QtCore.QString())
self.fontFooterWeightComboBox.addItem(QtCore.QString())
self.footerFontLayout.setWidget(3, QtGui.QFormLayout.FieldRole,
self.fontFooterWeightComboBox)
self.fontFooterWeightLabel = QtGui.QLabel(self.footerFontGroupBox)
self.fontFooterWeightLabel.setObjectName(u'fontFooterWeightLabel')
self.footerFontLayout.setWidget(3, QtGui.QFormLayout.LabelRole,
self.fontFooterWeightLabel)
self.footerLeftLayout.addWidget(self.footerFontGroupBox)
spacerItem3 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.footerLeftLayout.addItem(spacerItem3)
self.fontFooterLayout.addWidget(self.footerLeftWidget)
self.footerRightWidget = QtGui.QWidget(self.fontFooterTab)
self.footerRightWidget.setObjectName(u'footerRightWidget')
self.footerRightLayout = QtGui.QVBoxLayout(self.footerRightWidget)
self.footerRightLayout.setSpacing(8)
self.footerRightLayout.setMargin(0)
self.footerRightLayout.setObjectName(u'footerRightLayout')
self.locationFooterGroupBox = QtGui.QGroupBox(self.footerRightWidget)
self.locationFooterGroupBox.setObjectName(u'locationFooterGroupBox')
self.locationFooterLayout = QtGui.QFormLayout(
self.locationFooterGroupBox)
self.locationFooterLayout.setFieldGrowthPolicy(
QtGui.QFormLayout.ExpandingFieldsGrow)
self.locationFooterLayout.setFormAlignment(QtCore.Qt.AlignLeading |
QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
self.locationFooterLayout.setMargin(8)
self.locationFooterLayout.setSpacing(8)
self.locationFooterLayout.setObjectName(u'locationFooterLayout')
self.fontFooterDefaultLabel = QtGui.QLabel(self.locationFooterGroupBox)
self.fontFooterDefaultLabel.setObjectName(u'fontFooterDefaultLabel')
self.locationFooterLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.fontFooterDefaultLabel)
self.fontFooterDefaultCheckBox = QtGui.QCheckBox(
self.locationFooterGroupBox)
self.fontFooterDefaultCheckBox.setTristate(False)
self.fontFooterDefaultCheckBox.setObjectName(
u'fontFooterDefaultCheckBox')
self.locationFooterLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.fontFooterDefaultCheckBox)
self.fontFooterXLabel = QtGui.QLabel(self.locationFooterGroupBox)
self.fontFooterXLabel.setObjectName(u'fontFooterXLabel')
self.locationFooterLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.fontFooterXLabel)
self.fontFooterYLabel = QtGui.QLabel(self.locationFooterGroupBox)
self.fontFooterYLabel.setObjectName(u'fontFooterYLabel')
self.locationFooterLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.fontFooterYLabel)
self.fontFooterWidthLabel = QtGui.QLabel(self.locationFooterGroupBox)
self.fontFooterWidthLabel.setObjectName(u'fontFooterWidthLabel')
self.locationFooterLayout.setWidget(3, QtGui.QFormLayout.LabelRole,
self.fontFooterWidthLabel)
self.fontFooterHeightLabel = QtGui.QLabel(self.locationFooterGroupBox)
self.fontFooterHeightLabel.setObjectName(u'fontFooterHeightLabel')
self.locationFooterLayout.setWidget(4, QtGui.QFormLayout.LabelRole,
self.fontFooterHeightLabel)
self.fontFooterXSpinBox = QtGui.QSpinBox(self.locationFooterGroupBox)
defaultSizePolicy.setHeightForWidth(
self.fontFooterXSpinBox.sizePolicy().hasHeightForWidth())
self.fontFooterXSpinBox.setSizePolicy(defaultSizePolicy)
self.fontFooterXSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.fontFooterXSpinBox.setProperty(u'value', QtCore.QVariant(0))
self.fontFooterXSpinBox.setMaximum(9999)
self.fontFooterXSpinBox.setObjectName(u'fontFooterXSpinBox')
self.locationFooterLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.fontFooterXSpinBox)
self.fontFooterYSpinBox = QtGui.QSpinBox(self.locationFooterGroupBox)
defaultSizePolicy.setHeightForWidth(
self.fontFooterXSpinBox.sizePolicy().hasHeightForWidth())
self.fontFooterYSpinBox.setSizePolicy(defaultSizePolicy)
self.fontFooterYSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.fontFooterYSpinBox.setProperty(u'value', QtCore.QVariant(0))
self.fontFooterYSpinBox.setMaximum(9999)
self.fontFooterYSpinBox.setObjectName(u'fontFooterYSpinBox')
self.locationFooterLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.fontFooterYSpinBox)
self.fontFooterWidthSpinBox = QtGui.QSpinBox(
self.locationFooterGroupBox)
self.fontFooterWidthSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.fontFooterWidthSpinBox.setMaximum(9999)
self.fontFooterWidthSpinBox.setObjectName(u'fontFooterWidthSpinBox')
self.locationFooterLayout.setWidget(3, QtGui.QFormLayout.FieldRole,
self.fontFooterWidthSpinBox)
self.fontFooterHeightSpinBox = QtGui.QSpinBox(
self.locationFooterGroupBox)
self.fontFooterHeightSpinBox.setMinimumSize(QtCore.QSize(78, 0))
self.fontFooterHeightSpinBox.setMaximum(9999)
self.fontFooterHeightSpinBox.setObjectName(u'fontFooterHeightSpinBox')
self.locationFooterLayout.setWidget(4, QtGui.QFormLayout.FieldRole,
self.fontFooterHeightSpinBox)
self.footerRightLayout.addWidget(self.locationFooterGroupBox)
spacerItem4 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.footerRightLayout.addItem(spacerItem4)
self.fontFooterLayout.addWidget(self.footerRightWidget)
self.themeTabWidget.addTab(self.fontFooterTab, u'')
self.otherOptionsTab = QtGui.QWidget()
self.otherOptionsTab.setObjectName(u'otherOptionsTab')
self.otherOptionsLayout = QtGui.QHBoxLayout(self.otherOptionsTab)
self.otherOptionsLayout.setSpacing(8)
self.otherOptionsLayout.setMargin(8)
self.otherOptionsLayout.setObjectName(u'otherOptionsLayout')
self.optionsLeftWidget = QtGui.QWidget(self.otherOptionsTab)
self.optionsLeftWidget.setObjectName(u'optionsLeftWidget')
self.optionsLeftLayout = QtGui.QVBoxLayout(self.optionsLeftWidget)
self.optionsLeftLayout.setSpacing(8)
self.optionsLeftLayout.setMargin(0)
self.optionsLeftLayout.setObjectName(u'optionsLeftLayout')
self.outlineGroupBox = QtGui.QGroupBox(self.optionsLeftWidget)
self.outlineGroupBox.setObjectName(u'outlineGroupBox')
self.verticalLayout = QtGui.QVBoxLayout(self.outlineGroupBox)
self.verticalLayout.setSpacing(8)
self.verticalLayout.setMargin(8)
self.verticalLayout.setObjectName(u'verticalLayout')
self.outlineWidget = QtGui.QWidget(self.outlineGroupBox)
self.outlineWidget.setObjectName(u'outlineWidget')
self.outlineLayout = QtGui.QFormLayout(self.outlineWidget)
self.outlineLayout.setMargin(0)
self.outlineLayout.setSpacing(8)
self.outlineLayout.setObjectName(u'outlineLayout')
self.outlineCheckBox = QtGui.QCheckBox(self.outlineWidget)
self.outlineCheckBox.setObjectName(u'outlineCheckBox')
self.outlineLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.outlineCheckBox)
self.outlineSpinBox = QtGui.QSpinBox(self.outlineWidget)
self.outlineSpinBox.setObjectName(u'outlineSpinBox')
self.outlineSpinBox.setMaximum(10)
self.outlineLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.outlineSpinBox)
self.outlineSpinBoxLabel = QtGui.QLabel(self.outlineWidget)
self.outlineSpinBoxLabel.setObjectName(u'outlineSpinBoxLabel')
self.outlineLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.outlineSpinBoxLabel)
self.outlineColorLabel = QtGui.QLabel(self.outlineWidget)
self.outlineColorLabel.setObjectName(u'outlineColorLabel')
self.outlineLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.outlineColorLabel)
self.outlineColorPushButton = QtGui.QPushButton(self.outlineWidget)
self.outlineColorPushButton.setObjectName(u'outlineColorPushButton')
self.outlineLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.outlineColorPushButton)
self.outlineEnabledLabel = QtGui.QLabel(self.outlineWidget)
self.outlineEnabledLabel.setObjectName(u'outlineEnabledLabel')
self.outlineLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.outlineEnabledLabel)
self.verticalLayout.addWidget(self.outlineWidget)
self.optionsLeftLayout.addWidget(self.outlineGroupBox)
self.shadowGroupBox = QtGui.QGroupBox(self.optionsLeftWidget)
self.shadowGroupBox.setObjectName(u'shadowGroupBox')
self.verticalLayout = QtGui.QVBoxLayout(self.shadowGroupBox)
self.verticalLayout.setSpacing(8)
self.verticalLayout.setMargin(8)
self.verticalLayout.setObjectName(u'verticalLayout')
self.shadowWidget = QtGui.QWidget(self.shadowGroupBox)
self.shadowWidget.setObjectName(u'shadowWidget')
self.shadowLayout = QtGui.QFormLayout(self.shadowWidget)
self.shadowLayout.setMargin(0)
self.shadowLayout.setSpacing(8)
self.shadowLayout.setObjectName(u'shadowLayout')
self.shadowCheckBox = QtGui.QCheckBox(self.shadowWidget)
self.shadowCheckBox.setObjectName(u'shadowCheckBox')
self.shadowLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.shadowCheckBox)
self.shadowSpinBox = QtGui.QSpinBox(self.outlineWidget)
self.shadowSpinBox.setObjectName(u'shadowSpinBox')
self.shadowSpinBox.setMaximum(10)
self.shadowLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.shadowSpinBox)
self.shadowSpinBoxLabel = QtGui.QLabel(self.outlineWidget)
self.shadowSpinBoxLabel.setObjectName(u'shadowSpinBoxLabel')
self.shadowLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
self.shadowSpinBoxLabel)
self.shadowColorLabel = QtGui.QLabel(self.shadowWidget)
self.shadowColorLabel.setObjectName(u'shadowColorLabel')
self.shadowLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.shadowColorLabel)
self.shadowColorPushButton = QtGui.QPushButton(self.shadowWidget)
self.shadowColorPushButton.setObjectName(u'shadowColorPushButton')
self.shadowLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.shadowColorPushButton)
self.shadowEnabledLabel = QtGui.QLabel(self.shadowWidget)
self.shadowEnabledLabel.setObjectName(u'shadowEnabledLabel')
self.shadowLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.shadowEnabledLabel)
self.verticalLayout.addWidget(self.shadowWidget)
self.optionsLeftLayout.addWidget(self.shadowGroupBox)
spacerItem5 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.optionsLeftLayout.addItem(spacerItem5)
self.otherOptionsLayout.addWidget(self.optionsLeftWidget)
self.optionsRightWidget = QtGui.QWidget(self.otherOptionsTab)
self.optionsRightWidget.setObjectName(u'optionsRightWidget')
self.optionsRightLayout = QtGui.QVBoxLayout(self.optionsRightWidget)
self.optionsRightLayout.setSpacing(8)
self.optionsRightLayout.setMargin(0)
self.optionsRightLayout.setObjectName(u'optionsRightLayout')
self.alignmentGroupBox = QtGui.QGroupBox(self.optionsRightWidget)
self.alignmentGroupBox.setObjectName(u'alignmentGroupBox')
self.gridLayout4 = QtGui.QGridLayout(self.alignmentGroupBox)
self.gridLayout4.setObjectName(u'gridLayout4')
self.horizontalLabel = QtGui.QLabel(self.alignmentGroupBox)
self.horizontalLabel.setObjectName(u'horizontalLabel')
self.gridLayout4.addWidget(self.horizontalLabel, 0, 0, 1, 1)
self.horizontalComboBox = QtGui.QComboBox(self.alignmentGroupBox)
self.horizontalComboBox.setObjectName(u'horizontalComboBox')
self.horizontalComboBox.addItem(QtCore.QString())
self.horizontalComboBox.addItem(QtCore.QString())
self.horizontalComboBox.addItem(QtCore.QString())
self.gridLayout4.addWidget(self.horizontalComboBox, 0, 1, 1, 1)
self.verticalLabel = QtGui.QLabel(self.alignmentGroupBox)
self.verticalLabel.setObjectName(u'verticalLabel')
self.gridLayout4.addWidget(self.verticalLabel, 1, 0, 1, 1)
self.verticalComboBox = QtGui.QComboBox(self.alignmentGroupBox)
self.verticalComboBox.setObjectName(u'verticalComboBox')
self.verticalComboBox.addItem(QtCore.QString())
self.verticalComboBox.addItem(QtCore.QString())
self.verticalComboBox.addItem(QtCore.QString())
self.gridLayout4.addWidget(self.verticalComboBox, 1, 1, 1, 1)
self.optionsRightLayout.addWidget(self.alignmentGroupBox)
self.transitionGroupBox = QtGui.QGroupBox(self.optionsRightWidget)
self.transitionGroupBox.setObjectName(u'transitionGroupBox')
self.gridLayout5 = QtGui.QGridLayout(self.transitionGroupBox)
self.gridLayout5.setObjectName(u'gridLayout5')
self.slideTransitionCheckBoxLabel = QtGui.QLabel(
self.transitionGroupBox)
self.slideTransitionCheckBoxLabel.setObjectName(
u'slideTransitionCheckBoxLabel')
self.gridLayout5.addWidget(
self.slideTransitionCheckBoxLabel, 0, 0, 1, 1)
self.slideTransitionCheckBox = QtGui.QCheckBox(self.alignmentGroupBox)
self.slideTransitionCheckBox.setTristate(False)
self.gridLayout5.addWidget(self.slideTransitionCheckBox, 0, 1, 1, 1)
self.optionsRightLayout.addWidget(self.transitionGroupBox)
spacerItem6 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.optionsRightLayout.addItem(spacerItem6)
self.otherOptionsLayout.addWidget(self.optionsRightWidget)
self.themeTabWidget.addTab(self.otherOptionsTab, u'')
self.contentLayout.addWidget(self.themeTabWidget)
self.amendThemeLayout.addWidget(self.contentWidget)
self.previewGroupBox = QtGui.QGroupBox(amendThemeDialog)
self.previewGroupBox.setObjectName(u'previewGroupBox')
self.themePreviewLayout = QtGui.QHBoxLayout(self.previewGroupBox)
self.themePreviewLayout.setSpacing(8)
self.themePreviewLayout.setMargin(8)
self.themePreviewLayout.setObjectName(u'themePreviewLayout')
spacerItem7 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
self.themePreviewLayout.addItem(spacerItem7)
self.themePreview = QtGui.QLabel(self.previewGroupBox)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(
self.themePreview.sizePolicy().hasHeightForWidth())
self.themePreview.setSizePolicy(sizePolicy)
self.themePreview.setMaximumSize(QtCore.QSize(300, 225))
self.themePreview.setFrameShape(QtGui.QFrame.WinPanel)
self.themePreview.setFrameShadow(QtGui.QFrame.Sunken)
self.themePreview.setLineWidth(1)
self.themePreview.setScaledContents(True)
self.themePreview.setObjectName(u'themePreview')
self.themePreviewLayout.addWidget(self.themePreview)
spacerItem8 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
self.themePreviewLayout.addItem(spacerItem8)
self.amendThemeLayout.addWidget(self.previewGroupBox)
self.themeButtonBox = QtGui.QDialogButtonBox(amendThemeDialog)
self.themeButtonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Ok)
self.themeButtonBox.setObjectName(u'themeButtonBox')
self.amendThemeLayout.addWidget(self.themeButtonBox)
self.retranslateUi(amendThemeDialog)
self.themeTabWidget.setCurrentIndex(0)
QtCore.QObject.connect(self.themeButtonBox,
QtCore.SIGNAL(u'accepted()'), amendThemeDialog.accept)
QtCore.QObject.connect(self.themeButtonBox,
QtCore.SIGNAL(u'rejected()'), amendThemeDialog.reject)
QtCore.QMetaObject.connectSlotsByName(amendThemeDialog)
def retranslateUi(self, amendThemeDialog):
amendThemeDialog.setWindowTitle(
translate('OpenLP.AmendThemeForm', 'Theme Maintenance'))
self.themeNameLabel.setText(
translate('OpenLP.AmendThemeForm', 'Theme &name:'))
self.backgroundTypeLabel.setText(
translate('OpenLP.AmendThemeForm', 'Type:'))
self.backgroundTypeComboBox.setItemText(0,
translate('OpenLP.AmendThemeForm', 'Solid Color'))
self.backgroundTypeComboBox.setItemText(1,
translate('OpenLP.AmendThemeForm', 'Gradient'))
self.backgroundTypeComboBox.setItemText(2,
translate('OpenLP.AmendThemeForm', 'Image'))
self.color1Label.setText(u'<color1>:')
self.color2Label.setText(u'<color2>:')
self.imageLabel.setText(
translate('OpenLP.AmendThemeForm', 'Image:'))
self.gradientLabel.setText(
translate('OpenLP.AmendThemeForm', 'Gradient:'))
self.gradientComboBox.setItemText(0,
translate('OpenLP.AmendThemeForm', 'Horizontal'))
self.gradientComboBox.setItemText(1,
translate('OpenLP.AmendThemeForm', 'Vertical'))
self.gradientComboBox.setItemText(2,
translate('OpenLP.AmendThemeForm', 'Circular'))
self.themeTabWidget.setTabText(
self.themeTabWidget.indexOf(self.backgroundTab),
translate('OpenLP.AmendThemeForm', '&Background'))
self.fontMainGroupBox.setTitle(
translate('OpenLP.AmendThemeForm', 'Main Font'))
self.fontMainlabel.setText(
translate('OpenLP.AmendThemeForm', 'Font:'))
self.fontMainColorLabel.setText(
translate('OpenLP.AmendThemeForm', 'Color:'))
self.fontMainSize.setText(
translate('OpenLP.AmendThemeForm', 'Size:'))
self.fontMainSizeSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'pt'))
self.fontMainWrapLineAdjustmentLabel.setText(
translate('OpenLP.AmendThemeForm', 'Adjust line spacing:'))
self.fontMainWeightComboBox.setItemText(0,
translate('OpenLP.AmendThemeForm', 'Normal'))
self.fontMainWeightComboBox.setItemText(1,
translate('OpenLP.AmendThemeForm', 'Bold'))
self.fontMainWeightComboBox.setItemText(2,
translate('OpenLP.AmendThemeForm', 'Italics'))
self.fontMainWeightComboBox.setItemText(3,
translate('OpenLP.AmendThemeForm', 'Bold/Italics'))
self.fontMainWeightLabel.setText(
translate('OpenLP.AmendThemeForm', 'Style:'))
self.mainLocationGroupBox.setTitle(
translate('OpenLP.AmendThemeForm', 'Display Location'))
self.defaultLocationLabel.setText(
translate('OpenLP.AmendThemeForm', 'Use default location'))
self.fontMainXLabel.setText(
translate('OpenLP.AmendThemeForm', 'X position:'))
self.fontMainYLabel.setText(
translate('OpenLP.AmendThemeForm', 'Y position:'))
self.fontMainWidthLabel.setText(
translate('OpenLP.AmendThemeForm', 'Width:'))
self.fontMainHeightLabel.setText(
translate('OpenLP.AmendThemeForm', 'Height:'))
self.fontMainXSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.fontMainYSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.fontMainWidthSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.fontMainHeightSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.themeTabWidget.setTabText(
self.themeTabWidget.indexOf(self.fontMainTab),
translate('OpenLP.AmendThemeForm', '&Main Font'))
self.footerFontGroupBox.setTitle(
translate('OpenLP.AmendThemeForm', 'Footer Font'))
self.fontFooterLabel.setText(
translate('OpenLP.AmendThemeForm', 'Font:'))
self.fontFooterColorLabel.setText(
translate('OpenLP.AmendThemeForm', 'Color:'))
self.fontFooterSizeLabel.setText(
translate('OpenLP.AmendThemeForm', 'Size:'))
self.fontFooterSizeSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'pt'))
self.fontFooterWeightComboBox.setItemText(0,
translate('OpenLP.AmendThemeForm', 'Normal'))
self.fontFooterWeightComboBox.setItemText(1,
translate('OpenLP.AmendThemeForm', 'Bold'))
self.fontFooterWeightComboBox.setItemText(2,
translate('OpenLP.AmendThemeForm', 'Italics'))
self.fontFooterWeightComboBox.setItemText(3,
translate('OpenLP.AmendThemeForm', 'Bold/Italics'))
self.fontFooterWeightLabel.setText(
translate('OpenLP.AmendThemeForm', 'Style:'))
self.locationFooterGroupBox.setTitle(
translate('OpenLP.AmendThemeForm', 'Display Location'))
self.fontFooterDefaultLabel.setText(
translate('OpenLP.AmendThemeForm', 'Use default location'))
self.fontFooterXLabel.setText(
translate('OpenLP.AmendThemeForm', 'X position:'))
self.fontFooterYLabel.setText(
translate('OpenLP.AmendThemeForm', 'Y position:'))
self.fontFooterWidthLabel.setText(
translate('OpenLP.AmendThemeForm', 'Width:'))
self.fontFooterHeightLabel.setText(
translate('OpenLP.AmendThemeForm', 'Height:'))
self.fontFooterXSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.fontFooterYSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.fontFooterWidthSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.fontFooterHeightSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.themeTabWidget.setTabText(
self.themeTabWidget.indexOf(self.fontFooterTab),
translate('OpenLP.AmendThemeForm', '&Footer Font'))
self.outlineGroupBox.setTitle(
translate('OpenLP.AmendThemeForm', 'Outline'))
self.outlineSpinBoxLabel.setText(
translate('OpenLP.AmendThemeForm', 'Outline size:'))
self.outlineSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.outlineColorLabel.setText(
translate('OpenLP.AmendThemeForm', 'Outline color:'))
self.outlineEnabledLabel.setText(
translate('OpenLP.AmendThemeForm', 'Show outline:'))
self.shadowGroupBox.setTitle(
translate('OpenLP.AmendThemeForm', 'Shadow'))
self.shadowSpinBoxLabel.setText(
translate('OpenLP.AmendThemeForm', 'Shadow size:'))
self.shadowSpinBox.setSuffix(
translate('OpenLP.AmendThemeForm', 'px'))
self.shadowColorLabel.setText(
translate('OpenLP.AmendThemeForm', 'Shadow color:'))
self.shadowEnabledLabel.setText(
translate('OpenLP.AmendThemeForm', 'Show shadow:'))
self.alignmentGroupBox.setTitle(
translate('OpenLP.AmendThemeForm', 'Alignment'))
self.horizontalLabel.setText(
translate('OpenLP.AmendThemeForm', 'Horizontal align:'))
self.horizontalComboBox.setItemText(0,
translate('OpenLP.AmendThemeForm', 'Left'))
self.horizontalComboBox.setItemText(1,
translate('OpenLP.AmendThemeForm', 'Right'))
self.horizontalComboBox.setItemText(2,
translate('OpenLP.AmendThemeForm', 'Center'))
self.verticalLabel.setText(
translate('OpenLP.AmendThemeForm', 'Vertical align:'))
self.verticalComboBox.setItemText(0,
translate('OpenLP.AmendThemeForm', 'Top'))
self.verticalComboBox.setItemText(1,
translate('OpenLP.AmendThemeForm', 'Middle'))
self.verticalComboBox.setItemText(2,
translate('OpenLP.AmendThemeForm', 'Bottom'))
self.transitionGroupBox.setTitle(
translate('OpenLP.AmendThemeForm', 'Slide Transition'))
self.slideTransitionCheckBoxLabel.setText(
translate('OpenLP.AmendThemeForm', 'Transition active'))
self.themeTabWidget.setTabText(
self.themeTabWidget.indexOf(self.otherOptionsTab),
translate('OpenLP.AmendThemeForm', '&Other Options'))
self.previewGroupBox.setTitle(
translate('OpenLP.AmendThemeForm', 'Preview'))

View File

@ -1,717 +0,0 @@
# -*- 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
import os.path
from PyQt4 import QtCore, QtGui
from openlp.core.lib import ThemeXML, translate
from openlp.core.utils import get_images_filter
from amendthemedialog import Ui_AmendThemeDialog
log = logging.getLogger(u'AmendThemeForm')
class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
"""
The :class:`AmendThemeForm` class provides the user interface to set up
new and edit existing themes.
"""
def __init__(self, parent):
"""
Initialise the theme editor user interface
"""
QtGui.QDialog.__init__(self, parent)
self.thememanager = parent
self.path = None
self.theme = ThemeXML()
self.setupUi(self)
# Buttons
QtCore.QObject.connect(self.color1PushButton,
QtCore.SIGNAL(u'pressed()'), self.onColor1PushButtonClicked)
QtCore.QObject.connect(self.color2PushButton,
QtCore.SIGNAL(u'pressed()'), self.onColor2PushButtonClicked)
QtCore.QObject.connect(self.fontMainColorPushButton,
QtCore.SIGNAL(u'pressed()'), self.onFontMainColorPushButtonClicked)
QtCore.QObject.connect(self.fontFooterColorPushButton,
QtCore.SIGNAL(u'pressed()'),
self.onFontFooterColorPushButtonClicked)
QtCore.QObject.connect(self.outlineColorPushButton,
QtCore.SIGNAL(u'pressed()'), self.onOutlineColorPushButtonClicked)
QtCore.QObject.connect(self.shadowColorPushButton,
QtCore.SIGNAL(u'pressed()'), self.onShadowColorPushButtonClicked)
QtCore.QObject.connect(self.imageToolButton,
QtCore.SIGNAL(u'clicked()'), self.onImageToolButtonClicked)
# Combo boxes
QtCore.QObject.connect(self.backgroundTypeComboBox,
QtCore.SIGNAL(u'activated(int)'),
self.onBackgroundTypeComboBoxSelected)
QtCore.QObject.connect(self.gradientComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onGradientComboBoxSelected)
QtCore.QObject.connect(self.fontMainComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontMainComboBoxSelected)
QtCore.QObject.connect(self.fontMainWeightComboBox,
QtCore.SIGNAL(u'activated(int)'),
self.onFontMainWeightComboBoxSelected)
QtCore.QObject.connect(self.fontFooterComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontFooterComboBoxSelected)
QtCore.QObject.connect(self.fontFooterWeightComboBox,
QtCore.SIGNAL(u'activated(int)'),
self.onFontFooterWeightComboBoxSelected)
QtCore.QObject.connect(self.horizontalComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onHorizontalComboBoxSelected)
QtCore.QObject.connect(self.verticalComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onVerticalComboBoxSelected)
# Spin boxes
QtCore.QObject.connect(self.fontMainSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainSizeSpinBoxChanged)
QtCore.QObject.connect(self.fontFooterSizeSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterSizeSpinBoxChanged)
QtCore.QObject.connect(self.fontMainXSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontMainXSpinBoxChanged)
QtCore.QObject.connect(self.fontMainYSpinBox,
QtCore.SIGNAL(u'editingFinished()'), self.onFontMainYSpinBoxChanged)
QtCore.QObject.connect(self.fontMainWidthSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainWidthSpinBoxChanged)
QtCore.QObject.connect(self.fontMainHeightSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainHeightSpinBoxChanged)
QtCore.QObject.connect(self.fontMainLineAdjustmentSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontMainLineAdjustmentSpinBoxChanged)
QtCore.QObject.connect(self.fontFooterXSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterXSpinBoxChanged)
QtCore.QObject.connect(self.fontFooterYSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterYSpinBoxChanged)
QtCore.QObject.connect(self.fontFooterWidthSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterWidthSpinBoxChanged)
QtCore.QObject.connect(self.fontFooterHeightSpinBox,
QtCore.SIGNAL(u'editingFinished()'),
self.onFontFooterHeightSpinBoxChanged)
QtCore.QObject.connect(self.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)'),
self.onFontMainDefaultCheckBoxChanged)
QtCore.QObject.connect(self.fontFooterDefaultCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onFontFooterDefaultCheckBoxChanged)
QtCore.QObject.connect(self.outlineCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onOutlineCheckBoxChanged)
QtCore.QObject.connect(self.shadowCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.onShadowCheckBoxChanged)
QtCore.QObject.connect(self.slideTransitionCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onSlideTransitionCheckBoxChanged)
def accept(self):
new_theme = ThemeXML()
theme_name = unicode(self.themeNameEdit.text())
new_theme.new_document(theme_name)
save_from = None
save_to = None
if self.theme.background_type == u'solid':
new_theme.add_background_solid(
unicode(self.theme.background_color))
elif self.theme.background_type == u'gradient':
new_theme.add_background_gradient(
unicode(self.theme.background_start_color),
unicode(self.theme.background_end_color),
self.theme.background_direction)
else:
filename = \
os.path.split(unicode(self.theme.background_filename))[1]
new_theme.add_background_image(filename)
save_to = os.path.join(self.path, theme_name, filename)
save_from = self.theme.background_filename
new_theme.add_font(unicode(self.theme.font_main_name),
unicode(self.theme.font_main_color),
unicode(self.theme.font_main_proportion),
unicode(self.theme.font_main_override), u'main',
unicode(self.theme.font_main_weight),
unicode(self.theme.font_main_italics),
unicode(self.theme.font_main_line_adjustment),
unicode(self.theme.font_main_x),
unicode(self.theme.font_main_y),
unicode(self.theme.font_main_width),
unicode(self.theme.font_main_height))
new_theme.add_font(unicode(self.theme.font_footer_name),
unicode(self.theme.font_footer_color),
unicode(self.theme.font_footer_proportion),
unicode(self.theme.font_footer_override), u'footer',
unicode(self.theme.font_footer_weight),
unicode(self.theme.font_footer_italics),
0, # line adjustment
unicode(self.theme.font_footer_x),
unicode(self.theme.font_footer_y),
unicode(self.theme.font_footer_width),
unicode(self.theme.font_footer_height))
new_theme.add_display(unicode(self.theme.display_shadow),
unicode(self.theme.display_shadow_color),
unicode(self.theme.display_outline),
unicode(self.theme.display_outline_color),
unicode(self.theme.display_horizontal_align),
unicode(self.theme.display_vertical_align),
unicode(self.theme.display_wrap_style),
unicode(self.theme.display_slide_transition),
unicode(self.theme.display_shadow_size),
unicode(self.theme.display_outline_size))
theme = new_theme.extract_xml()
pretty_theme = new_theme.extract_formatted_xml()
if self.thememanager.saveTheme(theme_name, theme, pretty_theme,
save_from, save_to) is not False:
return QtGui.QDialog.accept(self)
def loadTheme(self, theme):
log.debug(u'LoadTheme %s', theme)
self.theme = theme
# Stop the initial screen setup generating 1 preview per field!
self.allowPreview = False
self.paintUi(self.theme)
self.allowPreview = True
self.previewTheme()
def onImageToolButtonClicked(self):
images_filter = get_images_filter()
images_filter = '%s;;%s (*.*) (*)' % (images_filter,
translate('OpenLP.AmendThemeForm', 'All Files'))
filename = QtGui.QFileDialog.getOpenFileName(self,
translate('OpenLP.AmendThemeForm', 'Select Image'), u'',
images_filter)
if filename:
self.imageLineEdit.setText(filename)
self.theme.background_filename = filename
self.previewTheme()
#
# Main Font Tab
#
def onFontMainComboBoxSelected(self):
self.theme.font_main_name = self.fontMainComboBox.currentFont().family()
self.previewTheme()
def onFontMainWeightComboBoxSelected(self, value):
if value == 0:
self.theme.font_main_weight = u'Normal'
self.theme.font_main_italics = False
elif value == 1:
self.theme.font_main_weight = u'Bold'
self.theme.font_main_italics = False
elif value == 2:
self.theme.font_main_weight = u'Normal'
self.theme.font_main_italics = True
else:
self.theme.font_main_weight = u'Bold'
self.theme.font_main_italics = True
self.previewTheme()
def onFontMainColorPushButtonClicked(self):
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.font_main_color), self)
if new_color.isValid():
self.theme.font_main_color = new_color.name()
self.fontMainColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(self.theme.font_main_color))
self.previewTheme()
def onFontMainSizeSpinBoxChanged(self):
if self.theme.font_main_proportion != self.fontMainSizeSpinBox.value():
self.theme.font_main_proportion = self.fontMainSizeSpinBox.value()
self.previewTheme()
def onFontMainDefaultCheckBoxChanged(self, value):
if value == 2: # checked
self.theme.font_main_override = False
else:
self.theme.font_main_override = True
if not self.theme.font_main_x and not self.theme.font_main_y and \
not self.theme.font_main_width and not self.theme.font_main_height:
self.theme.font_main_x = u'10'
self.theme.font_main_y = u'10'
self.theme.font_main_width = u'1024'
self.theme.font_main_height = u'730'
self.fontMainXSpinBox.setValue(self.theme.font_main_x)
self.fontMainYSpinBox.setValue(self.theme.font_main_y)
self.fontMainWidthSpinBox.setValue(self.theme.font_main_width)
self.fontMainHeightSpinBox.setValue(self.theme.font_main_height)
self.fontMainLineAdjustmentSpinBox.setValue(
self.theme.font_main_line_adjustment)
self.stateChanging(self.theme)
self.previewTheme()
def onFontMainXSpinBoxChanged(self):
if self.theme.font_main_x != self.fontMainXSpinBox.value():
self.theme.font_main_x = self.fontMainXSpinBox.value()
self.previewTheme()
def onFontMainYSpinBoxChanged(self):
if self.theme.font_main_y != self.fontMainYSpinBox.value():
self.theme.font_main_y = self.fontMainYSpinBox.value()
self.previewTheme()
def onFontMainWidthSpinBoxChanged(self):
if self.theme.font_main_width != self.fontMainWidthSpinBox.value():
self.theme.font_main_width = self.fontMainWidthSpinBox.value()
self.previewTheme()
def onFontMainLineAdjustmentSpinBoxChanged(self):
if self.theme.font_main_line_adjustment != \
self.fontMainLineAdjustmentSpinBox.value():
self.theme.font_main_line_adjustment = \
self.fontMainLineAdjustmentSpinBox.value()
self.previewTheme()
def onFontMainHeightSpinBoxChanged(self):
if self.theme.font_main_height != self.fontMainHeightSpinBox.value():
self.theme.font_main_height = self.fontMainHeightSpinBox.value()
self.previewTheme()
#
# Footer Font Tab
#
def onFontFooterComboBoxSelected(self):
self.theme.font_footer_name = \
self.fontFooterComboBox.currentFont().family()
self.previewTheme()
def onFontFooterWeightComboBoxSelected(self, value):
if value == 0:
self.theme.font_footer_weight = u'Normal'
self.theme.font_footer_italics = False
elif value == 1:
self.theme.font_footer_weight = u'Bold'
self.theme.font_footer_italics = False
elif value == 2:
self.theme.font_footer_weight = u'Normal'
self.theme.font_footer_italics = True
else:
self.theme.font_footer_weight = u'Bold'
self.theme.font_footer_italics = True
self.previewTheme()
def onFontFooterColorPushButtonClicked(self):
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.font_footer_color), self)
if new_color.isValid():
self.theme.font_footer_color = new_color.name()
self.fontFooterColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(self.theme.font_footer_color))
self.previewTheme()
def onFontFooterSizeSpinBoxChanged(self):
if self.theme.font_footer_proportion != \
self.fontFooterSizeSpinBox.value():
self.theme.font_footer_proportion = \
self.fontFooterSizeSpinBox.value()
self.previewTheme()
def onFontFooterDefaultCheckBoxChanged(self, value):
if value == 2: # checked
self.theme.font_footer_override = False
else:
self.theme.font_footer_override = True
if not self.theme.font_footer_x and not self.theme.font_footer_y and \
not self.theme.font_footer_width and \
not self.theme.font_footer_height:
self.theme.font_footer_x = u'10'
self.theme.font_footer_y = u'730'
self.theme.font_footer_width = u'1024'
self.theme.font_footer_height = u'38'
self.fontFooterXSpinBox.setValue(self.theme.font_footer_x)
self.fontFooterYSpinBox.setValue(self.theme.font_footer_y)
self.fontFooterWidthSpinBox.setValue(self.theme.font_footer_width)
self.fontFooterHeightSpinBox.setValue(
self.theme.font_footer_height)
self.stateChanging(self.theme)
self.previewTheme()
def onFontFooterXSpinBoxChanged(self):
if self.theme.font_footer_x != self.fontFooterXSpinBox.value():
self.theme.font_footer_x = self.fontFooterXSpinBox.value()
self.previewTheme()
def onFontFooterYSpinBoxChanged(self):
if self.theme.font_footer_y != self.fontFooterYSpinBox.value():
self.theme.font_footer_y = self.fontFooterYSpinBox.value()
self.previewTheme()
def onFontFooterWidthSpinBoxChanged(self):
if self.theme.font_footer_width != self.fontFooterWidthSpinBox.value():
self.theme.font_footer_width = self.fontFooterWidthSpinBox.value()
self.previewTheme()
def onFontFooterHeightSpinBoxChanged(self):
if self.theme.font_footer_height != \
self.fontFooterHeightSpinBox.value():
self.theme.font_footer_height = \
self.fontFooterHeightSpinBox.value()
self.previewTheme()
#
# Background Tab
#
def onGradientComboBoxSelected(self, currentIndex):
self.setBackground(self.backgroundTypeComboBox.currentIndex(),
currentIndex)
def onBackgroundTypeComboBoxSelected(self, currentIndex):
self.setBackground(currentIndex, self.gradientComboBox.currentIndex())
def setBackground(self, background, gradient):
if background == 0: # Solid
self.theme.background_type = u'solid'
if self.theme.background_color is None:
self.theme.background_color = u'#000000'
self.imageLineEdit.setText(u'')
elif background == 1: # Gradient
self.theme.background_type = u'gradient'
if gradient == 0: # Horizontal
self.theme.background_direction = u'horizontal'
elif gradient == 1: # vertical
self.theme.background_direction = u'vertical'
else:
self.theme.background_direction = u'circular'
if self.theme.background_start_color is None:
self.theme.background_start_color = u'#000000'
if self.theme.background_end_color is None:
self.theme.background_end_color = u'#ff0000'
self.imageLineEdit.setText(u'')
else:
self.theme.background_type = u'image'
self.stateChanging(self.theme)
self.previewTheme()
def onColor1PushButtonClicked(self):
if self.theme.background_type == u'solid':
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.background_color), self)
if new_color.isValid():
self.theme.background_color = new_color.name()
self.color1PushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.background_color))
else:
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.background_start_color), self)
if new_color.isValid():
self.theme.background_start_color = new_color.name()
self.color1PushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.background_start_color))
self.previewTheme()
def onColor2PushButtonClicked(self):
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.background_end_color), self)
if new_color.isValid():
self.theme.background_end_color = new_color.name()
self.color2PushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.background_end_color))
self.previewTheme()
#
# Other Tab
#
def onOutlineCheckBoxChanged(self, value):
if value == 2: # checked
self.theme.display_outline = True
else:
self.theme.display_outline = False
self.stateChanging(self.theme)
self.previewTheme()
def onOutlineSpinBoxChanged(self):
if self.theme.display_outline_size != self.outlineSpinBox.value():
self.theme.display_outline_size = self.outlineSpinBox.value()
self.previewTheme()
def onShadowSpinBoxChanged(self):
if self.theme.display_shadow_size != self.shadowSpinBox.value():
self.theme.display_shadow_size = self.shadowSpinBox.value()
self.previewTheme()
def onOutlineColorPushButtonClicked(self):
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.display_outline_color), self)
if new_color.isValid():
self.theme.display_outline_color = new_color.name()
self.outlineColorPushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.display_outline_color))
self.previewTheme()
def onShadowCheckBoxChanged(self, value):
if value == 2: # checked
self.theme.display_shadow = True
else:
self.theme.display_shadow = False
self.stateChanging(self.theme)
self.previewTheme()
def onSlideTransitionCheckBoxChanged(self, value):
if value == 2: # checked
self.theme.display_slide_transition = True
else:
self.theme.display_slide_transition = False
self.stateChanging(self.theme)
self.previewTheme()
def onShadowColorPushButtonClicked(self):
new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.display_shadow_color), self)
if new_color.isValid():
self.theme.display_shadow_color = new_color.name()
self.shadowColorPushButton.setStyleSheet(u'background-color: %s' %
unicode(self.theme.display_shadow_color))
self.previewTheme()
def onHorizontalComboBoxSelected(self, currentIndex):
self.theme.display_horizontal_align = currentIndex
self.stateChanging(self.theme)
self.previewTheme()
def onVerticalComboBoxSelected(self, currentIndex):
self.theme.display_vertical_align = currentIndex
self.stateChanging(self.theme)
self.previewTheme()
#
# Local Methods
#
def paintUi(self, theme):
self.stateChanging(theme)
self.themeNameEdit.setText(self.theme.theme_name)
# Background Tab
self.imageLineEdit.setText(u'')
if theme.background_type == u'solid':
self.backgroundTypeComboBox.setCurrentIndex(0)
elif theme.background_type == u'gradient':
self.backgroundTypeComboBox.setCurrentIndex(1)
else:
self.backgroundTypeComboBox.setCurrentIndex(2)
self.imageLineEdit.setText(self.theme.background_filename)
if self.theme.background_direction == u'horizontal':
self.gradientComboBox.setCurrentIndex(0)
elif self.theme.background_direction == u'vertical':
self.gradientComboBox.setCurrentIndex(1)
else:
self.gradientComboBox.setCurrentIndex(2)
# Font Main Tab
self.fontMainComboBox.setCurrentFont(
QtGui.QFont(self.theme.font_main_name))
self.fontMainSizeSpinBox.setValue(self.theme.font_main_proportion)
if not self.theme.font_main_italics and \
self.theme.font_main_weight == u'Normal':
self.fontMainWeightComboBox.setCurrentIndex(0)
elif not self.theme.font_main_italics and \
self.theme.font_main_weight == u'Bold':
self.fontMainWeightComboBox.setCurrentIndex(1)
elif self.theme.font_main_italics and \
self.theme.font_main_weight == u'Normal':
self.fontMainWeightComboBox.setCurrentIndex(2)
else:
self.fontMainWeightComboBox.setCurrentIndex(3)
self.fontMainXSpinBox.setValue(self.theme.font_main_x)
self.fontMainYSpinBox.setValue(self.theme.font_main_y)
self.fontMainWidthSpinBox.setValue(self.theme.font_main_width)
self.fontMainHeightSpinBox.setValue(self.theme.font_main_height)
# Font Footer Tab
self.fontFooterComboBox.setCurrentFont(
QtGui.QFont(self.theme.font_footer_name))
self.fontFooterSizeSpinBox.setValue(
self.theme.font_footer_proportion)
if not self.theme.font_footer_italics and \
self.theme.font_footer_weight == u'Normal':
self.fontFooterWeightComboBox.setCurrentIndex(0)
elif not self.theme.font_footer_italics and \
self.theme.font_footer_weight == u'Bold':
self.fontFooterWeightComboBox.setCurrentIndex(1)
elif self.theme.font_footer_italics and \
self.theme.font_footer_weight == u'Normal':
self.fontFooterWeightComboBox.setCurrentIndex(2)
else:
self.fontFooterWeightComboBox.setCurrentIndex(3)
self.fontFooterXSpinBox.setValue(self.theme.font_footer_x)
self.fontFooterYSpinBox.setValue(self.theme.font_footer_y)
self.fontFooterWidthSpinBox.setValue(self.theme.font_footer_width)
self.fontFooterHeightSpinBox.setValue(self.theme.font_footer_height)
self.fontMainColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.font_main_color))
self.fontFooterColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.font_footer_color))
if not self.theme.font_main_override:
self.fontMainDefaultCheckBox.setChecked(True)
else:
self.fontMainDefaultCheckBox.setChecked(False)
if not self.theme.font_footer_override:
self.fontFooterDefaultCheckBox.setChecked(True)
else:
self.fontFooterDefaultCheckBox.setChecked(False)
self.outlineColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.display_outline_color))
self.shadowColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.display_shadow_color))
if self.theme.display_outline:
self.outlineCheckBox.setChecked(True)
self.outlineColorPushButton.setEnabled(True)
else:
self.outlineCheckBox.setChecked(False)
self.outlineColorPushButton.setEnabled(False)
self.outlineSpinBox.setValue(int(self.theme.display_outline_size))
if self.theme.display_shadow:
self.shadowCheckBox.setChecked(True)
self.shadowColorPushButton.setEnabled(True)
else:
self.shadowCheckBox.setChecked(False)
self.shadowColorPushButton.setEnabled(False)
self.shadowSpinBox.setValue(int(self.theme.display_shadow_size))
if self.theme.display_slide_transition:
self.slideTransitionCheckBox.setCheckState(QtCore.Qt.Checked)
else:
self.slideTransitionCheckBox.setCheckState(QtCore.Qt.Unchecked)
self.horizontalComboBox.setCurrentIndex(
self.theme.display_horizontal_align)
self.verticalComboBox.setCurrentIndex(self.theme.display_vertical_align)
def stateChanging(self, theme):
self.backgroundTypeComboBox.setVisible(True)
self.backgroundTypeLabel.setVisible(True)
if theme.background_type == u'solid':
self.color1PushButton.setStyleSheet(
u'background-color: %s' % unicode(theme.background_color))
self.color1Label.setText(
translate('OpenLP.AmendThemeForm', 'Color:'))
self.color1Label.setVisible(True)
self.color1PushButton.setVisible(True)
self.color2Label.setVisible(False)
self.color2PushButton.setVisible(False)
self.imageLabel.setVisible(False)
self.imageLineEdit.setVisible(False)
self.imageFilenameWidget.setVisible(False)
self.gradientLabel.setVisible(False)
self.gradientComboBox.setVisible(False)
elif theme.background_type == u'gradient':
self.color1PushButton.setStyleSheet(u'background-color: %s' \
% unicode(theme.background_start_color))
self.color2PushButton.setStyleSheet(u'background-color: %s' \
% unicode(theme.background_end_color))
self.color1Label.setText(
translate('OpenLP.AmendThemeForm', 'First color:'))
self.color2Label.setText(
translate('OpenLP.AmendThemeForm', 'Second color:'))
self.color1Label.setVisible(True)
self.color1PushButton.setVisible(True)
self.color2Label.setVisible(True)
self.color2PushButton.setVisible(True)
self.imageLabel.setVisible(False)
self.imageLineEdit.setVisible(False)
self.imageFilenameWidget.setVisible(False)
self.gradientLabel.setVisible(True)
self.gradientComboBox.setVisible(True)
else: # must be image
self.color1Label.setVisible(False)
self.color1PushButton.setVisible(False)
self.color2Label.setVisible(False)
self.color2PushButton.setVisible(False)
self.imageLabel.setVisible(True)
self.imageLineEdit.setVisible(True)
self.imageFilenameWidget.setVisible(True)
self.gradientLabel.setVisible(False)
self.gradientComboBox.setVisible(False)
if not theme.font_main_override:
self.fontMainXSpinBox.setEnabled(False)
self.fontMainYSpinBox.setEnabled(False)
self.fontMainWidthSpinBox.setEnabled(False)
self.fontMainHeightSpinBox.setEnabled(False)
else:
self.fontMainXSpinBox.setEnabled(True)
self.fontMainYSpinBox.setEnabled(True)
self.fontMainWidthSpinBox.setEnabled(True)
self.fontMainHeightSpinBox.setEnabled(True)
if not theme.font_footer_override:
self.fontFooterXSpinBox.setEnabled(False)
self.fontFooterYSpinBox.setEnabled(False)
self.fontFooterWidthSpinBox.setEnabled(False)
self.fontFooterHeightSpinBox.setEnabled(False)
else:
self.fontFooterXSpinBox.setEnabled(True)
self.fontFooterYSpinBox.setEnabled(True)
self.fontFooterWidthSpinBox.setEnabled(True)
self.fontFooterHeightSpinBox.setEnabled(True)
if self.theme.display_outline:
self.outlineColorPushButton.setEnabled(True)
else:
self.outlineColorPushButton.setEnabled(False)
if self.theme.display_shadow:
self.shadowColorPushButton.setEnabled(True)
else:
self.shadowColorPushButton.setEnabled(False)
def previewTheme(self):
if self.allowPreview:
#calculate main number of rows
metrics = self._getThemeMetrics()
line_height = metrics.height() \
+ int(self.theme.font_main_line_adjustment)
if self.theme.display_shadow:
line_height += int(self.theme.display_shadow_size)
if self.theme.display_outline:
# pixels top/bottom
line_height += 2 * int(self.theme.display_outline_size)
page_length = \
((self.fontMainHeightSpinBox.value()) / line_height )
log.debug(u'Page Length area height %s, metrics %s, lines %s' %
(self.fontMainHeightSpinBox.value(), metrics.height(),
page_length))
page_length_text = unicode(
translate('OpenLP.AmendThemeForm', 'Slide height is %s rows.'))
self.fontMainLinesPageLabel.setText(page_length_text % page_length)
frame = self.thememanager.generateImage(self.theme)
self.themePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
def _getThemeMetrics(self):
main_weight = 50
if self.theme.font_main_weight == u'Bold':
main_weight = 75
mainFont = QtGui.QFont(self.theme.font_main_name,
self.theme.font_main_proportion, # size
main_weight, # weight
self.theme.font_main_italics)# italic
mainFont.setPixelSize(self.theme.font_main_proportion)
metrics = QtGui.QFontMetrics(mainFont)
# Validate that the screen width is big enough to display the text
if self.theme.font_main_width < metrics.maxWidth() * 2 + 64:
self.theme.font_main_width = metrics.maxWidth() * 2 + 64
self.fontMainWidthSpinBox.setValue(self.theme.font_main_width)
return metrics

View File

@ -23,7 +23,8 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
"""
import logging import logging
import os import os
@ -36,6 +37,7 @@ from openlp.core.ui import HideMode
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
#http://www.steveheffernan.com/html5-video-player/demo-video-player.html #http://www.steveheffernan.com/html5-video-player/demo-video-player.html
#http://html5demos.com/two-videos
class DisplayWidget(QtGui.QGraphicsView): class DisplayWidget(QtGui.QGraphicsView):
""" """
@ -99,7 +101,7 @@ class MainDisplay(DisplayWidget):
self.screens = screens self.screens = screens
self.isLive = live self.isLive = live
self.alertTab = None self.alertTab = None
self.hide_mode = None self.hideMode = None
self.setWindowTitle(u'OpenLP Display') self.setWindowTitle(u'OpenLP Display')
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;') self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | self.setWindowFlags(QtCore.Qt.FramelessWindowHint |
@ -228,7 +230,7 @@ class MainDisplay(DisplayWidget):
""" """
API for replacement backgrounds so Images are added directly to cache API for replacement backgrounds so Images are added directly to cache
""" """
image = self.imageManager.add_image(name, path) self.imageManager.add_image(name, path)
self.image(name) self.image(name)
def image(self, name): def image(self, name):
@ -380,8 +382,8 @@ class MainDisplay(DisplayWidget):
if self.isLive: if self.isLive:
self.setVisible(True) self.setVisible(True)
# if was hidden keep it hidden # if was hidden keep it hidden
if self.hide_mode and self.isLive: if self.hideMode and self.isLive:
self.hideDisplay(self.hide_mode) self.hideDisplay(self.hideMode)
preview = QtGui.QImage(self.screen[u'size'].width(), preview = QtGui.QImage(self.screen[u'size'].width(),
self.screen[u'size'].height(), self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied) QtGui.QImage.Format_ARGB32_Premultiplied)
@ -411,8 +413,8 @@ class MainDisplay(DisplayWidget):
if serviceItem.foot_text and serviceItem.foot_text: if serviceItem.foot_text and serviceItem.foot_text:
self.footer(serviceItem.foot_text) self.footer(serviceItem.foot_text)
# if was hidden keep it hidden # if was hidden keep it hidden
if self.hide_mode and self.isLive: if self.hideMode and self.isLive:
self.hideDisplay(self.hide_mode) self.hideDisplay(self.hideMode)
def footer(self, text): def footer(self, text):
""" """
@ -443,7 +445,7 @@ class MainDisplay(DisplayWidget):
self.setVisible(True) self.setVisible(True)
if self.phononActive: if self.phononActive:
self.webView.setVisible(True) self.webView.setVisible(True)
self.hide_mode = mode self.hideMode = mode
def showDisplay(self): def showDisplay(self):
""" """
@ -458,9 +460,9 @@ class MainDisplay(DisplayWidget):
if self.phononActive: if self.phononActive:
self.webView.setVisible(False) self.webView.setVisible(False)
self.videoPlay() self.videoPlay()
self.hideMode = None
# Trigger actions when display is active again # Trigger actions when display is active again
Receiver.send_message(u'maindisplay_active') Receiver.send_message(u'maindisplay_active')
self.hide_mode = None
class AudioPlayer(QtCore.QObject): class AudioPlayer(QtCore.QObject):
""" """

View File

@ -627,7 +627,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# warning cyclic dependency # warning cyclic dependency
# RenderManager needs to call ThemeManager and # RenderManager needs to call ThemeManager and
# ThemeManager needs to call RenderManager # ThemeManager needs to call RenderManager
self.RenderManager = RenderManager( self.renderManager = RenderManager(
self.ThemeManagerContents, self.screens) self.ThemeManagerContents, self.screens)
# Define the media Dock Manager # Define the media Dock Manager
self.mediaDockManager = MediaDockManager(self.MediaToolBox) self.mediaDockManager = MediaDockManager(self.MediaToolBox)
@ -635,7 +635,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# make the controllers available to the plugins # make the controllers available to the plugins
self.plugin_helpers[u'preview'] = self.PreviewController self.plugin_helpers[u'preview'] = self.PreviewController
self.plugin_helpers[u'live'] = self.LiveController self.plugin_helpers[u'live'] = self.LiveController
self.plugin_helpers[u'render'] = self.RenderManager self.plugin_helpers[u'render'] = self.renderManager
self.plugin_helpers[u'service'] = self.ServiceManagerContents self.plugin_helpers[u'service'] = self.ServiceManagerContents
self.plugin_helpers[u'settings form'] = self.settingsForm self.plugin_helpers[u'settings form'] = self.settingsForm
self.plugin_helpers[u'toolbox'] = self.mediaDockManager self.plugin_helpers[u'toolbox'] = self.mediaDockManager
@ -809,7 +809,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
their locations their locations
""" """
log.debug(u'screenChanged') log.debug(u'screenChanged')
self.RenderManager.update_display() self.renderManager.update_display()
self.setFocus() self.setFocus()
self.activateWindow() self.activateWindow()
@ -855,7 +855,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.plugin_manager.finalise_plugins() self.plugin_manager.finalise_plugins()
# Save settings # Save settings
self.saveSettings() self.saveSettings()
#Close down the display # Close down the display
self.LiveController.display.close() self.LiveController.display.close()
def serviceChanged(self, reset=False, serviceName=None): def serviceChanged(self, reset=False, serviceName=None):

View File

@ -116,6 +116,7 @@ class ServiceManager(QtGui.QWidget):
self.layout = QtGui.QVBoxLayout(self) self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0) self.layout.setSpacing(0)
self.layout.setMargin(0) self.layout.setMargin(0)
self.expandTabs = False
# Create the top toolbar # Create the top toolbar
self.toolbar = OpenLPToolbar(self) self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
@ -307,7 +308,7 @@ class ServiceManager(QtGui.QWidget):
self.maintainAction.setVisible(False) self.maintainAction.setVisible(False)
self.notesAction.setVisible(False) self.notesAction.setVisible(False)
if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit)\ 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) self.editAction.setVisible(True)
if serviceItem[u'service_item']\ if serviceItem[u'service_item']\
.is_capable(ItemCapabilities.AllowsMaintain): .is_capable(ItemCapabilities.AllowsMaintain):
@ -758,7 +759,7 @@ class ServiceManager(QtGui.QWidget):
self.onNewService() self.onNewService()
for item in items: for item in items:
serviceitem = ServiceItem() serviceitem = ServiceItem()
serviceitem.render_manager = self.parent.RenderManager serviceitem.render_manager = self.parent.renderManager
serviceitem.set_from_service(item, self.servicePath) serviceitem.set_from_service(item, self.servicePath)
self.validateItem(serviceitem) self.validateItem(serviceitem)
self.addServiceItem(serviceitem) self.addServiceItem(serviceitem)
@ -788,6 +789,8 @@ class ServiceManager(QtGui.QWidget):
self.serviceName = name[len(name) - 1] self.serviceName = name[len(name) - 1]
self.parent.addRecentFile(filename) self.parent.addRecentFile(filename)
self.parent.serviceChanged(True, self.serviceName) self.parent.serviceChanged(True, self.serviceName)
# Refresh Plugin lists
Receiver.send_message(u'plugin_list_refresh')
def validateItem(self, serviceItem): def validateItem(self, serviceItem):
""" """
@ -817,7 +820,7 @@ class ServiceManager(QtGui.QWidget):
""" """
log.debug(u'onThemeComboBoxSelected') log.debug(u'onThemeComboBoxSelected')
self.service_theme = unicode(self.themeComboBox.currentText()) self.service_theme = unicode(self.themeComboBox.currentText())
self.parent.RenderManager.set_service_theme(self.service_theme) self.parent.renderManager.set_service_theme(self.service_theme)
QtCore.QSettings().setValue( QtCore.QSettings().setValue(
self.parent.serviceSettingsSection + u'/service theme', self.parent.serviceSettingsSection + u'/service theme',
QtCore.QVariant(self.service_theme)) QtCore.QVariant(self.service_theme))
@ -829,7 +832,7 @@ class ServiceManager(QtGui.QWidget):
sure the theme combo box is in the correct state. sure the theme combo box is in the correct state.
""" """
log.debug(u'themeChange') log.debug(u'themeChange')
if self.parent.RenderManager.theme_level == ThemeLevel.Global: if self.parent.renderManager.theme_level == ThemeLevel.Global:
self.toolbar.actions[u'ThemeLabel'].setVisible(False) self.toolbar.actions[u'ThemeLabel'].setVisible(False)
self.toolbar.actions[u'ThemeWidget'].setVisible(False) self.toolbar.actions[u'ThemeWidget'].setVisible(False)
else: else:
@ -843,7 +846,7 @@ class ServiceManager(QtGui.QWidget):
""" """
log.debug(u'regenerateServiceItems') log.debug(u'regenerateServiceItems')
# force reset of renderer as theme data has changed # force reset of renderer as theme data has changed
self.parent.RenderManager.themedata = None self.parent.renderManager.themedata = None
if self.serviceItems: if self.serviceItems:
tempServiceItems = self.serviceItems tempServiceItems = self.serviceItems
self.serviceManagerList.clear() self.serviceManagerList.clear()
@ -863,7 +866,7 @@ class ServiceManager(QtGui.QWidget):
editId, uuid = message.split(u':') editId, uuid = message.split(u':')
for item in self.serviceItems: for item in self.serviceItems:
if item[u'service_item']._uuid == uuid: if item[u'service_item']._uuid == uuid:
item[u'service_item'].editId = editId item[u'service_item'].edit_id = editId
def replaceServiceItem(self, newItem): def replaceServiceItem(self, newItem):
""" """
@ -872,7 +875,7 @@ class ServiceManager(QtGui.QWidget):
""" """
newItem.render() newItem.render()
for itemcount, item in enumerate(self.serviceItems): 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: item[u'service_item'].name == newItem.name:
newItem.merge(item[u'service_item']) newItem.merge(item[u'service_item'])
item[u'service_item'] = newItem item[u'service_item'] = newItem
@ -890,8 +893,8 @@ class ServiceManager(QtGui.QWidget):
``expand`` ``expand``
Override the default expand settings. (Tristate) Override the default expand settings. (Tristate)
""" """
log.debug(u'addServiceItem') # if not passed set to config value
if expand == None: if expand is None:
expand = self.expandTabs expand = self.expandTabs
sitem = self.findServiceItem()[0] sitem = self.findServiceItem()[0]
item.render() item.render()
@ -982,7 +985,7 @@ class ServiceManager(QtGui.QWidget):
.is_capable(ItemCapabilities.AllowsEdit): .is_capable(ItemCapabilities.AllowsEdit):
Receiver.send_message(u'%s_edit' % Receiver.send_message(u'%s_edit' %
self.serviceItems[item][u'service_item'].name.lower(), u'L:%s' % 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): def findServiceItem(self):
""" """
@ -1027,6 +1030,9 @@ class ServiceManager(QtGui.QWidget):
# ServiceManager started the drag and drop # ServiceManager started the drag and drop
if plugin == u'ServiceManager': if plugin == u'ServiceManager':
startpos, startCount = self.findServiceItem() startpos, startCount = self.findServiceItem()
# If no items selected
if startpos == -1:
return
if item is None: if item is None:
endpos = len(self.serviceItems) endpos = len(self.serviceItems)
else: else:
@ -1082,7 +1088,7 @@ class ServiceManager(QtGui.QWidget):
index = 0 index = 0
self.service_theme = u'' self.service_theme = u''
self.themeComboBox.setCurrentIndex(index) self.themeComboBox.setCurrentIndex(index)
self.parent.RenderManager.set_service_theme(self.service_theme) self.parent.renderManager.set_service_theme(self.service_theme)
self.regenerateServiceItems() self.regenerateServiceItems()
def onThemeChangeAction(self): def onThemeChangeAction(self):

View File

@ -331,10 +331,8 @@ class SlideController(QtGui.QWidget):
QtCore.QObject.connect(self.PreviewListWidget, QtCore.QObject.connect(self.PreviewListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected) QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
if not self.isLive: if not self.isLive:
if QtCore.QSettings().value(u'advanced/double click live', QtCore.QObject.connect(self.PreviewListWidget,
QtCore.QVariant(False)).toBool(): QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onGoLiveClick)
QtCore.QObject.connect(self.PreviewListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onGoLive)
if isLive: if isLive:
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_live_spin_delay'), QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
@ -391,6 +389,8 @@ class SlideController(QtGui.QWidget):
if self.isLive: if self.isLive:
QtCore.QObject.connect(self.volumeSlider, QtCore.QObject.connect(self.volumeSlider,
QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume) QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_active'), self.updatePreview)
def screenSizeChanged(self): def screenSizeChanged(self):
""" """
@ -400,7 +400,7 @@ class SlideController(QtGui.QWidget):
log.debug(u'screenSizeChanged live = %s' % self.isLive) log.debug(u'screenSizeChanged live = %s' % self.isLive)
# rebuild display as screen size changed # rebuild display as screen size changed
self.display = MainDisplay(self, self.screens, self.isLive) self.display = MainDisplay(self, self.screens, self.isLive)
self.display.imageManager = self.parent.RenderManager.image_manager self.display.imageManager = self.parent.renderManager.image_manager
self.display.alertTab = self.alertTab self.display.alertTab = self.alertTab
self.ratio = float(self.screens.current[u'size'].width()) / \ self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height()) float(self.screens.current[u'size'].height())
@ -416,7 +416,7 @@ class SlideController(QtGui.QWidget):
""" """
log.debug(u'widthChanged live = %s' % self.isLive) log.debug(u'widthChanged live = %s' % self.isLive)
width = self.parent.ControlSplitter.sizes()[self.split] width = self.parent.ControlSplitter.sizes()[self.split]
height = width * self.parent.RenderManager.screen_ratio height = width * self.parent.renderManager.screen_ratio
self.PreviewListWidget.setColumnWidth(0, width) self.PreviewListWidget.setColumnWidth(0, width)
# Sort out image heights (Songs, bibles excluded) # Sort out image heights (Songs, bibles excluded)
if self.serviceItem and not self.serviceItem.is_text(): if self.serviceItem and not self.serviceItem.is_text():
@ -595,14 +595,14 @@ class SlideController(QtGui.QWidget):
label.setScaledContents(True) label.setScaledContents(True)
if self.serviceItem.is_command(): if self.serviceItem.is_command():
image = resize_image(frame[u'image'], image = resize_image(frame[u'image'],
self.parent.RenderManager.width, self.parent.renderManager.width,
self.parent.RenderManager.height) self.parent.renderManager.height)
else: else:
image = self.parent.RenderManager.image_manager. \ image = self.parent.renderManager.image_manager. \
get_image(frame[u'title']) get_image(frame[u'title'])
label.setPixmap(QtGui.QPixmap.fromImage(image)) label.setPixmap(QtGui.QPixmap.fromImage(image))
self.PreviewListWidget.setCellWidget(framenumber, 0, label) self.PreviewListWidget.setCellWidget(framenumber, 0, label)
slideHeight = width * self.parent.RenderManager.screen_ratio slideHeight = width * self.parent.renderManager.screen_ratio
row += 1 row += 1
text.append(unicode(row)) text.append(unicode(row))
self.PreviewListWidget.setItem(framenumber, 0, item) self.PreviewListWidget.setItem(framenumber, 0, item)
@ -823,16 +823,15 @@ class SlideController(QtGui.QWidget):
row) row)
def updatePreview(self): def updatePreview(self):
log.debug(u'updatePreview %s ' %self.screens.current[u'primary'])
if not self.screens.current[u'primary']: if not self.screens.current[u'primary']:
# Grab now, but try again in a couple of seconds if slide change # Grab now, but try again in a couple of seconds if slide change
# is slow # is slow
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay) QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
QtCore.QTimer.singleShot(2.5, self.grabMainDisplay) QtCore.QTimer.singleShot(2.5, self.grabMainDisplay)
else: else:
label = self.PreviewListWidget.cellWidget( self.SlidePreview.setPixmap(
self.PreviewListWidget.currentRow(), 1) QtGui.QPixmap.fromImage(self.display.preview()))
if label:
self.SlidePreview.setPixmap(label.pixmap())
def grabMainDisplay(self): def grabMainDisplay(self):
winid = QtGui.QApplication.desktop().winId() winid = QtGui.QApplication.desktop().winId()
@ -942,7 +941,15 @@ class SlideController(QtGui.QWidget):
""" """
self.songEdit = True self.songEdit = True
Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(), Receiver.send_message(u'%s_edit' % self.serviceItem.name.lower(),
u'P:%s' % self.serviceItem.editId) u'P:%s' % self.serviceItem.edit_id)
def onGoLiveClick(self):
"""
triggered by clicking the Preview slide items
"""
if QtCore.QSettings().value(u'advanced/double click live',
QtCore.QVariant(False)).toBool():
self.onGoLive()
def onGoLive(self): def onGoLive(self):
""" """

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

@ -0,0 +1,622 @@
# -*- 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
self.updateThemeAllowed = True
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.colorButton,
QtCore.SIGNAL(u'pressed()'),
self.onColorButtonClicked)
QtCore.QObject.connect(self.gradientStartButton,
QtCore.SIGNAL(u'pressed()'),
self.onGradientStartButtonClicked)
QtCore.QObject.connect(self.gradientEndButton,
QtCore.SIGNAL(u'pressed()'),
self.onGradientEndButtonClicked)
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', self.colorButton)
self.backgroundPage.registerField(
u'grandient_start', self.gradientStartButton)
self.backgroundPage.registerField(
u'grandient_end', self.gradientEndButton)
self.backgroundPage.registerField(
u'background_image', self.imageLineEdit)
self.backgroundPage.registerField(
u'gradient', self.gradientComboBox)
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, edit=False):
"""
Run the wizard.
"""
self.updateThemeAllowed = False
self.setDefaults()
self.updateThemeAllowed = True
if edit:
self.next()
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.colorButton.setStyleSheet(u'background-color: %s' %
self.theme.background_color)
self.setField(u'background_type', QtCore.QVariant(0))
elif self.theme.background_type == \
BackgroundType.to_string(BackgroundType.Gradient):
self.gradientStartButton.setStyleSheet(u'background-color: %s' %
self.theme.background_start_color)
self.gradientEndButton.setStyleSheet(u'background-color: %s' %
self.theme.background_end_color)
self.setField(u'background_type', QtCore.QVariant(1))
else:
self.imageLineEdit.setText(self.theme.background_filename)
self.setField(u'background_type', QtCore.QVariant(2))
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 onColorButtonClicked(self):
"""
Background / Gradient 1 Color button pushed.
"""
self.theme.background_color = \
self._colorButton(self.theme.background_color)
self.setBackgroundTabValues()
def onGradientStartButtonClicked(self):
"""
Gradient 2 Color button pushed.
"""
self.theme.background_start_color = \
self._colorButton(self.theme.background_start_color)
self.setBackgroundTabValues()
def onGradientEndButtonClicked(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 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.
"""
if not self.updateThemeAllowed:
return
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
# 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
self.accepted = True
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 xml.etree.ElementTree import ElementTree, XML
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.ui import AmendThemeForm, FileRenameForm from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.theme import Theme from openlp.core.theme import Theme
from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \ from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \
build_icon, Receiver, SettingsManager, translate, check_item_selected build_icon, Receiver, SettingsManager, translate, check_item_selected, \
BackgroundType, BackgroundGradientType
from openlp.core.utils import AppLocation, get_filesystem_encoding from openlp.core.utils import AppLocation, get_filesystem_encoding
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -52,7 +53,7 @@ class ThemeManager(QtGui.QWidget):
self.layout = QtGui.QVBoxLayout(self) self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0) self.layout.setSpacing(0)
self.layout.setMargin(0) self.layout.setMargin(0)
self.amendThemeForm = AmendThemeForm(self) self.themeForm = ThemeForm(self)
self.fileRenameForm = FileRenameForm(self) self.fileRenameForm = FileRenameForm(self)
self.toolbar = OpenLPToolbar(self) self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
@ -125,7 +126,7 @@ class ThemeManager(QtGui.QWidget):
self.checkThemesExists(self.path) self.checkThemesExists(self.path)
self.thumbPath = os.path.join(self.path, u'thumbnails') self.thumbPath = os.path.join(self.path, u'thumbnails')
self.checkThemesExists(self.thumbPath) self.checkThemesExists(self.thumbPath)
self.amendThemeForm.path = self.path self.themeForm.path = self.path
self.oldBackgroundImage = None self.oldBackgroundImage = None
self.editingDefault = False self.editingDefault = False
# Last little bits of setting up # Last little bits of setting up
@ -180,7 +181,7 @@ class ThemeManager(QtGui.QWidget):
'%s (default)')) % newName '%s (default)')) % newName
self.themeListWidget.item(count).setText(name) 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 Change the global theme when a theme is double clicked upon in the
Theme Manager list Theme Manager list
@ -213,10 +214,10 @@ class ThemeManager(QtGui.QWidget):
Loads a new theme with the default settings and then launches the theme Loads a new theme with the default settings and then launches the theme
editing form for the user to make their customisations. editing form for the user to make their customisations.
""" """
theme = self.createThemeFromXml(self.baseTheme(), self.path) theme = ThemeXML()
self.amendThemeForm.loadTheme(theme)
self.saveThemeName = u'' self.saveThemeName = u''
self.amendThemeForm.exec_() self.themeForm.theme = theme
self.themeForm.exec_()
def onRenameTheme(self): def onRenameTheme(self):
""" """
@ -242,67 +243,23 @@ class ThemeManager(QtGui.QWidget):
self.saveThemeName = u'' self.saveThemeName = u''
if self.fileRenameForm.exec_(): if self.fileRenameForm.exec_():
newThemeName = unicode(self.fileRenameForm.FileNameEdit.text()) newThemeName = unicode(self.fileRenameForm.FileNameEdit.text())
oldThemeData = self.getThemeData(oldThemeName) themeData = self.getThemeData(oldThemeName)
self.cloneThemeData(oldThemeData, newThemeName) self.cloneThemeData(themeData, newThemeName)
self.loadThemes() self.loadThemes()
def cloneThemeData(self, oldThemeData, newThemeName): def cloneThemeData(self, themeData, newThemeName):
""" """
Takes a theme and makes a new copy of it as well as saving it.
""" """
log.debug(u'cloneThemeData') log.debug(u'cloneThemeData')
new_theme = ThemeXML() saveTo = None
new_theme.new_document(newThemeName) saveFrom = None
save_from = None if themeData.background_type == u'image':
save_to = None saveTo = os.path.join(self.path, newThemeName,
if oldThemeData.background_type == u'solid': os.path.split(unicode(themeData.background_filename))[1])
new_theme.add_background_solid( saveFrom = themeData.background_filename
unicode(oldThemeData.background_color)) themeData.theme_name = newThemeName
elif oldThemeData.background_type == u'gradient': self.saveTheme(themeData, saveFrom, saveTo)
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)
def onEditTheme(self): def onEditTheme(self):
""" """
@ -320,10 +277,10 @@ class ThemeManager(QtGui.QWidget):
unicode(item.data(QtCore.Qt.UserRole).toString())) unicode(item.data(QtCore.Qt.UserRole).toString()))
if theme.background_type == u'image': if theme.background_type == u'image':
self.oldBackgroundImage = theme.background_filename self.oldBackgroundImage = theme.background_filename
self.amendThemeForm.loadTheme(theme)
self.saveThemeName = unicode( self.saveThemeName = unicode(
item.data(QtCore.Qt.UserRole).toString()) item.data(QtCore.Qt.UserRole).toString())
self.amendThemeForm.exec_() self.themeForm.theme = theme
self.themeForm.exec_(True)
def onDeleteTheme(self): def onDeleteTheme(self):
""" """
@ -340,7 +297,8 @@ class ThemeManager(QtGui.QWidget):
# confirm deletion # confirm deletion
answer = QtGui.QMessageBox.question(self, answer = QtGui.QMessageBox.question(self,
translate('OpenLP.ThemeManager', 'Delete Confirmation'), translate('OpenLP.ThemeManager', 'Delete Confirmation'),
translate('OpenLP.ThemeManager', 'Delete theme?'), unicode(translate('OpenLP.ThemeManager', 'Delete %s theme?'))
% theme,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No), QtGui.QMessageBox.No) QtGui.QMessageBox.No), QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No: if answer == QtGui.QMessageBox.No:
@ -462,6 +420,7 @@ class ThemeManager(QtGui.QWidget):
self.themelist = [] self.themelist = []
self.themeListWidget.clear() self.themeListWidget.clear()
dirList = os.listdir(self.path) dirList = os.listdir(self.path)
dirList.sort()
for name in dirList: for name in dirList:
if name.endswith(u'.png'): if name.endswith(u'.png'):
# check to see file is in theme root directory # check to see file is in theme root directory
@ -500,20 +459,21 @@ class ThemeManager(QtGui.QWidget):
""" """
return self.themelist return self.themelist
def getThemeData(self, themename): def getThemeData(self, themeName):
""" """
Returns a theme object from an XML file Returns a theme object from an XML file
``themename`` ``themeName``
Name of the theme to load from file Name of the theme to load from file
""" """
log.debug(u'getthemedata for theme %s', themename) log.debug(u'getthemedata for theme %s', themeName)
xml_file = os.path.join(self.path, unicode(themename), xmlFile = os.path.join(self.path, unicode(themeName),
unicode(themename) + u'.xml') unicode(themeName) + u'.xml')
xml = get_text_file_string(xml_file) xml = get_text_file_string(xmlFile)
if not xml: if not xml:
xml = self.baseTheme() return self.baseTheme()
return self.createThemeFromXml(xml, self.path) else:
return self.createThemeFromXml(xml, self.path)
def checkThemesExists(self, dir): def checkThemesExists(self, dir):
""" """
@ -584,7 +544,8 @@ class ThemeManager(QtGui.QWidget):
outfile = open(fullpath, u'wb') outfile = open(fullpath, u'wb')
outfile.write(zip.read(file)) outfile.write(zip.read(file))
if filexml: if filexml:
self.generateAndSaveImage(dir, themename, filexml) theme = self.createThemeFromXml(filexml, self.path)
self.generateAndSaveImage(dir, themename, theme)
else: else:
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('OpenLP.ThemeManager', 'Error'), translate('OpenLP.ThemeManager', 'Error'),
@ -631,50 +592,60 @@ class ThemeManager(QtGui.QWidget):
""" """
theme = Theme(xml_data) theme = Theme(xml_data)
newtheme = ThemeXML() newtheme = ThemeXML()
newtheme.new_document(theme.Name) newtheme.theme_name = theme.Name
if theme.BackgroundType == 0: if theme.BackgroundType == 0:
newtheme.add_background_solid(unicode( newtheme.background_type = \
theme.BackgroundParameter1.name())) BackgroundType.to_string(BackgroundType.Solid)
newtheme.background_color = \
unicode(theme.BackgroundParameter1.name())
elif theme.BackgroundType == 1: elif theme.BackgroundType == 1:
direction = u'vertical' newtheme.background_type = \
BackgroundType.to_string(BackgroundType.Gradient)
newtheme.background_direction = \
BackgroundGradientType. \
to_string(BackgroundGradientType.Horizontal)
if theme.BackgroundParameter3.name() == 1: if theme.BackgroundParameter3.name() == 1:
direction = u'horizontal' newtheme.background_direction = \
newtheme.add_background_gradient( BackgroundGradientType. \
unicode(theme.BackgroundParameter1.name()), to_string(BackgroundGradientType.Horizontal)
unicode(theme.BackgroundParameter2.name()), direction) newtheme.background_start_color = \
unicode(theme.BackgroundParameter1.name())
newtheme.background_end_color = \
unicode(theme.BackgroundParameter2.name())
else: else:
newtheme.add_background_image(unicode(theme.BackgroundParameter1)) newtheme.background_type = \
newtheme.add_font(unicode(theme.FontName), BackgroundType.to_string(BackgroundType.Image)
unicode(theme.FontColor.name()), newtheme.background_filename = unicode(theme.BackgroundParameter1)
unicode(theme.FontProportion * 3), u'False') newtheme.font_main_name = theme.FontName
newtheme.add_font(unicode(theme.FontName), newtheme.font_main_color = unicode(theme.FontColor.name())
unicode(theme.FontColor.name()), newtheme.font_main_size = theme.FontProportion * 3
unicode(12), u'False', u'footer') newtheme.font_footer_name = theme.FontName
outline = False newtheme.font_footer_color = unicode(theme.FontColor.name())
shadow = False newtheme.font_main_shadow = False
if theme.Shadow == 1: if theme.Shadow == 1:
shadow = True newtheme.font_main_shadow = True
newtheme.font_main_shadow_color = unicode(theme.ShadowColor.name())
if theme.Outline == 1: if theme.Outline == 1:
outline = True newtheme.font_main_outline = True
newtheme.font_main_outline_color = \
unicode(theme.OutlineColor.name())
vAlignCorrection = 0 vAlignCorrection = 0
if theme.VerticalAlign == 2: if theme.VerticalAlign == 2:
vAlignCorrection = 1 vAlignCorrection = 1
elif theme.VerticalAlign == 1: elif theme.VerticalAlign == 1:
vAlignCorrection = 2 vAlignCorrection = 2
newtheme.add_display(unicode(shadow), newtheme.display_horizontal_align = theme.HorizontalAlign
unicode(theme.ShadowColor.name()), newtheme.display_vertical_align = vAlignCorrection
unicode(outline), unicode(theme.OutlineColor.name()),
unicode(theme.HorizontalAlign), unicode(vAlignCorrection),
unicode(theme.WrapStyle), unicode(0))
return newtheme.extract_xml() return newtheme.extract_xml()
def saveTheme(self, name, theme_xml, theme_pretty_xml, image_from, def saveTheme(self, theme, imageFrom, imageTo):
image_to):
""" """
Called by thememaintenance Dialog to save the theme Called by thememaintenance Dialog to save the theme
and to trigger the reload of the theme list and to trigger the reload of the theme list
""" """
log.debug(u'saveTheme %s %s', name, theme_xml) name = theme.theme_name
theme_pretty_xml = theme.extract_formatted_xml()
log.debug(u'saveTheme %s %s', name, theme_pretty_xml)
theme_dir = os.path.join(self.path, name) theme_dir = os.path.join(self.path, name)
if not os.path.exists(theme_dir): if not os.path.exists(theme_dir):
os.mkdir(os.path.join(self.path, name)) os.mkdir(os.path.join(self.path, name))
@ -700,8 +671,8 @@ class ThemeManager(QtGui.QWidget):
self.deleteTheme(self.saveThemeName) self.deleteTheme(self.saveThemeName)
if result == QtGui.QMessageBox.Yes: if result == QtGui.QMessageBox.Yes:
# Save the theme, overwriting the existing theme if necessary. # Save the theme, overwriting the existing theme if necessary.
if image_to and self.oldBackgroundImage and \ if imageTo and self.oldBackgroundImage and \
image_to != self.oldBackgroundImage: imageTo != self.oldBackgroundImage:
try: try:
os.remove(self.oldBackgroundImage) os.remove(self.oldBackgroundImage)
except OSError: except OSError:
@ -715,15 +686,15 @@ class ThemeManager(QtGui.QWidget):
finally: finally:
if outfile: if outfile:
outfile.close() outfile.close()
if image_from and image_from != image_to: if imageFrom and imageFrom != imageTo:
try: try:
encoding = get_filesystem_encoding() encoding = get_filesystem_encoding()
shutil.copyfile( shutil.copyfile(
unicode(image_from).encode(encoding), unicode(imageFrom).encode(encoding),
unicode(image_to).encode(encoding)) unicode(imageTo).encode(encoding))
except IOError: except IOError:
log.exception(u'Failed to save theme image') log.exception(u'Failed to save theme image')
self.generateAndSaveImage(self.path, name, theme_xml) self.generateAndSaveImage(self.path, name, theme)
self.loadThemes() self.loadThemes()
# Check if we need to set a new service theme # Check if we need to set a new service theme
if editedServiceTheme: if editedServiceTheme:
@ -748,14 +719,15 @@ class ThemeManager(QtGui.QWidget):
self.global_theme) self.global_theme)
self.editingDefault = False self.editingDefault = False
self.pushThemes() self.pushThemes()
return True
else: else:
# Don't close the dialog - allow the user to change the name of # Don't close the dialog - allow the user to change the name of
# the theme or to cancel the theme dialog completely. # the theme or to cancel the theme dialog completely.
return False return False
def generateAndSaveImage(self, dir, name, theme_xml): def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s %s', dir, name, theme_xml) log.debug(u'generateAndSaveImage %s %s', dir, name)
theme = self.createThemeFromXml(theme_xml, dir) theme_xml = theme.extract_xml()
frame = self.generateImage(theme) frame = self.generateImage(theme)
samplepathname = os.path.join(self.path, name + u'.png') samplepathname = os.path.join(self.path, name + u'.png')
if os.path.exists(samplepathname): if os.path.exists(samplepathname):
@ -767,12 +739,18 @@ class ThemeManager(QtGui.QWidget):
pixmap.save(thumb, u'png') pixmap.save(thumb, u'png')
log.debug(u'Theme image written to %s', samplepathname) 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 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) log.debug(u'generateImage \n%s ', themeData)
return self.parent.RenderManager.generate_preview(themedata) return self.parent.renderManager.generate_preview(themeData, forcePage)
def getPreviewImage(self, theme): def getPreviewImage(self, theme):
""" """
@ -791,25 +769,16 @@ class ThemeManager(QtGui.QWidget):
""" """
log.debug(u'base theme created') log.debug(u'base theme created')
newtheme = ThemeXML() newtheme = ThemeXML()
newtheme.new_document( return newtheme
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()
def createThemeFromXml(self, theme_xml, path): def createThemeFromXml(self, themeXml, path):
""" """
Return a theme object using information parsed from XML Return a theme object using information parsed from XML
``theme_xml`` ``themeXml``
The XML data to load into the theme The XML data to load into the theme
""" """
theme = ThemeXML() theme = ThemeXML()
theme.parse(theme_xml) theme.parse(themeXml)
theme.extend_image_filename(path) theme.extend_image_filename(path)
return theme return theme

View File

@ -153,7 +153,7 @@ class ThemesTab(SettingsTab):
settings.setValue(u'global theme', settings.setValue(u'global theme',
QtCore.QVariant(self.global_theme)) QtCore.QVariant(self.global_theme))
settings.endGroup() settings.endGroup()
self.parent.RenderManager.set_global_theme( self.parent.renderManager.set_global_theme(
self.global_theme, self.theme_level) self.global_theme, self.theme_level)
Receiver.send_message(u'theme_update_global', self.global_theme) Receiver.send_message(u'theme_update_global', self.global_theme)
@ -171,7 +171,7 @@ class ThemesTab(SettingsTab):
def onDefaultComboBoxChanged(self, value): def onDefaultComboBoxChanged(self, value):
self.global_theme = unicode(self.DefaultComboBox.currentText()) self.global_theme = unicode(self.DefaultComboBox.currentText())
self.parent.RenderManager.set_global_theme( self.parent.renderManager.set_global_theme(
self.global_theme, self.theme_level) self.global_theme, self.theme_level)
image = self.parent.ThemeManagerContents.getPreviewImage( image = self.parent.ThemeManagerContents.getPreviewImage(
self.global_theme) self.global_theme)
@ -183,9 +183,14 @@ class ThemesTab(SettingsTab):
def updateThemeList(self, theme_list): def updateThemeList(self, theme_list):
""" """
Called from ThemeManager when the Themes have changed Called from ThemeManager when the Themes have changed.
``theme_list``
The list of available themes::
[u'Bible Theme', u'Song Theme']
""" """
#reload as may have been triggered by the ThemeManager # Reload as may have been triggered by the ThemeManager.
self.global_theme = unicode(QtCore.QSettings().value( self.global_theme = unicode(QtCore.QSettings().value(
self.settingsSection + u'/global theme', self.settingsSection + u'/global theme',
QtCore.QVariant(u'')).toString()) QtCore.QVariant(u'')).toString())
@ -198,7 +203,7 @@ class ThemesTab(SettingsTab):
id = 0 # Not Found id = 0 # Not Found
self.global_theme = u'' self.global_theme = u''
self.DefaultComboBox.setCurrentIndex(id) self.DefaultComboBox.setCurrentIndex(id)
self.parent.RenderManager.set_global_theme( self.parent.renderManager.set_global_theme(
self.global_theme, self.theme_level) self.global_theme, self.theme_level)
if self.global_theme is not u'': if self.global_theme is not u'':
image = self.parent.ThemeManagerContents.getPreviewImage( image = self.parent.ThemeManagerContents.getPreviewImage(

View File

@ -0,0 +1,757 @@
# -*- 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'OpenLP.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.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
QtGui.QPixmap(u':/wizards/wizard_createtheme.bmp'))
self.welcomeLayout = QtGui.QHBoxLayout(self.welcomePage)
self.welcomeLayout.setSpacing(8)
self.welcomeLayout.setMargin(0)
self.welcomeLayout.setObjectName(u'welcomeLayout')
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)
self.welcomeTopSpacer = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
self.welcomePageLayout.addItem(self.welcomeTopSpacer)
self.informationLabel = QtGui.QLabel(self.welcomePage)
self.informationLabel.setWordWrap(True)
self.informationLabel.setMargin(10)
self.informationLabel.setObjectName(u'informationLabel')
self.welcomePageLayout.addWidget(self.informationLabel)
self.welcomeBottomSpacer = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.welcomePageLayout.addItem(self.welcomeBottomSpacer)
self.welcomeLayout.addLayout(self.welcomePageLayout)
ThemeWizard.addPage(self.welcomePage)
self.backgroundPage = QtGui.QWizardPage()
self.backgroundPage.setObjectName(u'backgroundPage')
self.backgroundLayout = QtGui.QVBoxLayout(self.backgroundPage)
self.backgroundLayout.setSpacing(8)
self.backgroundLayout.setMargin(20)
self.backgroundLayout.setObjectName(u'backgroundLayout')
self.backgroundTypeLayout = QtGui.QHBoxLayout()
self.backgroundTypeLayout.setSpacing(8)
self.backgroundTypeLayout.setObjectName(u'backgroundTypeLayout')
self.backgroundTypeLabel = QtGui.QLabel(self.backgroundPage)
self.backgroundTypeLabel.setObjectName(u'backgroundTypeLabel')
self.backgroundTypeLayout.addWidget(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.backgroundTypeLayout.addWidget(self.backgroundTypeComboBox)
self.backgroundTypeSpacer = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.backgroundTypeLayout.addItem(self.backgroundTypeSpacer)
self.backgroundLayout.addLayout(self.backgroundTypeLayout)
self.backgroundStackedWidget = QtGui.QStackedWidget(
self.backgroundPage)
self.backgroundStackedWidget.setObjectName(u'backgroundStackedWidget')
self.colorPage = QtGui.QWidget()
self.colorPage.setObjectName(u'colorPage')
self.colorLayout = QtGui.QFormLayout(self.colorPage)
self.colorLayout.setMargin(0)
self.colorLayout.setSpacing(8)
self.colorLayout.setObjectName(u'colorLayout')
self.colorLabel = QtGui.QLabel(self.colorPage)
self.colorLabel.setMinimumSize(QtCore.QSize(103, 0))
self.colorLabel.setAlignment(QtCore.Qt.AlignRight |
QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.colorLabel.setObjectName(u'colorLabel')
self.colorLayout.setWidget(0,
QtGui.QFormLayout.LabelRole, self.colorLabel)
self.colorButton = QtGui.QPushButton(self.colorPage)
self.colorButton.setText(u'')
self.colorButton.setObjectName(u'colorButton')
self.colorLayout.setWidget(0,
QtGui.QFormLayout.FieldRole, self.colorButton)
self.backgroundStackedWidget.addWidget(self.colorPage)
self.gradientPage = QtGui.QWidget()
self.gradientPage.setObjectName(u'gradientPage')
self.gradientLayout = QtGui.QFormLayout(self.gradientPage)
self.gradientLayout.setMargin(0)
self.gradientLayout.setSpacing(8)
self.gradientLayout.setObjectName(u'gradientLayout')
self.gradientStartLabel = QtGui.QLabel(self.gradientPage)
self.gradientStartLabel.setMinimumSize(QtCore.QSize(103, 0))
self.gradientStartLabel.setAlignment(QtCore.Qt.AlignRight |
QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.gradientStartLabel.setObjectName(u'gradientStartLabel')
self.gradientLayout.setWidget(0,
QtGui.QFormLayout.LabelRole, self.gradientStartLabel)
self.gradientStartButton = QtGui.QPushButton(self.gradientPage)
self.gradientStartButton.setText(u'')
self.gradientStartButton.setObjectName(u'gradientStartButton')
self.gradientLayout.setWidget(0,
QtGui.QFormLayout.FieldRole, self.gradientStartButton)
self.gradientEndLabel = QtGui.QLabel(self.gradientPage)
self.gradientEndLabel.setMinimumSize(QtCore.QSize(103, 0))
self.gradientEndLabel.setAlignment(QtCore.Qt.AlignRight |
QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.gradientEndLabel.setObjectName(u'gradientEndLabel')
self.gradientLayout.setWidget(1,
QtGui.QFormLayout.LabelRole, self.gradientEndLabel)
self.gradientEndButton = QtGui.QPushButton(self.gradientPage)
self.gradientEndButton.setText(u'')
self.gradientEndButton.setObjectName(u'gradientEndButton')
self.gradientLayout.setWidget(1,
QtGui.QFormLayout.FieldRole, self.gradientEndButton)
self.gradientTypeLabel = QtGui.QLabel(self.gradientPage)
self.gradientTypeLabel.setMinimumSize(QtCore.QSize(103, 0))
self.gradientTypeLabel.setAlignment(QtCore.Qt.AlignRight |
QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.gradientTypeLabel.setObjectName(u'gradientTypeLabel')
self.gradientLayout.setWidget(2,
QtGui.QFormLayout.LabelRole, self.gradientTypeLabel)
self.gradientComboBox = QtGui.QComboBox(self.gradientPage)
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.gradientLayout.setWidget(2,
QtGui.QFormLayout.FieldRole, self.gradientComboBox)
self.backgroundStackedWidget.addWidget(self.gradientPage)
self.imagePage = QtGui.QWidget()
self.imagePage.setObjectName(u'imagePage')
self.imageLayout = QtGui.QFormLayout(self.imagePage)
self.imageLayout.setMargin(0)
self.imageLayout.setSpacing(8)
self.imageLayout.setObjectName(u'imageLayout')
self.imageLabel = QtGui.QLabel(self.imagePage)
self.imageLabel.setMinimumSize(QtCore.QSize(103, 0))
self.imageLabel.setAlignment(QtCore.Qt.AlignRight |
QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.imageLabel.setObjectName(u'imageLabel')
self.imageLayout.setWidget(0,
QtGui.QFormLayout.LabelRole, self.imageLabel)
self.imageFileLayout = QtGui.QHBoxLayout()
self.imageFileLayout.setSpacing(8)
self.imageFileLayout.setObjectName(u'imageFileLayout')
self.imageLineEdit = QtGui.QLineEdit(self.imagePage)
self.imageLineEdit.setObjectName(u'imageLineEdit')
self.imageFileLayout.addWidget(self.imageLineEdit)
self.imageBrowseButton = QtGui.QToolButton(self.imagePage)
self.imageBrowseButton.setText(u'')
self.imageBrowseButton.setIcon(
build_icon(u':/general/general_open.png'))
self.imageBrowseButton.setObjectName(u'imageBrowseButton')
self.imageFileLayout.addWidget(self.imageBrowseButton)
self.imageLayout.setLayout(0,
QtGui.QFormLayout.FieldRole, self.imageFileLayout)
self.backgroundStackedWidget.addWidget(self.imagePage)
self.backgroundLayout.addWidget(self.backgroundStackedWidget)
ThemeWizard.addPage(self.backgroundPage)
self.mainAreaPage = QtGui.QWizardPage()
self.mainAreaPage.setObjectName(u'mainAreaPage')
self.mainAreaLayout = QtGui.QFormLayout(self.mainAreaPage)
self.mainAreaLayout.setFormAlignment(QtCore.Qt.AlignLeading |
QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
self.mainAreaLayout.setMargin(20)
self.mainAreaLayout.setSpacing(8)
self.mainAreaLayout.setObjectName(u'mainAreaLayout')
self.mainFontLabel = QtGui.QLabel(self.mainAreaPage)
self.mainFontLabel.setMinimumSize(QtCore.QSize(103, 0))
self.mainFontLabel.setAlignment(QtCore.Qt.AlignRight |
QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.mainFontLabel.setObjectName(u'mainFontLabel')
self.mainAreaLayout.setWidget(0,
QtGui.QFormLayout.LabelRole, self.mainFontLabel)
self.mainFontComboBox = QtGui.QFontComboBox(self.mainAreaPage)
self.mainFontComboBox.setObjectName(u'mainFontComboBox')
self.mainAreaLayout.setWidget(0,
QtGui.QFormLayout.FieldRole, self.mainFontComboBox)
self.mainColorLabel = QtGui.QLabel(self.mainAreaPage)
self.mainColorLabel.setObjectName(u'mainColorLabel')
self.mainAreaLayout.setWidget(1,
QtGui.QFormLayout.LabelRole, self.mainColorLabel)
self.fontPropertiesLayout = QtGui.QHBoxLayout()
self.fontPropertiesLayout.setSpacing(24)
self.fontPropertiesLayout.setObjectName(u'fontPropertiesLayout')
self.mainColorPushButton = QtGui.QPushButton(self.mainAreaPage)
self.mainColorPushButton.setText(u'')
self.mainColorPushButton.setObjectName(u'mainColorPushButton')
self.fontPropertiesLayout.addWidget(self.mainColorPushButton)
self.boldCheckBox = QtGui.QCheckBox(self.mainAreaPage)
self.boldCheckBox.setObjectName(u'boldCheckBox')
self.fontPropertiesLayout.addWidget(self.boldCheckBox)
self.italicsCheckBox = QtGui.QCheckBox(self.mainAreaPage)
self.italicsCheckBox.setObjectName(u'italicsCheckBox')
self.fontPropertiesLayout.addWidget(self.italicsCheckBox)
self.mainAreaLayout.setLayout(1,
QtGui.QFormLayout.FieldRole, self.fontPropertiesLayout)
self.mainSizeLabel = QtGui.QLabel(self.mainAreaPage)
self.mainSizeLabel.setObjectName(u'mainSizeLabel')
self.mainAreaLayout.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.mainAreaLayout.setLayout(2,
QtGui.QFormLayout.FieldRole, self.mainSizeLayout)
self.lineSpacingLabel = QtGui.QLabel(self.mainAreaPage)
self.lineSpacingLabel.setObjectName(u'lineSpacingLabel')
self.mainAreaLayout.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.mainAreaLayout.setWidget(3,
QtGui.QFormLayout.FieldRole, self.lineSpacingSpinBox)
self.outlineCheckBox = QtGui.QCheckBox(self.mainAreaPage)
self.outlineCheckBox.setObjectName(u'outlineCheckBox')
self.mainAreaLayout.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.mainAreaLayout.setLayout(4,
QtGui.QFormLayout.FieldRole, self.outlineLayout)
self.shadowCheckBox = QtGui.QCheckBox(self.mainAreaPage)
self.shadowCheckBox.setObjectName(u'shadowCheckBox')
self.mainAreaLayout.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.mainAreaLayout.setLayout(5,
QtGui.QFormLayout.FieldRole, self.shadowLayout)
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.setMargin(20)
self.footerLayout.setSpacing(8)
self.footerLayout.setObjectName(u'footerLayout')
self.footerFontLabel = QtGui.QLabel(self.footerAreaPage)
self.footerFontLabel.setMinimumSize(QtCore.QSize(103, 0))
self.footerFontLabel.setAlignment(QtCore.Qt.AlignRight |
QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
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.alignmentLayout = QtGui.QFormLayout(self.alignmentPage)
self.alignmentLayout.setMargin(20)
self.alignmentLayout.setSpacing(8)
self.alignmentLayout.setObjectName(u'alignmentLayout')
self.horizontalLabel = QtGui.QLabel(self.alignmentPage)
self.horizontalLabel.setMinimumSize(QtCore.QSize(103, 0))
self.horizontalLabel.setAlignment(QtCore.Qt.AlignRight |
QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.horizontalLabel.setObjectName(u'horizontalLabel')
self.alignmentLayout.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.alignmentLayout.setWidget(0,
QtGui.QFormLayout.FieldRole, self.horizontalComboBox)
self.verticalLabel = QtGui.QLabel(self.alignmentPage)
self.verticalLabel.setObjectName(u'verticalLabel')
self.alignmentLayout.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.alignmentLayout.setWidget(1,
QtGui.QFormLayout.FieldRole, self.verticalComboBox)
self.transitionsCheckBox = QtGui.QCheckBox(self.alignmentPage)
self.transitionsCheckBox.setObjectName(u'transitionsCheckBox')
self.alignmentLayout.setWidget(2,
QtGui.QFormLayout.FieldRole, self.transitionsCheckBox)
ThemeWizard.addPage(self.alignmentPage)
self.areaPositionPage = QtGui.QWizardPage()
self.areaPositionPage.setObjectName(u'areaPositionPage')
self.areaPositionLayout = QtGui.QGridLayout(self.areaPositionPage)
self.areaPositionLayout.setMargin(20)
self.areaPositionLayout.setSpacing(8)
self.areaPositionLayout.setObjectName(u'areaPositionLayout')
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.areaPositionLayout.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.areaPositionLayout.addWidget(self.footerPositionGroupBox, 1, 1, 1, 1)
ThemeWizard.addPage(self.areaPositionPage)
self.previewPage = QtGui.QWizardPage()
self.previewPage.setObjectName(u'previewPage')
self.previewLayout = QtGui.QVBoxLayout(self.previewPage)
self.previewLayout.setSpacing(8)
self.previewLayout.setMargin(20)
self.previewLayout.setObjectName(u'previewLayout')
self.themeNameLayout = QtGui.QHBoxLayout()
self.themeNameLayout.setSpacing(8)
self.themeNameLayout.setObjectName(u'themeNameLayout')
self.themeNameLabel = QtGui.QLabel(self.previewPage)
self.themeNameLabel.setMinimumSize(QtCore.QSize(103, 0))
self.themeNameLabel.setTextFormat(QtCore.Qt.PlainText)
self.themeNameLabel.setAlignment(QtCore.Qt.AlignRight |
QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.themeNameLabel.setObjectName(u'themeNameLabel')
self.themeNameLayout.addWidget(self.themeNameLabel)
self.themeNameEdit = QtGui.QLineEdit(self.previewPage)
self.themeNameEdit.setObjectName(u'themeNameEdit')
self.themeNameLayout.addWidget(self.themeNameEdit)
self.previewLayout.addLayout(self.themeNameLayout)
self.previewPaneLayout = QtGui.QHBoxLayout()
self.previewPaneLayout.setSpacing(0)
self.previewPaneLayout.setObjectName(u'previewPaneLayout')
self.previewLeftSpacer = QtGui.QSpacerItem(58, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.previewPaneLayout.addItem(self.previewLeftSpacer)
self.previewBoxLabel = QtGui.QLabel(self.previewPage)
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(100, 150))
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.previewPaneLayout.addWidget(self.previewBoxLabel)
self.previewRightSpacer = QtGui.QSpacerItem(78, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.previewPaneLayout.addItem(self.previewRightSpacer)
self.previewLayout.addLayout(self.previewPaneLayout)
ThemeWizard.addPage(self.previewPage)
self.themeNameLabel.setBuddy(self.themeNameEdit)
self.retranslateUi(ThemeWizard)
self.backgroundStackedWidget.setCurrentIndex(0)
QtCore.QObject.connect(
ThemeWizard,
QtCore.SIGNAL(u'accepted()'),
ThemeWizard.accept)
QtCore.QObject.connect(
self.backgroundTypeComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.backgroundStackedWidget.setCurrentIndex)
QtCore.QMetaObject.connectSlotsByName(ThemeWizard)
def retranslateUi(self, ThemeWizard):
ThemeWizard.setWindowTitle(
translate('OpenLP.ThemeWizard', 'Theme Wizard'))
self.titleLabel.setText(
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate('OpenLP.ThemeWizard', 'Welcome to the Theme Wizard'))
self.informationLabel.setText(
translate('OpenLP.ThemeWizard', 'This wizard will help you to '
'create and edit your themes . Click the next button below to '
'start the process by setting up your background.'))
self.backgroundPage.setTitle(
translate('OpenLP.ThemeWizard', 'Set Up Background'))
self.backgroundPage.setSubTitle(
translate('OpenLP.ThemeWizard', 'Set up your theme\'s background '
'according to the parameters below.'))
self.backgroundTypeLabel.setText(
translate('OpenLP.ThemeWizard', 'Background type:'))
self.backgroundTypeComboBox.setItemText(0,
translate('OpenLP.ThemeWizard', 'Solid Color'))
self.backgroundTypeComboBox.setItemText(1,
translate('OpenLP.ThemeWizard', 'Gradient'))
self.backgroundTypeComboBox.setItemText(2,
translate('OpenLP.ThemeWizard', 'Image'))
self.colorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
self.gradientStartLabel.setText(
translate(u'OpenLP.ThemeWizard', 'Starting color:'))
self.gradientEndLabel.setText(
translate(u'OpenLP.ThemeWizard', 'Ending color:'))
self.gradientTypeLabel.setText(
translate('OpenLP.ThemeWizard', 'Gradient:'))
self.gradientComboBox.setItemText(0,
translate('OpenLP.ThemeWizard', 'Horizontal'))
self.gradientComboBox.setItemText(1,
translate('OpenLP.ThemeWizard', 'Vertical'))
self.gradientComboBox.setItemText(2,
translate('OpenLP.ThemeWizard', 'Circular'))
self.gradientComboBox.setItemText(3,
translate('OpenLP.ThemeWizard', 'Top Left - Bottom Right'))
self.gradientComboBox.setItemText(4,
translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
self.imageLabel.setText(translate('OpenLP.ThemeWizard', 'Image:'))
self.mainAreaPage.setTitle(
translate('OpenLP.ThemeWizard', 'Main Area Font Details'))
self.mainAreaPage.setSubTitle(
translate('OpenLP.ThemeWizard', 'Define the font and display '
'characteristics for the Display text'))
self.mainFontLabel.setText(
translate('OpenLP.ThemeWizard', 'Font:'))
self.mainColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
self.mainSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.mainSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
self.mainLineCountLabel.setText(
translate('OpenLP.ThemeWizard', '(%d lines per slide)'))
self.lineSpacingLabel.setText(
translate('OpenLP.ThemeWizard', 'Line Spacing:'))
self.lineSpacingSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
self.outlineCheckBox.setText(
translate('OpenLP.ThemeWizard', '&Outline:'))
self.outlineSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.outlineSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
self.shadowCheckBox.setText(translate('OpenLP.ThemeWizard', '&Shadow:'))
self.shadowSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.shadowSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
self.boldCheckBox.setText(
translate('OpenLP.ThemeWizard', 'Bold'))
self.italicsCheckBox.setText(
translate('OpenLP.ThemeWizard', 'Italic'))
self.footerAreaPage.setTitle(
translate('OpenLP.ThemeWizard', 'Footer Area Font Details'))
self.footerAreaPage.setSubTitle(
translate('OpenLP.ThemeWizard', 'Define the font and display '
'characteristics for the Footer text'))
self.footerFontLabel.setText(translate('OpenLP.ThemeWizard', 'Font:'))
self.footerColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
self.footerSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.footerSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
self.alignmentPage.setTitle(
translate('OpenLP.ThemeWizard', 'Text Formatting Details'))
self.alignmentPage.setSubTitle(
translate('OpenLP.ThemeWizard', 'Allows additional display '
'formatting information to be defined'))
self.horizontalLabel.setText(
translate('OpenLP.ThemeWizard', 'Horizontal Align:'))
self.horizontalComboBox.setItemText(0,
translate('OpenLP.ThemeWizard', 'Left'))
self.horizontalComboBox.setItemText(1,
translate('OpenLP.ThemeWizard', 'Right'))
self.horizontalComboBox.setItemText(2,
translate('OpenLP.ThemeWizard', 'Center'))
self.verticalLabel.setText(
translate('OpenLP.ThemeWizard', 'Vertical Align:'))
self.verticalComboBox.setItemText(0,
translate('OpenLP.ThemeWizard', 'Top'))
self.verticalComboBox.setItemText(1,
translate('OpenLP.ThemeWizard', 'Middle'))
self.verticalComboBox.setItemText(2,
translate('OpenLP.ThemeWizard', 'Bottom'))
self.transitionsCheckBox.setText(
translate('OpenLP.ThemeWizard', 'Transitions'))
self.areaPositionPage.setTitle(
translate('OpenLP.ThemeWizard', 'Output Area Locations'))
self.areaPositionPage.setSubTitle(
translate('OpenLP.ThemeWizard', 'Allows you to change and move the '
'main and footer areas.'))
self.mainPositionGroupBox.setTitle(
translate('OpenLP.ThemeWizard', '&Main Area'))
self.mainDefaultPositionCheckBox.setText(
translate('OpenLP.ThemeWizard', '&Use default location'))
self.nainXLabel.setText(translate('OpenLP.ThemeWizard', 'X position:'))
self.mainXSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
self.mainYSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
self.mainYLabel.setText(translate('OpenLP.ThemeWizard', 'Y position:'))
self.mainWidthSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
self.mainWidthLabel.setText(translate('OpenLP.ThemeWizard', 'Width:'))
self.mainHeightSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
self.mainHeightLabel.setText(translate('OpenLP.ThemeWizard', 'Height:'))
self.footerPositionGroupBox.setTitle(
translate('OpenLP.ThemeWizard', 'Footer Area'))
self.footerXLabel.setText(translate('OpenLP.ThemeWizard', 'X position:'))
self.footerXSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
self.footerYLabel.setText(translate('OpenLP.ThemeWizard', 'Y position:'))
self.footerYSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
self.footerWidthLabel.setText(translate('OpenLP.ThemeWizard', 'Width:'))
self.footerWidthSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
self.footerHeightLabel.setText(
translate('OpenLP.ThemeWizard', 'Height:'))
self.footerHeightSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'px'))
self.footerDefaultPositionCheckBox.setText(
translate('OpenLP.ThemeWizard', 'Use default location'))
self.previewPage.setTitle(
translate('OpenLP.ThemeWizard', 'Save and Preview'))
self.previewPage.setSubTitle(
translate('OpenLP.ThemeWizard', 'View the theme and save it '
'replacing the current one or change the name to create a '
'new theme'))
self.themeNameLabel.setText(
translate('OpenLP.ThemeWizard', 'Theme name:'))

View File

@ -133,7 +133,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
self.OSISLocationEdit.setFocus() self.OSISLocationEdit.setFocus()
return False return False
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV: elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
if self.field(u'csv_booksfile').toString() == u'': if not self.field(u'csv_booksfile').toString():
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Books File'), 'Invalid Books File'),
@ -142,7 +142,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
'the Bible to use in the import.')) 'the Bible to use in the import.'))
self.BooksLocationEdit.setFocus() self.BooksLocationEdit.setFocus()
return False return False
elif self.field(u'csv_versefile').toString() == u'': elif not self.field(u'csv_versefile').toString():
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Verse File'), 'Invalid Verse File'),
@ -153,7 +153,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
return False return False
elif self.field(u'source_format').toInt()[0] == \ elif self.field(u'source_format').toInt()[0] == \
BibleFormat.OpenSong: BibleFormat.OpenSong:
if self.field(u'opensong_file').toString() == u'': if not self.field(u'opensong_file').toString():
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid OpenSong Bible'), 'Invalid OpenSong Bible'),
@ -168,7 +168,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
license_version = unicode(self.field(u'license_version').toString()) license_version = unicode(self.field(u'license_version').toString())
license_copyright = \ license_copyright = \
unicode(self.field(u'license_copyright').toString()) unicode(self.field(u'license_copyright').toString())
if license_version == u'': if not license_version:
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Empty Version Name'), 'Empty Version Name'),
@ -176,7 +176,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
'You need to specify a version name for your Bible.')) 'You need to specify a version name for your Bible.'))
self.VersionNameEdit.setFocus() self.VersionNameEdit.setFocus()
return False return False
elif license_copyright == u'': elif not license_copyright:
QtGui.QMessageBox.critical(self, QtGui.QMessageBox.critical(self,
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Empty Copyright'), 'Empty Copyright'),
@ -207,9 +207,11 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
The index of the combo box. The index of the combo box.
""" """
self.BibleComboBox.clear() self.BibleComboBox.clear()
for bible in self.web_bible_list[index].keys(): bibles = [unicode(translate('BiblesPlugin.ImportWizardForm', bible)) for
self.BibleComboBox.addItem(unicode( bible in self.web_bible_list[index].keys()]
translate('BiblesPlugin.ImportWizardForm', bible))) bibles.sort()
for bible in bibles:
self.BibleComboBox.addItem(bible)
def onOsisFileButtonClicked(self): def onOsisFileButtonClicked(self):
""" """
@ -317,7 +319,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
""" """
Load the list of Crosswalk and BibleGateway bibles. Load the list of Crosswalk and BibleGateway bibles.
""" """
#Load and store Crosswalk Bibles # Load and store Crosswalk Bibles.
filepath = AppLocation.get_directory(AppLocation.PluginsDir) filepath = AppLocation.get_directory(AppLocation.PluginsDir)
filepath = os.path.join(filepath, u'bibles', u'resources') filepath = os.path.join(filepath, u'bibles', u'resources')
books_file = None books_file = None
@ -341,7 +343,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
finally: finally:
if books_file: if books_file:
books_file.close() books_file.close()
#Load and store BibleGateway Bibles # Load and store BibleGateway Bibles.
books_file = None books_file = None
try: try:
self.web_bible_list[WebDownload.BibleGateway] = {} self.web_bible_list[WebDownload.BibleGateway] = {}
@ -379,12 +381,18 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
def preImport(self): def preImport(self):
bible_type = self.field(u'source_format').toInt()[0]
self.finishButton.setVisible(False) self.finishButton.setVisible(False)
self.ImportProgressBar.setMinimum(0) self.ImportProgressBar.setMinimum(0)
self.ImportProgressBar.setMaximum(1188) self.ImportProgressBar.setMaximum(1188)
self.ImportProgressBar.setValue(0) self.ImportProgressBar.setValue(0)
self.ImportProgressLabel.setText( if bible_type == BibleFormat.WebDownload:
translate('BiblesPlugin.ImportWizardForm', 'Starting import...')) self.ImportProgressLabel.setText(translate(
'BiblesPlugin.ImportWizardForm',
'Starting Registering bible...'))
else:
self.ImportProgressLabel.setText(translate(
'BiblesPlugin.ImportWizardForm', 'Starting import...'))
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
def performImport(self): def performImport(self):
@ -395,26 +403,26 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
unicode(self.field(u'license_permissions').toString()) unicode(self.field(u'license_permissions').toString())
importer = None importer = None
if bible_type == BibleFormat.OSIS: if bible_type == BibleFormat.OSIS:
# Import an OSIS bible # Import an OSIS bible.
importer = self.manager.import_bible(BibleFormat.OSIS, importer = self.manager.import_bible(BibleFormat.OSIS,
name=license_version, name=license_version,
filename=unicode(self.field(u'osis_location').toString()) filename=unicode(self.field(u'osis_location').toString())
) )
elif bible_type == BibleFormat.CSV: elif bible_type == BibleFormat.CSV:
# Import a CSV bible # Import a CSV bible.
importer = self.manager.import_bible(BibleFormat.CSV, importer = self.manager.import_bible(BibleFormat.CSV,
name=license_version, name=license_version,
booksfile=unicode(self.field(u'csv_booksfile').toString()), booksfile=unicode(self.field(u'csv_booksfile').toString()),
versefile=unicode(self.field(u'csv_versefile').toString()) versefile=unicode(self.field(u'csv_versefile').toString())
) )
elif bible_type == BibleFormat.OpenSong: elif bible_type == BibleFormat.OpenSong:
# Import an OpenSong bible # Import an OpenSong bible.
importer = self.manager.import_bible(BibleFormat.OpenSong, importer = self.manager.import_bible(BibleFormat.OpenSong,
name=license_version, name=license_version,
filename=unicode(self.field(u'opensong_file').toString()) filename=unicode(self.field(u'opensong_file').toString())
) )
elif bible_type == BibleFormat.WebDownload: elif bible_type == BibleFormat.WebDownload:
# Import a bible from the web # Import a bible from the web.
self.ImportProgressBar.setMaximum(1) self.ImportProgressBar.setMaximum(1)
download_location = self.field(u'web_location').toInt()[0] download_location = self.field(u'web_location').toInt()[0]
bible_version = unicode(self.BibleComboBox.currentText()) bible_version = unicode(self.BibleComboBox.currentText())
@ -438,8 +446,14 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
self.manager.save_meta_data(license_version, license_version, self.manager.save_meta_data(license_version, license_version,
license_copyright, license_permissions) license_copyright, license_permissions)
self.manager.reload_bibles() self.manager.reload_bibles()
self.ImportProgressLabel.setText( if bible_type == BibleFormat.WebDownload:
translate('BiblesPlugin.ImportWizardForm', 'Finished import.')) self.ImportProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Registered '
'bible. Please note, that verses will be downloaded on\n'
'demand and thus an internet connection is required.'))
else:
self.ImportProgressLabel.setText(translate(
'BiblesPlugin.ImportWizardForm', 'Finished import.'))
else: else:
self.ImportProgressLabel.setText( self.ImportProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',

View File

@ -110,9 +110,9 @@ class BiblesTab(SettingsTab):
self.BibleThemeComboBox.setObjectName(u'BibleThemeComboBox') self.BibleThemeComboBox.setObjectName(u'BibleThemeComboBox')
self.BibleThemeComboBox.addItem(QtCore.QString()) self.BibleThemeComboBox.addItem(QtCore.QString())
self.BibleThemeLayout.addWidget(self.BibleThemeComboBox) self.BibleThemeLayout.addWidget(self.BibleThemeComboBox)
self.BibleDualCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox) self.BibleSecondCheckBox = QtGui.QCheckBox(self.VerseDisplayGroupBox)
self.BibleDualCheckBox.setObjectName(u'BibleDualCheckBox') self.BibleSecondCheckBox.setObjectName(u'BibleSecondCheckBox')
self.VerseDisplayLayout.addWidget(self.BibleDualCheckBox, 3, 0, 1, 1) self.VerseDisplayLayout.addWidget(self.BibleSecondCheckBox, 3, 0, 1, 1)
self.VerseDisplayLayout.addWidget(self.BibleThemeWidget, 4, 0, 1, 1) self.VerseDisplayLayout.addWidget(self.BibleThemeWidget, 4, 0, 1, 1)
self.ChangeNoteLabel = QtGui.QLabel(self.VerseDisplayGroupBox) self.ChangeNoteLabel = QtGui.QLabel(self.VerseDisplayGroupBox)
self.ChangeNoteLabel.setObjectName(u'ChangeNoteLabel') self.ChangeNoteLabel.setObjectName(u'ChangeNoteLabel')
@ -143,8 +143,8 @@ class BiblesTab(SettingsTab):
self.LayoutStyleComboBox, QtCore.SIGNAL(u'activated(int)'), self.LayoutStyleComboBox, QtCore.SIGNAL(u'activated(int)'),
self.onLayoutStyleComboBoxChanged) self.onLayoutStyleComboBoxChanged)
QtCore.QObject.connect( QtCore.QObject.connect(
self.BibleDualCheckBox, QtCore.SIGNAL(u'stateChanged(int)'), self.BibleSecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
self.onBibleDualCheckBox) self.onBibleSecondCheckBox)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
@ -176,8 +176,8 @@ class BiblesTab(SettingsTab):
translate('BiblesPlugin.BiblesTab', '[ And ]')) translate('BiblesPlugin.BiblesTab', '[ And ]'))
self.ChangeNoteLabel.setText(translate('BiblesPlugin.BiblesTab', self.ChangeNoteLabel.setText(translate('BiblesPlugin.BiblesTab',
'Note:\nChanges do not affect verses already in the service.')) 'Note:\nChanges do not affect verses already in the service.'))
self.BibleDualCheckBox.setText( self.BibleSecondCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'Display dual Bible verses')) translate('BiblesPlugin.BiblesTab', 'Display second Bible verses'))
def onBibleThemeComboBoxChanged(self): def onBibleThemeComboBoxChanged(self):
self.bible_theme = self.BibleThemeComboBox.currentText() self.bible_theme = self.BibleThemeComboBox.currentText()
@ -190,15 +190,15 @@ class BiblesTab(SettingsTab):
def onNewChaptersCheckBoxChanged(self, check_state): def onNewChaptersCheckBoxChanged(self, check_state):
self.show_new_chapters = False self.show_new_chapters = False
# we have a set value convert to True/False # We have a set value convert to True/False.
if check_state == QtCore.Qt.Checked: if check_state == QtCore.Qt.Checked:
self.show_new_chapters = True self.show_new_chapters = True
def onBibleDualCheckBox(self, check_state): def onBibleSecondCheckBox(self, check_state):
self.dual_bibles = False self.second_bibles = False
# we have a set value convert to True/False # We have a set value convert to True/False.
if check_state == QtCore.Qt.Checked: if check_state == QtCore.Qt.Checked:
self.dual_bibles = True self.second_bibles = True
def load(self): def load(self):
settings = QtCore.QSettings() settings = QtCore.QSettings()
@ -211,12 +211,12 @@ class BiblesTab(SettingsTab):
u'verse layout style', QtCore.QVariant(0)).toInt()[0] u'verse layout style', QtCore.QVariant(0)).toInt()[0]
self.bible_theme = unicode( self.bible_theme = unicode(
settings.value(u'bible theme', QtCore.QVariant(u'')).toString()) settings.value(u'bible theme', QtCore.QVariant(u'')).toString())
self.dual_bibles = settings.value( self.second_bibles = settings.value(
u'dual bibles', QtCore.QVariant(True)).toBool() u'second bibles', QtCore.QVariant(True)).toBool()
self.NewChaptersCheckBox.setChecked(self.show_new_chapters) self.NewChaptersCheckBox.setChecked(self.show_new_chapters)
self.DisplayStyleComboBox.setCurrentIndex(self.display_style) self.DisplayStyleComboBox.setCurrentIndex(self.display_style)
self.LayoutStyleComboBox.setCurrentIndex(self.layout_style) self.LayoutStyleComboBox.setCurrentIndex(self.layout_style)
self.BibleDualCheckBox.setChecked(self.dual_bibles) self.BibleSecondCheckBox.setChecked(self.second_bibles)
settings.endGroup() settings.endGroup()
def save(self): def save(self):
@ -228,13 +228,18 @@ class BiblesTab(SettingsTab):
QtCore.QVariant(self.display_style)) QtCore.QVariant(self.display_style))
settings.setValue(u'verse layout style', settings.setValue(u'verse layout style',
QtCore.QVariant(self.layout_style)) QtCore.QVariant(self.layout_style))
settings.setValue(u'dual bibles', QtCore.QVariant(self.dual_bibles)) settings.setValue(u'second bibles', QtCore.QVariant(self.second_bibles))
settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme)) settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme))
settings.endGroup() settings.endGroup()
def updateThemeList(self, theme_list): def updateThemeList(self, theme_list):
""" """
Called from ThemeManager when the Themes have changed Called from ThemeManager when the Themes have changed.
``theme_list``
The list of available themes::
[u'Bible Theme', u'Song Theme']
""" """
self.BibleThemeComboBox.clear() self.BibleThemeComboBox.clear()
self.BibleThemeComboBox.addItem(u'') self.BibleThemeComboBox.addItem(u'')
@ -243,7 +248,7 @@ class BiblesTab(SettingsTab):
index = self.BibleThemeComboBox.findText( index = self.BibleThemeComboBox.findText(
unicode(self.bible_theme), QtCore.Qt.MatchExactly) unicode(self.bible_theme), QtCore.Qt.MatchExactly)
if index == -1: if index == -1:
# Not Found # Not Found.
index = 0 index = 0
self.bible_theme = u'' self.bible_theme = u''
self.BibleThemeComboBox.setCurrentIndex(index) self.BibleThemeComboBox.setCurrentIndex(index)

View File

@ -44,24 +44,28 @@ class BibleMeta(BaseModel):
""" """
pass pass
class Testament(BaseModel): class Testament(BaseModel):
""" """
Bible Testaments Bible Testaments
""" """
pass pass
class Book(BaseModel): class Book(BaseModel):
""" """
Song model Song model
""" """
pass pass
class Verse(BaseModel): class Verse(BaseModel):
""" """
Topic model Topic model
""" """
pass pass
def init_schema(url): def init_schema(url):
""" """
Setup a bible database connection and initialise the database schema. Setup a bible database connection and initialise the database schema.
@ -240,7 +244,7 @@ class BibleDB(QtCore.QObject, Manager):
and the value is the verse text. and the value is the verse text.
""" """
log.debug(u'create_chapter %s,%s', book_id, chapter) log.debug(u'create_chapter %s,%s', book_id, chapter)
# text list has book and chapter as first two elements of the array # Text list has book and chapter as first two elements of the array.
for verse_number, verse_text in textlist.iteritems(): for verse_number, verse_text in textlist.iteritems():
verse = Verse.populate( verse = Verse.populate(
book_id = book_id, book_id = book_id,

View File

@ -213,7 +213,7 @@ class BGExtract(object):
finally: finally:
if not page: if not page:
return None return None
cleaner = [(re.compile('&nbsp;|<br />'), lambda match: '')] cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')]
soup = None soup = None
try: try:
soup = BeautifulSoup(page, markupMassage=cleaner) soup = BeautifulSoup(page, markupMassage=cleaner)
@ -364,12 +364,11 @@ class HTTPBible(BibleDB):
if self.proxy_server: if self.proxy_server:
self.create_meta(u'proxy server', self.proxy_server) self.create_meta(u'proxy server', self.proxy_server)
if self.proxy_username: if self.proxy_username:
# store the proxy userid # Store the proxy userid.
self.create_meta(u'proxy username', self.proxy_username) self.create_meta(u'proxy username', self.proxy_username)
if self.proxy_password: if self.proxy_password:
# store the proxy password # Store the proxy password.
self.create_meta(u'proxy password', self.proxy_password) self.create_meta(u'proxy password', self.proxy_password)
self.wizard.incrementProgressBar('Registered.')
return True return True
def get_verses(self, reference_list): def get_verses(self, reference_list):
@ -417,7 +416,7 @@ class HTTPBible(BibleDB):
## to request ac and get Acts back. ## to request ac and get Acts back.
bookname = search_results.book bookname = search_results.book
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
# check to see if book/chapter exists # Check to see if book/chapter exists.
db_book = self.get_book(bookname) db_book = self.get_book(bookname)
self.create_chapter(db_book.id, search_results.chapter, self.create_chapter(db_book.id, search_results.chapter,
search_results.verselist) search_results.verselist)

View File

@ -257,17 +257,34 @@ class BibleManager(object):
'Book Chapter:Verse-Chapter:Verse')) 'Book Chapter:Verse-Chapter:Verse'))
return None return None
def verse_search(self, bible, text): def verse_search(self, bible, second_bible, text):
""" """
Does a verse search for the given bible and text. Does a verse search for the given bible and text.
``bible`` ``bible``
The bible to seach in (unicode). The bible to seach in (unicode).
``second_bible``
The second bible (unicode). We do not search in this bible.
``text`` ``text``
The text to search for (unicode). The text to search for (unicode).
""" """
log.debug(u'BibleManager.verse_search("%s", "%s")', bible, text) log.debug(u'BibleManager.verse_search("%s", "%s")', bible, text)
# Check if the bible or second_bible is a web bible.
webbible = self.db_cache[bible].get_object(BibleMeta,
u'download source')
second_webbible = u''
if second_bible:
second_webbible = self.db_cache[second_bible].get_object(BibleMeta,
u'download source')
if webbible or second_webbible:
QtGui.QMessageBox.information(self.parent.mediaItem,
translate('BiblesPlugin.BibleManager',
'Web Bible cannot be used'),
translate('BiblesPlugin.BibleManager', 'Text Search is not '
'available with Web Bibles.'))
return None
if text: if text:
return self.db_cache[bible].verse_search(text) return self.db_cache[bible].verse_search(text)
else: else:
@ -317,4 +334,3 @@ class BibleManager(object):
""" """
for bible in self.db_cache: for bible in self.db_cache:
self.db_cache[bible].finalise() self.db_cache[bible].finalise()

View File

@ -47,21 +47,22 @@ class BibleListView(BaseListWithDnD):
self.parent().onListViewResize(event.size().width(), self.parent().onListViewResize(event.size().width(),
event.size().width()) event.size().width())
class BibleMediaItem(MediaManagerItem): class BibleMediaItem(MediaManagerItem):
""" """
This is the custom media manager item for Bibles. This is the custom media manager item for Bibles.
""" """
log.info(u'Bible Media Item loaded') log.info(u'Bible Media Item loaded')
def __init__(self, parent, icon, title): def __init__(self, parent, plugin, icon):
self.PluginNameShort = u'Bible' self.PluginNameShort = u'Bible'
self.pluginNameVisible = translate('BiblesPlugin.MediaItem', 'Bible') self.pluginNameVisible = translate('BiblesPlugin.MediaItem', 'Bible')
self.IconPath = u'songs/song' self.IconPath = u'songs/song'
self.ListViewWithDnD_class = BibleListView self.ListViewWithDnD_class = BibleListView
MediaManagerItem.__init__(self, parent, icon, title) MediaManagerItem.__init__(self, parent, plugin, icon)
# place to store the search results for both bibles # Place to store the search results for both bibles.
self.search_results = {} self.search_results = {}
self.dual_search_results = {} self.second_search_results = {}
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles) QtCore.SIGNAL(u'bibles_load_list'), self.reloadBibles)
@ -83,7 +84,7 @@ class BibleMediaItem(MediaManagerItem):
self.SearchTabWidget.sizePolicy().hasHeightForWidth()) self.SearchTabWidget.sizePolicy().hasHeightForWidth())
self.SearchTabWidget.setSizePolicy(sizePolicy) self.SearchTabWidget.setSizePolicy(sizePolicy)
self.SearchTabWidget.setObjectName(u'SearchTabWidget') self.SearchTabWidget.setObjectName(u'SearchTabWidget')
# Add the Quick Search tab # Add the Quick Search tab.
self.QuickTab = QtGui.QWidget() self.QuickTab = QtGui.QWidget()
self.QuickTab.setObjectName(u'QuickTab') self.QuickTab.setObjectName(u'QuickTab')
self.QuickLayout = QtGui.QGridLayout(self.QuickTab) self.QuickLayout = QtGui.QGridLayout(self.QuickTab)
@ -144,7 +145,7 @@ class BibleMediaItem(MediaManagerItem):
QuickSpacerItem = QtGui.QSpacerItem(20, 35, QtGui.QSizePolicy.Minimum, QuickSpacerItem = QtGui.QSpacerItem(20, 35, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding) QtGui.QSizePolicy.Expanding)
self.QuickLayout.addItem(QuickSpacerItem, 6, 2, 1, 1) self.QuickLayout.addItem(QuickSpacerItem, 6, 2, 1, 1)
# Add the Advanced Search tab # Add the Advanced Search tab.
self.AdvancedTab = QtGui.QWidget() self.AdvancedTab = QtGui.QWidget()
self.AdvancedTab.setObjectName(u'AdvancedTab') self.AdvancedTab.setObjectName(u'AdvancedTab')
self.AdvancedLayout = QtGui.QGridLayout(self.AdvancedTab) self.AdvancedLayout = QtGui.QGridLayout(self.AdvancedTab)
@ -226,7 +227,7 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedLayout.addWidget(self.AdvancedMessage, 8, 0, 1, 3) self.AdvancedLayout.addWidget(self.AdvancedMessage, 8, 0, 1, 3)
self.SearchTabWidget.addTab(self.AdvancedTab, self.SearchTabWidget.addTab(self.AdvancedTab,
translate('BiblesPlugin.MediaItem', 'Advanced')) translate('BiblesPlugin.MediaItem', 'Advanced'))
# Add the search tab widget to the page layout # Add the search tab widget to the page layout.
self.pageLayout.addWidget(self.SearchTabWidget) self.pageLayout.addWidget(self.SearchTabWidget)
# Combo Boxes # Combo Boxes
QtCore.QObject.connect(self.AdvancedVersionComboBox, QtCore.QObject.connect(self.AdvancedVersionComboBox,
@ -239,6 +240,10 @@ class BibleMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedFromVerse) QtCore.SIGNAL(u'activated(int)'), self.onAdvancedFromVerse)
QtCore.QObject.connect(self.AdvancedToChapter, QtCore.QObject.connect(self.AdvancedToChapter,
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedToChapter) QtCore.SIGNAL(u'activated(int)'), self.onAdvancedToChapter)
QtCore.QObject.connect(self.QuickSearchComboBox,
QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter)
QtCore.QObject.connect(self.QuickVersionComboBox,
QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter)
# Buttons # Buttons
QtCore.QObject.connect(self.AdvancedSearchButton, QtCore.QObject.connect(self.AdvancedSearchButton,
QtCore.SIGNAL(u'pressed()'), self.onAdvancedSearchButton) QtCore.SIGNAL(u'pressed()'), self.onAdvancedSearchButton)
@ -270,7 +275,7 @@ class BibleMediaItem(MediaManagerItem):
def configUpdated(self): def configUpdated(self):
log.debug(u'configUpdated') log.debug(u'configUpdated')
if QtCore.QSettings().value(self.settingsSection + u'/dual bibles', if QtCore.QSettings().value(self.settingsSection + u'/second bibles',
QtCore.QVariant(True)).toBool(): QtCore.QVariant(True)).toBool():
self.AdvancedSecondBibleLabel.setVisible(True) self.AdvancedSecondBibleLabel.setVisible(True)
self.AdvancedSecondBibleComboBox.setVisible(True) self.AdvancedSecondBibleComboBox.setVisible(True)
@ -287,7 +292,7 @@ class BibleMediaItem(MediaManagerItem):
self.QuickVersionLabel.setText( self.QuickVersionLabel.setText(
translate('BiblesPlugin.MediaItem', 'Version:')) translate('BiblesPlugin.MediaItem', 'Version:'))
self.QuickSecondVersionLabel.setText( self.QuickSecondVersionLabel.setText(
translate('BiblesPlugin.MediaItem', 'Dual:')) translate('BiblesPlugin.MediaItem', 'Second:'))
self.QuickSearchLabel.setText( self.QuickSearchLabel.setText(
translate('BiblesPlugin.MediaItem', 'Search type:')) translate('BiblesPlugin.MediaItem', 'Search type:'))
self.QuickSearchLabel.setText( self.QuickSearchLabel.setText(
@ -299,7 +304,7 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedVersionLabel.setText( self.AdvancedVersionLabel.setText(
translate('BiblesPlugin.MediaItem', 'Version:')) translate('BiblesPlugin.MediaItem', 'Version:'))
self.AdvancedSecondBibleLabel.setText( self.AdvancedSecondBibleLabel.setText(
translate('BiblesPlugin.MediaItem', 'Dual:')) translate('BiblesPlugin.MediaItem', 'Second:'))
self.AdvancedBookLabel.setText( self.AdvancedBookLabel.setText(
translate('BiblesPlugin.MediaItem', 'Book:')) translate('BiblesPlugin.MediaItem', 'Book:'))
self.AdvancedChapterLabel.setText( self.AdvancedChapterLabel.setText(
@ -331,6 +336,7 @@ class BibleMediaItem(MediaManagerItem):
log.debug(u'bible manager initialise') log.debug(u'bible manager initialise')
self.parent.manager.media = self self.parent.manager.media = self
self.loadBibles() self.loadBibles()
self.updateAutoCompleter()
self.configUpdated() self.configUpdated()
log.debug(u'bible manager initialise complete') log.debug(u'bible manager initialise complete')
@ -338,7 +344,7 @@ class BibleMediaItem(MediaManagerItem):
self.QuickMessage.setText(text) self.QuickMessage.setText(text)
self.AdvancedMessage.setText(text) self.AdvancedMessage.setText(text)
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
# minor delay to get the events processed # Minor delay to get the events processed.
time.sleep(0.1) time.sleep(0.1)
def onListViewResize(self, width, height): def onListViewResize(self, width, height):
@ -358,13 +364,15 @@ class BibleMediaItem(MediaManagerItem):
translate('BiblesPlugin.MediaItem', 'No Book Found'), translate('BiblesPlugin.MediaItem', 'No Book Found'),
translate('BiblesPlugin.MediaItem', translate('BiblesPlugin.MediaItem',
'No matching book could be found in this Bible.')) 'No matching book could be found in this Bible.'))
self.AdvancedSearchButton.setEnabled(True)
def onImportClick(self): def onImportClick(self):
if not hasattr(self, u'import_wizard'): if not hasattr(self, u'import_wizard'):
self.import_wizard = BibleImportForm(self, self.parent.manager, self.import_wizard = BibleImportForm(self, self.parent.manager,
self.parent) self.parent)
self.import_wizard.exec_() # If the import was not canceled then reload.
self.reloadBibles() if self.import_wizard.exec_():
self.reloadBibles()
def loadBibles(self): def loadBibles(self):
log.debug(u'Loading Bibles') log.debug(u'Loading Bibles')
@ -374,8 +382,10 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedSecondBibleComboBox.clear() self.AdvancedSecondBibleComboBox.clear()
self.QuickSecondBibleComboBox.addItem(u'') self.QuickSecondBibleComboBox.addItem(u'')
self.AdvancedSecondBibleComboBox.addItem(u'') self.AdvancedSecondBibleComboBox.addItem(u'')
# Get all bibles and sort the list.
bibles = self.parent.manager.get_bibles().keys() bibles = self.parent.manager.get_bibles().keys()
# load bibles into the combo boxes bibles.sort()
# Load the bibles into the combo boxes.
first = True first = True
for bible in bibles: for bible in bibles:
if bible: if bible:
@ -393,6 +403,15 @@ class BibleMediaItem(MediaManagerItem):
self.loadBibles() self.loadBibles()
def initialiseBible(self, bible): def initialiseBible(self, bible):
"""
This initialises the given bible, which means that its book names and
their chapter numbers is added to the combo boxes on the
'Advanced Search' Tab. This is not of any importance of the
'Quick Search' Tab.
``bible``
The bible to initialise (unicode).
"""
log.debug(u'initialiseBible %s', bible) log.debug(u'initialiseBible %s', bible)
book_data = self.parent.manager.get_books(bible) book_data = self.parent.manager.get_books(bible)
self.AdvancedBookComboBox.clear() self.AdvancedBookComboBox.clear()
@ -423,6 +442,25 @@ class BibleMediaItem(MediaManagerItem):
self.adjustComboBox(1, verse_count, self.AdvancedFromVerse) self.adjustComboBox(1, verse_count, self.AdvancedFromVerse)
self.adjustComboBox(1, verse_count, self.AdvancedToVerse) self.adjustComboBox(1, verse_count, self.AdvancedToVerse)
def updateAutoCompleter(self):
"""
This updates the bible book completion list for the search field. The
completion depends on the bible. It is only updated when we are doing a
verse search, otherwise the auto completion list is removed.
"""
books = []
# We have to do a 'Verse Search'.
if self.QuickSearchComboBox.currentIndex() == 0:
bibles = self.parent.manager.get_bibles()
bible = unicode(self.QuickVersionComboBox.currentText())
if bible:
book_data = bibles[bible].get_books()
books = [book.name for book in book_data]
books.sort()
completer = QtGui.QCompleter(books)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.QuickSearchEdit.setCompleter(completer)
def onAdvancedVersionComboBox(self): def onAdvancedVersionComboBox(self):
self.initialiseBible( self.initialiseBible(
unicode(self.AdvancedVersionComboBox.currentText())) unicode(self.AdvancedVersionComboBox.currentText()))
@ -482,6 +520,17 @@ class BibleMediaItem(MediaManagerItem):
def adjustComboBox(self, range_from, range_to, combo, restore=False): def adjustComboBox(self, range_from, range_to, combo, restore=False):
""" """
Adjusts the given como box to the given values.
``range_from``
The first number of the range (int).
``range_to``
The last number of the range (int).
``combo``
The combo box itself (QComboBox).
``restore`` ``restore``
If True, then the combo's currentText will be restored after If True, then the combo's currentText will be restored after
adjusting (if possible). adjusting (if possible).
@ -490,16 +539,19 @@ class BibleMediaItem(MediaManagerItem):
if restore: if restore:
old_text = unicode(combo.currentText()) old_text = unicode(combo.currentText())
combo.clear() combo.clear()
for i in range(int(range_from), int(range_to) + 1): for i in range(range_from, range_to + 1):
combo.addItem(unicode(i)) combo.addItem(unicode(i))
if restore and combo.findText(old_text) != -1: if restore and combo.findText(old_text) != -1:
combo.setCurrentIndex(combo.findText(old_text)) combo.setCurrentIndex(combo.findText(old_text))
def onAdvancedSearchButton(self): def onAdvancedSearchButton(self):
"""
Does an advanced search and saves the search results.
"""
log.debug(u'Advanced Search Button pressed') log.debug(u'Advanced Search Button pressed')
self.AdvancedSearchButton.setEnabled(False) self.AdvancedSearchButton.setEnabled(False)
bible = unicode(self.AdvancedVersionComboBox.currentText()) bible = unicode(self.AdvancedVersionComboBox.currentText())
dual_bible = unicode(self.AdvancedSecondBibleComboBox.currentText()) second_bible = unicode(self.AdvancedSecondBibleComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText()) book = unicode(self.AdvancedBookComboBox.currentText())
chapter_from = int(self.AdvancedFromChapter.currentText()) chapter_from = int(self.AdvancedFromChapter.currentText())
chapter_to = int(self.AdvancedToChapter.currentText()) chapter_to = int(self.AdvancedToChapter.currentText())
@ -508,74 +560,81 @@ class BibleMediaItem(MediaManagerItem):
versetext = u'%s %s:%s-%s:%s' % (book, chapter_from, verse_from, versetext = u'%s %s:%s-%s:%s' % (book, chapter_from, verse_from,
chapter_to, verse_to) chapter_to, verse_to)
self.search_results = self.parent.manager.get_verses(bible, versetext) self.search_results = self.parent.manager.get_verses(bible, versetext)
if dual_bible: if second_bible:
self.dual_search_results = self.parent.manager.get_verses( self.second_search_results = self.parent.manager.get_verses(
dual_bible, versetext) second_bible, versetext)
if self.ClearAdvancedSearchComboBox.currentIndex() == 0: if self.ClearAdvancedSearchComboBox.currentIndex() == 0:
self.listView.clear() self.listView.clear()
if self.listView.count() != 0: if self.listView.count() != 0:
# Check if the first item is a second bible item or not.
bitem = self.listView.item(0) bitem = self.listView.item(0)
item_dual_bible = self._decodeQtObject(bitem, 'dual_bible') item_second_bible = self._decodeQtObject(bitem, 'second_bible')
if item_dual_bible and dual_bible or not item_dual_bible and \ if item_second_bible and second_bible or not item_second_bible and \
not dual_bible: not second_bible:
self.displayResults(bible, dual_bible) self.displayResults(bible, second_bible)
elif QtGui.QMessageBox.critical(self, elif QtGui.QMessageBox.critical(self,
translate('BiblePlugin.MediaItem', 'Error'), translate('BiblePlugin.MediaItem', 'Error'),
translate('BiblePlugin.MediaItem', 'You cannot combine single ' translate('BiblePlugin.MediaItem', 'You cannot combine single '
'and dual bible verses. Do you want to delete your search ' 'and second bible verses. Do you want to delete your search '
'results and start a new search?'), 'results and start a new search?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes: QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
self.listView.clear() self.listView.clear()
self.displayResults(bible, dual_bible) self.displayResults(bible, second_bible)
else: else:
self.displayResults(bible, dual_bible) self.displayResults(bible, second_bible)
self.AdvancedSearchButton.setEnabled(True) self.AdvancedSearchButton.setEnabled(True)
def onQuickSearchButton(self): def onQuickSearchButton(self):
"""
Does a quick search and saves the search results. Quick search can
either be "Verse Search" or "Text Search".
"""
log.debug(u'Quick Search Button pressed') log.debug(u'Quick Search Button pressed')
self.QuickSearchButton.setEnabled(False) self.QuickSearchButton.setEnabled(False)
bible = unicode(self.QuickVersionComboBox.currentText()) bible = unicode(self.QuickVersionComboBox.currentText())
dual_bible = unicode(self.QuickSecondBibleComboBox.currentText()) second_bible = unicode(self.QuickSecondBibleComboBox.currentText())
text = unicode(self.QuickSearchEdit.text()) text = unicode(self.QuickSearchEdit.text())
if self.QuickSearchComboBox.currentIndex() == 0: if self.QuickSearchComboBox.currentIndex() == 0:
# We are doing a 'Verse Search'. # We are doing a 'Verse Search'.
self.search_results = self.parent.manager.get_verses(bible, text) self.search_results = self.parent.manager.get_verses(bible, text)
if dual_bible and self.search_results: if second_bible and self.search_results:
self.dual_search_results = self.parent.manager.get_verses( self.second_search_results = self.parent.manager.get_verses(
dual_bible, text) second_bible, text)
else: else:
# We are doing a ' Text Search'. # We are doing a 'Text Search'.
bibles = self.parent.manager.get_bibles() bibles = self.parent.manager.get_bibles()
self.search_results = self.parent.manager.verse_search(bible, text) self.search_results = self.parent.manager.verse_search(bible,
if dual_bible and self.search_results: second_bible, text)
if second_bible and self.search_results:
text = [] text = []
for verse in self.search_results: for verse in self.search_results:
text.append((verse.book.name, verse.chapter, verse.verse, text.append((verse.book.name, verse.chapter, verse.verse,
verse.verse)) verse.verse))
self.dual_search_results = bibles[dual_bible].get_verses(text) self.second_search_results = \
bibles[second_bible].get_verses(text)
if self.ClearQuickSearchComboBox.currentIndex() == 0: if self.ClearQuickSearchComboBox.currentIndex() == 0:
self.listView.clear() self.listView.clear()
if self.listView.count() != 0 and self.search_results: if self.listView.count() != 0 and self.search_results:
bitem = self.listView.item(0) bitem = self.listView.item(0)
item_dual_bible = self._decodeQtObject(bitem, 'dual_bible') item_second_bible = self._decodeQtObject(bitem, 'second_bible')
if item_dual_bible and dual_bible or not item_dual_bible and \ if item_second_bible and second_bible or not item_second_bible and \
not dual_bible: not second_bible:
self.displayResults(bible, dual_bible) self.displayResults(bible, second_bible)
elif QtGui.QMessageBox.critical(self, elif QtGui.QMessageBox.critical(self,
translate('BiblePlugin.MediaItem', 'Error'), translate('BiblePlugin.MediaItem', 'Error'),
translate('BiblePlugin.MediaItem', 'You cannot combine single ' translate('BiblePlugin.MediaItem', 'You cannot combine single '
'and dual bible verses. Do you want to delete your search ' 'and second bible verses. Do you want to delete your search '
'results and start a new search?'), 'results and start a new search?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes: QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes:
self.listView.clear() self.listView.clear()
self.displayResults(bible, dual_bible) self.displayResults(bible, second_bible)
elif self.search_results: elif self.search_results:
self.displayResults(bible, dual_bible) self.displayResults(bible, second_bible)
self.QuickSearchButton.setEnabled(True) self.QuickSearchButton.setEnabled(True)
def displayResults(self, bible, dual_bible=u''): def displayResults(self, bible, second_bible=u''):
""" """
Displays the search results in the media manager. All data needed for Displays the search results in the media manager. All data needed for
further action is saved for/in each row. further action is saved for/in each row.
@ -583,38 +642,41 @@ class BibleMediaItem(MediaManagerItem):
version = self.parent.manager.get_meta_data(bible, u'Version') version = self.parent.manager.get_meta_data(bible, u'Version')
copyright = self.parent.manager.get_meta_data(bible, u'Copyright') copyright = self.parent.manager.get_meta_data(bible, u'Copyright')
permissions = self.parent.manager.get_meta_data(bible, u'Permissions') permissions = self.parent.manager.get_meta_data(bible, u'Permissions')
if dual_bible: if second_bible:
dual_version = self.parent.manager.get_meta_data(dual_bible, second_version = self.parent.manager.get_meta_data(second_bible,
u'Version') u'Version')
dual_copyright = self.parent.manager.get_meta_data(dual_bible, second_copyright = self.parent.manager.get_meta_data(second_bible,
u'Copyright') u'Copyright')
dual_permissions = self.parent.manager.get_meta_data(dual_bible, second_permissions = self.parent.manager.get_meta_data(second_bible,
u'Permissions') u'Permissions')
if not dual_permissions: if not second_permissions:
dual_permissions = u'' second_permissions = u''
# We count the number of rows which are maybe already present.
start_count = self.listView.count()
for count, verse in enumerate(self.search_results): for count, verse in enumerate(self.search_results):
if dual_bible: if second_bible:
vdict = { try:
'book': QtCore.QVariant(verse.book.name), vdict = {
'chapter': QtCore.QVariant(verse.chapter), 'book': QtCore.QVariant(verse.book.name),
'verse': QtCore.QVariant(verse.verse), 'chapter': QtCore.QVariant(verse.chapter),
'bible': QtCore.QVariant(bible), 'verse': QtCore.QVariant(verse.verse),
'version': QtCore.QVariant(version.value), 'bible': QtCore.QVariant(bible),
'copyright': QtCore.QVariant(copyright.value), 'version': QtCore.QVariant(version.value),
'permissions': QtCore.QVariant(permissions.value), 'copyright': QtCore.QVariant(copyright.value),
'text': QtCore.QVariant(verse.text), 'permissions': QtCore.QVariant(permissions.value),
'dual_bible': QtCore.QVariant(dual_bible), 'text': QtCore.QVariant(verse.text),
'dual_version': QtCore.QVariant(dual_version.value), 'second_bible': QtCore.QVariant(second_bible),
'dual_copyright': QtCore.QVariant(dual_copyright.value), 'second_version': QtCore.QVariant(second_version.value),
'dual_permissions': QtCore.QVariant(dual_permissions.value), 'second_copyright': QtCore.QVariant(
'dual_text': QtCore.QVariant( second_copyright.value),
self.dual_search_results[count].text) 'second_permissions': QtCore.QVariant(
} second_permissions.value),
'second_text': QtCore.QVariant(
self.second_search_results[count].text)
}
except IndexError:
break
bible_text = u' %s %d:%d (%s, %s)' % (verse.book.name, bible_text = u' %s %d:%d (%s, %s)' % (verse.book.name,
verse.chapter, verse.verse, version.value, verse.chapter, verse.verse, version.value,
dual_version.value) second_version.value)
else: else:
vdict = { vdict = {
'book': QtCore.QVariant(verse.book.name), 'book': QtCore.QVariant(verse.book.name),
@ -625,22 +687,20 @@ class BibleMediaItem(MediaManagerItem):
'copyright': QtCore.QVariant(copyright.value), 'copyright': QtCore.QVariant(copyright.value),
'permissions': QtCore.QVariant(permissions.value), 'permissions': QtCore.QVariant(permissions.value),
'text': QtCore.QVariant(verse.text), 'text': QtCore.QVariant(verse.text),
'dual_bible': QtCore.QVariant(u''), 'second_bible': QtCore.QVariant(u''),
'dual_version': QtCore.QVariant(u''), 'second_version': QtCore.QVariant(u''),
'dual_copyright': QtCore.QVariant(u''), 'second_copyright': QtCore.QVariant(u''),
'dual_permissions': QtCore.QVariant(u''), 'second_permissions': QtCore.QVariant(u''),
'dual_text': QtCore.QVariant(u'') 'second_text': QtCore.QVariant(u'')
} }
bible_text = u' %s %d:%d (%s)' % (verse.book.name, bible_text = u'%s %d:%d (%s)' % (verse.book.name,
verse.chapter, verse.verse, version.value) verse.chapter, verse.verse, version.value)
bible_verse = QtGui.QListWidgetItem(bible_text) bible_verse = QtGui.QListWidgetItem(bible_text)
bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(vdict)) bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(vdict))
self.listView.addItem(bible_verse) self.listView.addItem(bible_verse)
row = self.listView.setCurrentRow(count + start_count) self.listView.selectAll()
if row:
row.setSelected(True)
self.search_results = {} self.search_results = {}
self.dual_search_results = {} self.second_search_results = {}
def _decodeQtObject(self, bitem, key): def _decodeQtObject(self, bitem, key):
reference = bitem.data(QtCore.Qt.UserRole) reference = bitem.data(QtCore.Qt.UserRole)
@ -651,7 +711,7 @@ class BibleMediaItem(MediaManagerItem):
obj = obj.toPyObject() obj = obj.toPyObject()
return unicode(obj) return unicode(obj)
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None, xmlVersion=False):
""" """
Generates and formats the slides for the service item as well as the Generates and formats the slides for the service item as well as the
service item's title. service item's title.
@ -661,7 +721,7 @@ class BibleMediaItem(MediaManagerItem):
if len(items) == 0: if len(items) == 0:
return False return False
bible_text = u'' bible_text = u''
old_chapter = u'' old_chapter = -1
raw_footer = [] raw_footer = []
raw_slides = [] raw_slides = []
raw_title = [] raw_title = []
@ -676,22 +736,22 @@ class BibleMediaItem(MediaManagerItem):
copyright = self._decodeQtObject(bitem, 'copyright') copyright = self._decodeQtObject(bitem, 'copyright')
permissions = self._decodeQtObject(bitem, 'permissions') permissions = self._decodeQtObject(bitem, 'permissions')
text = self._decodeQtObject(bitem, 'text') text = self._decodeQtObject(bitem, 'text')
dual_bible = self._decodeQtObject(bitem, 'dual_bible') second_bible = self._decodeQtObject(bitem, 'second_bible')
dual_version = self._decodeQtObject(bitem, 'dual_version') second_version = self._decodeQtObject(bitem, 'second_version')
dual_copyright = self._decodeQtObject(bitem, 'dual_copyright') second_copyright = self._decodeQtObject(bitem, 'second_copyright')
dual_permissions = self._decodeQtObject(bitem, 'dual_permissions') second_permissions = self._decodeQtObject(bitem, 'second_permissions')
dual_text = self._decodeQtObject(bitem, 'dual_text') second_text = self._decodeQtObject(bitem, 'second_text')
verse_text = self.formatVerse(old_chapter, chapter, verse) verse_text = self.formatVerse(old_chapter, chapter, verse)
footer = u'%s (%s %s %s)' % (book, version, copyright, permissions) footer = u'%s (%s %s %s)' % (book, version, copyright, permissions)
if footer not in raw_footer: if footer not in raw_footer:
raw_footer.append(footer) raw_footer.append(footer)
if dual_bible: if second_bible:
footer = u'%s (%s %s %s)' % (book, dual_version, dual_copyright, footer = u'%s (%s %s %s)' % (book, second_version,
dual_permissions) second_copyright, second_permissions)
if footer not in raw_footer: if footer not in raw_footer:
raw_footer.append(footer) raw_footer.append(footer)
bible_text = u'%s %s\n\n%s %s' % (verse_text, text, verse_text, bible_text = u'%s %s\n\n%s %s' % (verse_text, text, verse_text,
dual_text) second_text)
raw_slides.append(bible_text) raw_slides.append(bible_text)
bible_text = u'' bible_text = u''
# If we are 'Verse Per Slide' then create a new slide. # If we are 'Verse Per Slide' then create a new slide.
@ -719,7 +779,7 @@ class BibleMediaItem(MediaManagerItem):
raw_slides.append(bible_text) raw_slides.append(bible_text)
bible_text = u'' bible_text = u''
# Service Item: Capabilities # Service Item: Capabilities
if self.parent.settings_tab.layout_style == 2 and not dual_bible: if self.parent.settings_tab.layout_style == 2 and not second_bible:
# Split the line but do not replace line breaks in renderer. # Split the line but do not replace line breaks in renderer.
service_item.add_capability(ItemCapabilities.NoLineBreaks) service_item.add_capability(ItemCapabilities.NoLineBreaks)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
@ -749,6 +809,12 @@ class BibleMediaItem(MediaManagerItem):
This methode is called, when we have to change the title, because This methode is called, when we have to change the title, because
we are at the end of a verse range. E. g. if we want to add we are at the end of a verse range. E. g. if we want to add
Genesis 1:1-6 as well as Daniel 2:14. Genesis 1:1-6 as well as Daniel 2:14.
``start_item``
The first item of a range.
``old_item``
The last item of a range.
""" """
old_bitem = self.listView.item(old_item.row()) old_bitem = self.listView.item(old_item.row())
old_chapter = int(self._decodeQtObject(old_bitem, 'chapter')) old_chapter = int(self._decodeQtObject(old_bitem, 'chapter'))
@ -758,18 +824,18 @@ class BibleMediaItem(MediaManagerItem):
start_chapter = int(self._decodeQtObject(start_bitem, 'chapter')) start_chapter = int(self._decodeQtObject(start_bitem, 'chapter'))
start_verse = int(self._decodeQtObject(start_bitem, 'verse')) start_verse = int(self._decodeQtObject(start_bitem, 'verse'))
start_bible = self._decodeQtObject(start_bitem, 'bible') start_bible = self._decodeQtObject(start_bitem, 'bible')
start_dual_bible = self._decodeQtObject(start_bitem, 'dual_bible') start_second_bible = self._decodeQtObject(start_bitem, 'second_bible')
if start_dual_bible: if start_second_bible:
if start_verse == old_verse and start_chapter == old_chapter: if start_verse == old_verse and start_chapter == old_chapter:
title = u'%s %s:%s (%s, %s)' % (start_book, start_chapter, title = u'%s %s:%s (%s, %s)' % (start_book, start_chapter,
start_verse, start_bible, start_dual_bible) start_verse, start_bible, start_second_bible)
elif start_chapter == old_chapter: elif start_chapter == old_chapter:
title = u'%s %s:%s-%s (%s, %s)' % (start_book, start_chapter, title = u'%s %s:%s-%s (%s, %s)' % (start_book, start_chapter,
start_verse, old_verse, start_bible, start_dual_bible) start_verse, old_verse, start_bible, start_second_bible)
else: else:
title = u'%s %s:%s-%s:%s (%s, %s)' % (start_book, start_chapter, title = u'%s %s:%s-%s:%s (%s, %s)' % (start_book, start_chapter,
start_verse, old_chapter, old_verse, start_bible, start_verse, old_chapter, old_verse, start_bible,
start_dual_bible) start_second_bible)
else: else:
if start_verse == old_verse and start_chapter == old_chapter: if start_verse == old_verse and start_chapter == old_chapter:
title = u'%s %s:%s (%s)' % (start_book, start_chapter, title = u'%s %s:%s (%s)' % (start_book, start_chapter,
@ -785,34 +851,62 @@ class BibleMediaItem(MediaManagerItem):
def checkTitle(self, item, old_item): def checkTitle(self, item, old_item):
""" """
This methode checks if we are at the end of an verse range. If that is This methode checks if we are at the end of an verse range. If that is
the case, we return True, else False. E. g. if we added Genesis 1:1-6, the case, we return True, otherwise False. E. g. if we added
but the next verse is Daniel 2:14. Genesis 1:1-6, but the next verse is Daniel 2:14, we return True.
``item``
The item we are dealing with at the moment.
``old_item``
The item we were previously dealing with.
""" """
# Get all the necessary meta data.
bitem = self.listView.item(item.row()) bitem = self.listView.item(item.row())
book = self._decodeQtObject(bitem, 'book') book = self._decodeQtObject(bitem, 'book')
chapter = int(self._decodeQtObject(bitem, 'chapter')) chapter = int(self._decodeQtObject(bitem, 'chapter'))
verse = int(self._decodeQtObject(bitem, 'verse')) verse = int(self._decodeQtObject(bitem, 'verse'))
bible = self._decodeQtObject(bitem, 'bible') bible = self._decodeQtObject(bitem, 'bible')
dual_bible = self._decodeQtObject(bitem, 'dual_bible') second_bible = self._decodeQtObject(bitem, 'second_bible')
old_bitem = self.listView.item(old_item.row()) old_bitem = self.listView.item(old_item.row())
old_book = self._decodeQtObject(old_bitem, 'book') old_book = self._decodeQtObject(old_bitem, 'book')
old_chapter = int(self._decodeQtObject(old_bitem, 'chapter')) old_chapter = int(self._decodeQtObject(old_bitem, 'chapter'))
old_verse = int(self._decodeQtObject(old_bitem, 'verse')) old_verse = int(self._decodeQtObject(old_bitem, 'verse'))
old_bible = self._decodeQtObject(old_bitem, 'bible') old_bible = self._decodeQtObject(old_bitem, 'bible')
old_dual_bible = self._decodeQtObject(old_bitem, 'dual_bible') old_second_bible = self._decodeQtObject(old_bitem, 'second_bible')
if old_bible != bible or old_dual_bible != dual_bible or \ if old_bible != bible or old_second_bible != second_bible or \
old_book != book: old_book != book:
# The bible, second bible or book has changed.
return True return True
elif old_verse + 1 != verse and old_chapter == chapter: elif old_verse + 1 != verse and old_chapter == chapter:
# We are still in the same chapter, but a verse has been skipped.
return True return True
elif old_chapter + 1 == chapter and (verse != 1 or elif old_chapter + 1 == chapter and (verse != 1 or
old_verse != self.parent.manager.get_verse_count( old_verse != self.parent.manager.get_verse_count(
old_bible, old_book, old_chapter)): old_bible, old_book, old_chapter)):
# We are in the following chapter, but the last verse was not the
# last verse of the chapter or the current verse is not the
# first one of the chapter.
return True return True
else: else:
return False return False
def formatVerse(self, old_chapter, chapter, verse): def formatVerse(self, old_chapter, chapter, verse):
"""
Formats and returns the text, each verse starts with, for the given
chapter and verse. The text is either surrounded by round, square,
curly brackets or no brackets at all. For example::
u'{su}1:1{/su}'
``old_chapter``
The previous verse's chapter number (int).
``chapter``
The chapter number (int).
``verse``
The verse number (int).
"""
if not self.parent.settings_tab.show_new_chapters or \ if not self.parent.settings_tab.show_new_chapters or \
old_chapter != chapter: old_chapter != chapter:
verse_text = u'%s:%s' % (chapter, verse) verse_text = u'%s:%s' % (chapter, verse)

View File

@ -46,7 +46,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
Constructor Constructor
""" """
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
#self.parent = parent
self.setupUi(self) self.setupUi(self)
# Connecting signals and slots # Connecting signals and slots
self.previewButton = QtGui.QPushButton() self.previewButton = QtGui.QPushButton()
@ -124,8 +123,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.slideListView.addItem(slide[1]) self.slideListView.addItem(slide[1])
theme = self.customSlide.theme_name theme = self.customSlide.theme_name
id = self.themeComboBox.findText(theme, QtCore.Qt.MatchExactly) id = self.themeComboBox.findText(theme, QtCore.Qt.MatchExactly)
# No theme match
if id == -1: if id == -1:
id = 0 # Not Found id = 0
self.themeComboBox.setCurrentIndex(id) self.themeComboBox.setCurrentIndex(id)
else: else:
self.themeComboBox.setCurrentIndex(0) self.themeComboBox.setCurrentIndex(0)
@ -264,7 +264,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.titleEdit.setFocus() self.titleEdit.setFocus()
return False, translate('CustomPlugin.EditCustomForm', return False, translate('CustomPlugin.EditCustomForm',
'You need to type in a title.') 'You need to type in a title.')
# We must have one slide. # We must have at least one slide.
if self.slideListView.count() == 0: if self.slideListView.count() == 0:
return False, translate('CustomPlugin.EditCustomForm', return False, translate('CustomPlugin.EditCustomForm',
'You need to add at least one slide') 'You need to add at least one slide')

View File

@ -50,7 +50,7 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
def setText(self, text): def setText(self, text):
""" """
Set the text for slideTextEdit. Set the text for slideTextEdit.
``text`` ``text``
The text (unicode). The text (unicode).
""" """
@ -67,7 +67,7 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
def onSplitButtonPressed(self): def onSplitButtonPressed(self):
""" """
Splits a slide in two slides. Adds a slide split at the cursor.
""" """
if self.slideTextEdit.textCursor().columnNumber() != 0: if self.slideTextEdit.textCursor().columnNumber() != 0:
self.slideTextEdit.insertPlainText(u'\n') self.slideTextEdit.insertPlainText(u'\n')

View File

@ -42,8 +42,8 @@ The basic XML is of the format::
import logging import logging
from xml.dom.minidom import Document from xml.dom.minidom import Document
from xml.etree.ElementTree import ElementTree, XML, dump from xml.etree.ElementTree import dump
from xml.parsers.expat import ExpatError from lxml import etree, objectify
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -55,14 +55,14 @@ class CustomXMLBuilder(object):
def __init__(self): def __init__(self):
""" """
Set up the song builder. Set up the custom builder.
""" """
# Create the minidom document # Create the minidom document
self.custom_xml = Document() self.custom_xml = Document()
def new_document(self): def new_document(self):
""" """
Create a new song XML document. Create a new custom XML document.
""" """
# Create the <song> base element # Create the <song> base element
self.song = self.custom_xml.createElement(u'song') self.song = self.custom_xml.createElement(u'song')
@ -72,7 +72,7 @@ class CustomXMLBuilder(object):
def add_lyrics_to_song(self): def add_lyrics_to_song(self):
""" """
Set up and add a ``<lyrics>`` tag which contains the lyrics of the Set up and add a ``<lyrics>`` tag which contains the lyrics of the
song. custom item.
""" """
# Create the main <lyrics> element # Create the main <lyrics> element
self.lyrics = self.custom_xml.createElement(u'lyrics') self.lyrics = self.custom_xml.createElement(u'lyrics')
@ -93,7 +93,6 @@ class CustomXMLBuilder(object):
``content`` ``content``
The actual text of the verse to be stored. The actual text of the verse to be stored.
""" """
#log.debug(u'add_verse_to_lyrics %s, %s\n%s' % (type, number, content))
verse = self.custom_xml.createElement(u'verse') verse = self.custom_xml.createElement(u'verse')
verse.setAttribute(u'type', type) verse.setAttribute(u'type', type)
verse.setAttribute(u'label', number) verse.setAttribute(u'label', number)
@ -102,7 +101,7 @@ class CustomXMLBuilder(object):
cds = self.custom_xml.createCDATASection(content) cds = self.custom_xml.createCDATASection(content)
verse.appendChild(cds) verse.appendChild(cds)
def dump_xml(self): def _dump_xml(self):
""" """
Debugging aid to dump XML so that we can see what we have. Debugging aid to dump XML so that we can see what we have.
""" """
@ -110,29 +109,30 @@ class CustomXMLBuilder(object):
def extract_xml(self): def extract_xml(self):
""" """
Extract our newly created XML song. Extract our newly created XML custom.
""" """
return self.custom_xml.toxml(u'utf-8') return self.custom_xml.toxml(u'utf-8')
class CustomXMLParser(object): class CustomXMLParser(object):
""" """
A class to read in and parse a song's XML. A class to read in and parse a custom's XML.
""" """
log.info(u'CustomXMLParser Loaded') log.info(u'CustomXMLParser Loaded')
def __init__(self, xml): def __init__(self, xml):
""" """
Set up our song XML parser. Set up our custom XML parser.
``xml`` ``xml``
The XML of the song to be parsed. The XML of the custom to be parsed.
""" """
self.custom_xml = None self.custom_xml = None
if xml[:5] == u'<?xml':
xml = xml[38:]
try: try:
self.custom_xml = ElementTree( self.custom_xml = objectify.fromstring(xml)
element=XML(unicode(xml).encode('unicode-escape'))) except etree.XMLSyntaxError:
except ExpatError:
log.exception(u'Invalid xml %s', xml) log.exception(u'Invalid xml %s', xml)
def get_verses(self): def get_verses(self):
@ -146,11 +146,10 @@ class CustomXMLParser(object):
if element.tag == u'verse': if element.tag == u'verse':
if element.text is None: if element.text is None:
element.text = u'' element.text = u''
verse_list.append([element.attrib, verse_list.append([element.attrib, unicode(element.text)])
unicode(element.text).decode('unicode-escape')])
return verse_list return verse_list
def dump_xml(self): def _dump_xml(self):
""" """
Debugging aid to dump XML so that we can see what we have. Debugging aid to dump XML so that we can see what we have.
""" """

View File

@ -74,9 +74,9 @@ class CustomMediaItem(MediaManagerItem):
def initialise(self): def initialise(self):
self.loadCustomListView(self.manager.get_all_objects( self.loadCustomListView(self.manager.get_all_objects(
CustomSlide, order_by_ref=CustomSlide.title)) CustomSlide, order_by_ref=CustomSlide.title))
#Called to redisplay the song list screen edith from a search # Called to redisplay the custom list screen edith from a search
#or from the exit of the Song edit dialog. If remote editing is active # or from the exit of the Custom edit dialog. If remote editing is
#Trigger it and clean up so it will not update again. # active trigger it and clean up so it will not update again.
if self.remoteTriggered == u'L': if self.remoteTriggered == u'L':
self.onAddClick() self.onAddClick()
if self.remoteTriggered == u'P': if self.remoteTriggered == u'P':
@ -144,7 +144,7 @@ class CustomMediaItem(MediaManagerItem):
for row in row_list: for row in row_list:
self.listView.takeItem(row) self.listView.takeItem(row)
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None, xmlVersion=False):
raw_slides = [] raw_slides = []
raw_footer = [] raw_footer = []
slide = None slide = None
@ -165,7 +165,7 @@ class CustomMediaItem(MediaManagerItem):
customSlide = self.parent.manager.get_object(CustomSlide, item_id) customSlide = self.parent.manager.get_object(CustomSlide, item_id)
title = customSlide.title title = customSlide.title
credit = customSlide.credits credit = customSlide.credits
service_item.editId = item_id service_item.edit_id = item_id
theme = customSlide.theme_name theme = customSlide.theme_name
if theme: if theme:
service_item.theme = theme service_item.theme = theme

View File

@ -154,7 +154,7 @@ class ImageMediaItem(MediaManagerItem):
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
self.listView.addItem(item_name) self.listView.addItem(item_name)
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None, xmlVersion=False):
items = self.listView.selectedIndexes() items = self.listView.selectedIndexes()
if items: if items:
service_item.title = unicode( service_item.title = unicode(
@ -163,6 +163,8 @@ class ImageMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)
service_item.add_capability(ItemCapabilities.AllowsAdditions) service_item.add_capability(ItemCapabilities.AllowsAdditions)
# force a nonexistent theme
service_item.theme = -1
for item in items: for item in items:
bitem = self.listView.item(item.row()) bitem = self.listView.item(item.row())
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString()) filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())

View File

@ -116,7 +116,7 @@ class MediaMediaItem(MediaManagerItem):
self.parent.liveController.display.video(filename, 0, True) self.parent.liveController.display.video(filename, 0, True)
self.resetButton.setVisible(True) self.resetButton.setVisible(True)
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None, xmlVersion=False):
if item is None: if item is None:
item = self.listView.currentItem() item = self.listView.currentItem()
if item is None: if item is None:
@ -125,6 +125,8 @@ class MediaMediaItem(MediaManagerItem):
service_item.title = unicode( service_item.title = unicode(
translate('MediaPlugin.MediaItem', 'Media')) translate('MediaPlugin.MediaItem', 'Media'))
service_item.add_capability(ItemCapabilities.RequiresMedia) service_item.add_capability(ItemCapabilities.RequiresMedia)
# force a nonexistent theme
service_item.theme = -1
frame = u':/media/image_clapperboard.png' frame = u':/media/image_clapperboard.png'
(path, name) = os.path.split(filename) (path, name) = os.path.split(filename)
service_item.add_from_command(path, name, frame) service_item.add_from_command(path, name, frame)

View File

@ -38,7 +38,7 @@ log = logging.getLogger(__name__)
class PresentationListView(BaseListWithDnD): class PresentationListView(BaseListWithDnD):
""" """
Class for the list of Presentations Class for the list of Presentations
We have to explicitly create separate classes for each plugin We have to explicitly create separate classes for each plugin
in order for DnD to the Service manager to work correctly. in order for DnD to the Service manager to work correctly.
""" """
@ -67,7 +67,7 @@ class PresentationMediaItem(MediaManagerItem):
self.message_listener = MessageListener(self) self.message_listener = MessageListener(self)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild) QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild)
def retranslateUi(self): def retranslateUi(self):
""" """
The name of the plugin media displayed in UI The name of the plugin media displayed in UI
@ -159,7 +159,7 @@ class PresentationMediaItem(MediaManagerItem):
if self.DisplayTypeComboBox.count() > 1: if self.DisplayTypeComboBox.count() > 1:
self.DisplayTypeComboBox.insertItem(0, self.Automatic) self.DisplayTypeComboBox.insertItem(0, self.Automatic)
self.DisplayTypeComboBox.setCurrentIndex(0) self.DisplayTypeComboBox.setCurrentIndex(0)
if QtCore.QSettings().value(self.settingsSection + u'/override app', if QtCore.QSettings().value(self.settingsSection + u'/override app',
QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked: QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
self.PresentationWidget.show() self.PresentationWidget.show()
else: else:
@ -238,7 +238,7 @@ class PresentationMediaItem(MediaManagerItem):
SettingsManager.set_list(self.settingsSection, SettingsManager.set_list(self.settingsSection,
self.settingsSection, self.getFileList()) self.settingsSection, self.getFileList())
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None, xmlVersion=False):
""" """
Load the relevant information for displaying the presentation Load the relevant information for displaying the presentation
in the slidecontroller. In the case of powerpoints, an image in the slidecontroller. In the case of powerpoints, an image
@ -277,7 +277,7 @@ class PresentationMediaItem(MediaManagerItem):
def findControllerByType(self, filename): def findControllerByType(self, filename):
""" """
Determine the default application controller to use for the selected Determine the default application controller to use for the selected
file type. This is used if "Automatic" is set as the preferred file type. This is used if "Automatic" is set as the preferred
controller. Find the first (alphabetic) enabled controller which controller. Find the first (alphabetic) enabled controller which
"supports" the extension. If none found, then look for a controller "supports" the extension. If none found, then look for a controller
which "alsosupports" it instead. which "alsosupports" it instead.

View File

@ -152,6 +152,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def newSong(self): def newSong(self):
log.debug(u'New Song') log.debug(u'New Song')
self.initialise()
self.SongTabWidget.setCurrentIndex(0) self.SongTabWidget.setCurrentIndex(0)
self.TitleEditItem.setText(u'') self.TitleEditItem.setText(u'')
self.AlternativeEdit.setText(u'') self.AlternativeEdit.setText(u'')
@ -170,8 +171,18 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
# it's a new song to preview is not possible # it's a new song to preview is not possible
self.previewButton.setVisible(False) self.previewButton.setVisible(False)
def loadSong(self, id, preview): def loadSong(self, id, preview=False):
"""
Loads a song.
``id``
The song id (int).
``preview``
Should be ``True`` if the song is also previewed (boolean).
"""
log.debug(u'Load Song') log.debug(u'Load Song')
self.initialise()
self.SongTabWidget.setCurrentIndex(0) self.SongTabWidget.setCurrentIndex(0)
self.loadAuthors() self.loadAuthors()
self.loadTopics() self.loadTopics()
@ -594,6 +605,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
""" """
Save and Preview button pressed. Save and Preview button pressed.
The Song is valid so as the plugin to add it to preview to see. The Song is valid so as the plugin to add it to preview to see.
``button``
A button (QPushButton).
""" """
log.debug(u'onPreview') log.debug(u'onPreview')
if unicode(button.objectName()) == u'previewButton' and \ if unicode(button.objectName()) == u'previewButton' and \
@ -631,13 +645,16 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
database. database.
``preview`` ``preview``
Should be True if song is also previewed. Should be ``True`` if the song is also previewed (boolean).
""" """
self.song.title = unicode(self.TitleEditItem.text()) self.song.title = unicode(self.TitleEditItem.text())
self.song.alternate_title = unicode(self.AlternativeEdit.text()) self.song.alternate_title = unicode(self.AlternativeEdit.text())
self.song.copyright = unicode(self.CopyrightEditItem.text()) self.song.copyright = unicode(self.CopyrightEditItem.text())
self.song.search_title = self.song.title + u'@' + \ if self.song.alternate_title:
self.song.alternate_title self.song.search_title = self.song.title + u'@' + \
self.song.alternate_title
else:
self.song.search_title = self.song.title
self.song.comments = unicode(self.CommentsEdit.toPlainText()) self.song.comments = unicode(self.CommentsEdit.toPlainText())
self.song.verse_order = unicode(self.VerseOrderEdit.text()) self.song.verse_order = unicode(self.VerseOrderEdit.text())
self.song.ccli_number = unicode(self.CCLNumberEdit.text()) self.song.ccli_number = unicode(self.CCLNumberEdit.text())
@ -648,6 +665,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
Book.name == book_name) Book.name == book_name)
else: else:
self.song.book = None self.song.book = None
theme_name = unicode(self.ThemeSelectionComboItem.currentText())
if theme_name:
self.song.theme_name = theme_name
else:
self.song.theme_name = None
if self._validate_song(): if self._validate_song():
self.processLyrics() self.processLyrics()
self.processTitle() self.processTitle()

View File

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

View File

@ -507,8 +507,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
filenames=self.getListOfFiles( filenames=self.getListOfFiles(
self.songBeamerFileListWidget) self.songBeamerFileListWidget)
) )
success = importer.do_import() if importer.do_import():
if success:
# reload songs # reload songs
self.importProgressLabel.setText( self.importProgressLabel.setText(
translate('SongsPlugin.SongImportForm', 'Finished import.')) translate('SongsPlugin.SongImportForm', 'Finished import.'))

View File

@ -405,7 +405,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def mergeAuthors(self, old_author): def mergeAuthors(self, old_author):
""" """
Merges two authors into one author. Merges two authors into one author.
``old_author`` ``old_author``
The author which will be deleted afterwards. The author which will be deleted afterwards.
""" """
@ -427,7 +427,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def mergeTopics(self, old_topic): def mergeTopics(self, old_topic):
""" """
Merges two topics into one topic. Merges two topics into one topic.
``old_topic`` ``old_topic``
The topic which will be deleted afterwards. The topic which will be deleted afterwards.
""" """
@ -447,7 +447,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def mergeBooks(self, old_book): def mergeBooks(self, old_book):
""" """
Merges two books into one book. Merges two books into one book.
``old_book`` ``old_book``
The book which will be deleted afterwards. The book which will be deleted afterwards.
""" """

View File

@ -62,6 +62,36 @@ class VerseType(object):
elif verse_type == VerseType.Other: elif verse_type == VerseType.Other:
return translate('SongsPlugin.VerseType', 'Other') return translate('SongsPlugin.VerseType', 'Other')
@staticmethod
def expand_string(verse_type):
"""
Return the VerseType for a given string
``verse_type``
The string to return a VerseType for
"""
verse_type = verse_type.lower()
if verse_type == unicode(VerseType.to_string(VerseType.Verse)).lower()[0]:
return translate('SongsPlugin.VerseType', 'Verse')
elif verse_type == \
unicode(VerseType.to_string(VerseType.Chorus)).lower()[0]:
return translate('SongsPlugin.VerseType', 'Chorus')
elif verse_type == \
unicode(VerseType.to_string(VerseType.Bridge)).lower()[0]:
return translate('SongsPlugin.VerseType', 'Bridge')
elif verse_type == \
unicode(VerseType.to_string(VerseType.PreChorus)).lower()[0]:
return translate('SongsPlugin.VerseType', 'PreChorus')
elif verse_type == \
unicode(VerseType.to_string(VerseType.Intro)).lower()[0]:
return translate('SongsPlugin.VerseType', 'Intro')
elif verse_type == \
unicode(VerseType.to_string(VerseType.Ending)).lower()[0]:
return translate('SongsPlugin.VerseType', 'Ending')
elif verse_type == \
unicode(VerseType.to_string(VerseType.Other)).lower()[0]:
return translate('SongsPlugin.VerseType', 'Other')
@staticmethod @staticmethod
def from_string(verse_type): def from_string(verse_type):
""" """
@ -92,7 +122,6 @@ class VerseType(object):
unicode(VerseType.to_string(VerseType.Other)).lower(): unicode(VerseType.to_string(VerseType.Other)).lower():
return VerseType.Other return VerseType.Other
from xml import LyricsXML, SongXMLBuilder, SongXMLParser, OpenLyricsParser
from xml import LyricsXML, SongXMLBuilder, SongXMLParser
from songstab import SongsTab from songstab import SongsTab
from mediaitem import SongMediaItem from mediaitem import SongMediaItem

View File

@ -32,7 +32,7 @@ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \
ItemCapabilities, translate, check_item_selected ItemCapabilities, translate, check_item_selected
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm SongImportForm
from openlp.plugins.songs.lib import SongXMLParser from openlp.plugins.songs.lib import SongXMLParser, OpenLyricsParser
from openlp.plugins.songs.lib.db import Author, Song from openlp.plugins.songs.lib.db import Author, Song
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -53,8 +53,8 @@ class SongMediaItem(MediaManagerItem):
self.ListViewWithDnD_class = SongListView self.ListViewWithDnD_class = SongListView
MediaManagerItem.__init__(self, parent, self, icon) MediaManagerItem.__init__(self, parent, self, icon)
self.edit_song_form = EditSongForm(self, self.parent.manager) self.edit_song_form = EditSongForm(self, self.parent.manager)
self.openLyrics = OpenLyricsParser(self.parent.manager)
self.singleServiceItem = False self.singleServiceItem = False
#self.edit_song_form = EditSongForm(self.parent.manager, self)
self.song_maintenance_form = SongMaintenanceForm( self.song_maintenance_form = SongMaintenanceForm(
self.parent.manager, self) self.parent.manager, self)
# Holds information about whether the edit is remotly triggered and # Holds information about whether the edit is remotly triggered and
@ -114,6 +114,8 @@ class SongMediaItem(MediaManagerItem):
self.SearchButtonLayout.addWidget(self.ClearTextButton) self.SearchButtonLayout.addWidget(self.ClearTextButton)
self.pageLayout.addLayout(self.SearchButtonLayout) self.pageLayout.addLayout(self.SearchButtonLayout)
# Signals and slots # Signals and slots
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'plugin_list_refresh'), self.onSearchTextButtonClick)
QtCore.QObject.connect(self.SearchTextEdit, QtCore.QObject.connect(self.SearchTextEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick) QtCore.SIGNAL(u'returnPressed()'), self.onSearchTextButtonClick)
QtCore.QObject.connect(self.SearchTextButton, QtCore.QObject.connect(self.SearchTextButton,
@ -141,7 +143,7 @@ class SongMediaItem(MediaManagerItem):
self.updateServiceOnEdit = QtCore.QSettings().value( self.updateServiceOnEdit = QtCore.QSettings().value(
self.settingsSection + u'/update service on edit', self.settingsSection + u'/update service on edit',
QtCore.QVariant(u'False')).toBool() QtCore.QVariant(u'False')).toBool()
self.AddSongFromServide = QtCore.QSettings().value( self.addSongFromService = QtCore.QSettings().value(
self.settingsSection + u'/add song from service', self.settingsSection + u'/add song from service',
QtCore.QVariant(u'True')).toBool() QtCore.QVariant(u'True')).toBool()
@ -192,6 +194,7 @@ class SongMediaItem(MediaManagerItem):
Handle the exit from the edit dialog and trigger remote updates Handle the exit from the edit dialog and trigger remote updates
of songs of songs
""" """
log.debug(u'onSongListLoad')
# Called to redisplay the song list screen edit from a search # 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 # 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. # Trigger it and clean up so it will not update again.
@ -259,6 +262,7 @@ class SongMediaItem(MediaManagerItem):
Receiver.send_message(u'songs_load_list') Receiver.send_message(u'songs_load_list')
def onNewClick(self): def onNewClick(self):
log.debug(u'onNewClick')
self.edit_song_form.newSong() self.edit_song_form.newSong()
self.edit_song_form.exec_() self.edit_song_form.exec_()
@ -266,6 +270,7 @@ class SongMediaItem(MediaManagerItem):
self.song_maintenance_form.exec_() self.song_maintenance_form.exec_()
def onRemoteEditClear(self): def onRemoteEditClear(self):
log.debug(u'onRemoteEditClear')
self.remoteTriggered = None self.remoteTriggered = None
self.remoteSong = -1 self.remoteSong = -1
@ -275,6 +280,7 @@ class SongMediaItem(MediaManagerItem):
the Song Id in the payload along with an indicator to say which the Song Id in the payload along with an indicator to say which
type of display is required. type of display is required.
""" """
log.debug(u'onRemoteEdit %s' % songid)
fields = songid.split(u':') fields = songid.split(u':')
valid = self.parent.manager.get_object(Song, fields[1]) valid = self.parent.manager.get_object(Song, fields[1])
if valid: if valid:
@ -287,6 +293,7 @@ class SongMediaItem(MediaManagerItem):
""" """
Edit a song Edit a song
""" """
log.debug(u'onEditClick')
if check_item_selected(self.listView, if check_item_selected(self.listView,
translate('SongsPlugin.MediaItem', translate('SongsPlugin.MediaItem',
'You must select an item to edit.')): 'You must select an item to edit.')):
@ -323,7 +330,8 @@ class SongMediaItem(MediaManagerItem):
self.parent.manager.delete_object(Song, item_id) self.parent.manager.delete_object(Song, item_id)
self.onSearchTextButtonClick() self.onSearchTextButtonClick()
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None, xmlVersion=False):
log.debug(u'generateSlideData (%s:%s)' % (service_item, item))
raw_footer = [] raw_footer = []
author_list = u'' author_list = u''
author_audit = [] author_audit = []
@ -345,11 +353,11 @@ class SongMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.AddIfNewItem) service_item.add_capability(ItemCapabilities.AddIfNewItem)
song = self.parent.manager.get_object(Song, item_id) song = self.parent.manager.get_object(Song, item_id)
service_item.theme = song.theme_name service_item.theme = song.theme_name
service_item.editId = item_id service_item.edit_id = item_id
if song.lyrics.startswith(u'<?xml version='): if song.lyrics.startswith(u'<?xml version='):
songXML = SongXMLParser(song.lyrics) songXML = SongXMLParser(song.lyrics)
verseList = songXML.get_verses() verseList = songXML.get_verses()
#no verse list or only 1 space (in error) # no verse list or only 1 space (in error)
if not song.verse_order or not song.verse_order.strip(): if not song.verse_order or not song.verse_order.strip():
for verse in verseList: for verse in verseList:
verseTag = u'%s:%s' % ( verseTag = u'%s:%s' % (
@ -357,7 +365,7 @@ class SongMediaItem(MediaManagerItem):
service_item.add_from_text( service_item.add_from_text(
verse[1][:30], unicode(verse[1]), verseTag) verse[1][:30], unicode(verse[1]), verseTag)
else: 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(): for order in song.verse_order.upper().split():
if len(order) == 0: if len(order) == 0:
break break
@ -391,30 +399,41 @@ class SongMediaItem(MediaManagerItem):
] ]
service_item.data_string = {u'title':song.search_title, service_item.data_string = {u'title':song.search_title,
u'authors':author_list} u'authors':author_list}
service_item.xml_version = self.openLyrics.song_to_xml(song)
return True return True
def serviceLoad(self, item): def serviceLoad(self, item):
""" """
Triggered by a song being loaded by the service item Triggered by a song being loaded by the service item
""" """
log.debug(u'serviceLoad')
if item.data_string: if item.data_string:
search_results = self.parent.manager.get_all_objects(Song, search_results = self.parent.manager.get_all_objects(Song,
Song.search_title.like(u'%' + Song.search_title ==
item.data_string[u'title'].split(u'@')[0] + u'%'), item.data_string[u'title'].split(u'@')[0].lower() ,
Song.search_title.asc()) Song.search_title.asc())
author_list = item.data_string[u'authors'].split(u',') author_list = item.data_string[u'authors'].split(u', ')
editId = 0 editId = 0
uuid = 0 uuid = item._uuid
if search_results: if search_results:
for song in search_results: for song in search_results:
count = 0 count = 0
for author in song.authors: for author in song.authors:
if author.display_name in author_list: if author.display_name in author_list:
count += 1 count += 1
# All Authors the same
if count == len(author_list): if count == len(author_list):
editId = song.id editId = song.id
uuid = item._uuid else:
# Authors different
if self.addSongFromService:
editId = self.openLyrics. \
xml_to_song(item.xml_version)
else:
# Title does not match
if self.addSongFromService:
editId = self.openLyrics.xml_to_song(item.xml_version)
# Update service with correct song id
if editId != 0: if editId != 0:
Receiver.send_message(u'service_item_update', Receiver.send_message(u'service_item_update',
u'%s:%s' %(editId, uuid)) u'%s:%s' %(editId, uuid))

View File

@ -152,7 +152,7 @@ class OpenLPSongImport(SongImport):
u'Importing song %s of %s' % (song_count, song_total)) u'Importing song %s of %s' % (song_count, song_total))
new_song = Song() new_song = Song()
new_song.title = song.title new_song.title = song.title
if has_media_files: if has_media_files and hasattr(song, 'alternate_title'):
new_song.alternate_title = song.alternate_title new_song.alternate_title = song.alternate_title
else: else:
old_titles = song.search_title.split(u'@') old_titles = song.search_title.split(u'@')

View File

@ -57,15 +57,17 @@ class SongBeamerTypes(object):
u'Unknown': u'O' u'Unknown': u'O'
} }
class SongBeamerImport(SongImport): class SongBeamerImport(SongImport):
""" """
Import Song Beamer files(s) Import Song Beamer files(s)
Song Beamer file format is text based Song Beamer file format is text based
in the beginning are one or more control tags written in the beginning are one or more control tags written
""" """
def __init__(self, master_manager, **kwargs): def __init__(self, master_manager, **kwargs):
""" """
Initialise the import. Initialise the import.
``master_manager`` ``master_manager``
The song manager for the running OpenLP installation. The song manager for the running OpenLP installation.
""" """
@ -88,6 +90,7 @@ class SongBeamerImport(SongImport):
# TODO: check that it is a valid SongBeamer file # TODO: check that it is a valid SongBeamer file
self.current_verse = u'' self.current_verse = u''
self.current_verse_type = u'V' self.current_verse_type = u'V'
read_verses = False
self.file_name = os.path.split(file)[1] self.file_name = os.path.split(file)[1]
self.import_wizard.incrementProgressBar( self.import_wizard.incrementProgressBar(
"Importing %s" % (self.file_name), 0) "Importing %s" % (self.file_name), 0)
@ -100,134 +103,182 @@ class SongBeamerImport(SongImport):
else: else:
return False return False
for line in self.songData: for line in self.songData:
line = line.strip() # Just make sure that the line is of the type 'Unicode'.
if line.startswith('#'): line = unicode(line).strip()
log.debug(u'find tag: %s' % line) if line.startswith(u'#') and not read_verses:
if not self.parse_tags(line): self.parse_tags(line)
return False elif line.startswith(u'---'):
elif line.startswith('---'): if self.current_verse:
log.debug(u'find ---') self.replace_html_tags()
if len(self.current_verse) > 0: self.add_verse(self.current_verse,
self.add_verse(self.current_verse,
self.current_verse_type) self.current_verse_type)
self.current_verse = u'' self.current_verse = u''
self.current_verse_type = u'V' self.current_verse_type = u'V'
self.read_verse = True read_verses = True
self.verse_start = True verse_start = True
elif self.read_verse: elif read_verses:
if self.verse_start: if verse_start:
self.check_verse_marks(line) verse_start = False
self.verse_start = False if not self.check_verse_marks(line):
self.current_verse = u'%s\n' % line
else: else:
self.current_verse += u'%s\n' % line self.current_verse += u'%s\n' % line
if len(self.current_verse) > 0: if self.current_verse:
self.replace_html_tags()
self.add_verse(self.current_verse, self.current_verse_type) self.add_verse(self.current_verse, self.current_verse_type)
self.finish() self.finish()
self.import_wizard.incrementProgressBar( self.import_wizard.incrementProgressBar(
"Importing %s" % (self.file_name)) "Importing %s" % (self.file_name))
return True return True
def replace_html_tags(self):
"""
This can be called to replace SongBeamer's specific (html) tags with
OpenLP's specific (html) tags.
"""
tag_pairs = [
(u'<b>', u'{st}'),
(u'</b>', u'{/st}'),
(u'<i>', u'{it}'),
(u'</i>', u'{/it}'),
(u'<u>', u'{u}'),
(u'</u>', u'{/u}'),
(u'<br>', u'{st}'),
(u'</br>', u'{st}'),
(u'</ br>', u'{st}'),
(u'<p>', u'{p}'),
(u'</p>', u'{/p}'),
(u'<super>', u'{su}'),
(u'</super>', u'{/su}'),
(u'<sub>', u'{sb}'),
(u'</sub>', u'{/sb}'),
(u'<wordwrap>', u''),
(u'</wordwrap>', u''),
(u'<strike>', u''),
(u'</strike>', u'')
]
for pair in tag_pairs:
self.current_verse = self.current_verse.replace(pair[0], pair[1])
# TODO: check for unsupported tags (see wiki) and remove them as well.
def parse_tags(self, line): def parse_tags(self, line):
tag_val = line.split('=') """
if len(tag_val[0]) == 0 or len(tag_val[1]) == 0: Parses a meta data line.
return True
if tag_val[0] == '#(c)': ``line``
The line in the file. It should consist of a tag and a value
for this tag (unicode)::
u'#Title=Nearer my God to Thee'
"""
tag_val = line.split(u'=', 1)
if len(tag_val) == 1:
return
if not tag_val[0] or not tag_val[1]:
return
if tag_val[0] == u'#(c)':
self.add_copyright(tag_val[1]) self.add_copyright(tag_val[1])
elif tag_val[0] == '#AddCopyrightInfo': elif tag_val[0] == u'#AddCopyrightInfo':
pass pass
elif tag_val[0] == '#Author': elif tag_val[0] == u'#Author':
#TODO split Authors self.parse_author(tag_val[1])
self.add_author(tag_val[1]) elif tag_val[0] == u'#BackgroundImage':
elif tag_val[0] == '#BackgroundImage':
pass pass
elif tag_val[0] == '#Bible': elif tag_val[0] == u'#Bible':
pass pass
elif tag_val[0] == '#Categories': elif tag_val[0] == u'#Categories':
self.topics = line.split(',') self.topics = line.split(',')
elif tag_val[0] == '#CCLI': elif tag_val[0] == u'#CCLI':
self.ccli_number = tag_val[1] self.ccli_number = tag_val[1]
elif tag_val[0] == '#Chords': elif tag_val[0] == u'#Chords':
pass pass
elif tag_val[0] == '#ChurchSongID': elif tag_val[0] == u'#ChurchSongID':
pass pass
elif tag_val[0] == '#ColorChords': elif tag_val[0] == u'#ColorChords':
pass pass
elif tag_val[0] == '#Comments': elif tag_val[0] == u'#Comments':
self.comments = tag_val[1] self.comments = tag_val[1]
elif tag_val[0] == '#Editor': elif tag_val[0] == u'#Editor':
pass pass
elif tag_val[0] == '#Font': elif tag_val[0] == u'#Font':
pass pass
elif tag_val[0] == '#FontLang2': elif tag_val[0] == u'#FontLang2':
pass pass
elif tag_val[0] == '#FontSize': elif tag_val[0] == u'#FontSize':
pass pass
elif tag_val[0] == '#Format': elif tag_val[0] == u'#Format':
pass pass
elif tag_val[0] == '#Format_PreLine': elif tag_val[0] == u'#Format_PreLine':
pass pass
elif tag_val[0] == '#Format_PrePage': elif tag_val[0] == u'#Format_PrePage':
pass pass
elif tag_val[0] == '#ID': elif tag_val[0] == u'#ID':
pass pass
elif tag_val[0] == '#Key': elif tag_val[0] == u'#Key':
pass pass
elif tag_val[0] == '#Keywords': elif tag_val[0] == u'#Keywords':
pass pass
elif tag_val[0] == '#LangCount': elif tag_val[0] == u'#LangCount':
pass pass
elif tag_val[0] == '#Melody': elif tag_val[0] == u'#Melody':
#TODO split Authors self.parse_author(tag_val[1])
self.add_author(tag_val[1]) elif tag_val[0] == u'#NatCopyright':
elif tag_val[0] == '#NatCopyright':
pass pass
elif tag_val[0] == '#OTitle': elif tag_val[0] == u'#OTitle':
pass pass
elif tag_val[0] == '#OutlineColor': elif tag_val[0] == u'#OutlineColor':
pass pass
elif tag_val[0] == '#OutlinedFont': elif tag_val[0] == u'#OutlinedFont':
pass pass
elif tag_val[0] == '#QuickFind': elif tag_val[0] == u'#QuickFind':
pass pass
elif tag_val[0] == '#Rights': elif tag_val[0] == u'#Rights':
song_book_pub = tag_val[1] song_book_pub = tag_val[1]
elif tag_val[0] == '#Songbook': elif tag_val[0] == u'#Songbook':
book_num = tag_val[1].split(' / ') book_num = tag_val[1].split(' / ')
self.song_book_name = book_num[0] self.song_book_name = book_num[0]
if len(book_num) == book_num[1]: if len(book_num) == book_num[1]:
self.song_number = u'' self.song_number = u''
elif tag_val[0] == '#Speed': elif tag_val[0] == u'#Speed':
pass pass
elif tag_val[0] == '#TextAlign': elif tag_val[0] == u'#TextAlign':
pass pass
elif tag_val[0] == '#Title': elif tag_val[0] == u'#Title':
self.title = u'%s' % tag_val[1] self.title = u'%s' % tag_val[1]
elif tag_val[0] == '#TitleAlign': elif tag_val[0] == u'#TitleAlign':
pass pass
elif tag_val[0] == '#TitleFontSize': elif tag_val[0] == u'#TitleFontSize':
pass pass
elif tag_val[0] == '#TitleLang2': elif tag_val[0] == u'#TitleLang2':
pass pass
elif tag_val[0] == '#TitleLang3': elif tag_val[0] == u'#TitleLang3':
pass pass
elif tag_val[0] == '#TitleLang4': elif tag_val[0] == u'#TitleLang4':
pass pass
elif tag_val[0] == '#Translation': elif tag_val[0] == u'#Translation':
pass pass
elif tag_val[0] == '#Transpose': elif tag_val[0] == u'#Transpose':
pass pass
elif tag_val[0] == '#TransposeAccidental': elif tag_val[0] == u'#TransposeAccidental':
pass pass
elif tag_val[0] == '#Version': elif tag_val[0] == u'#Version':
pass pass
else:
pass
return True
def check_verse_marks(self, line): def check_verse_marks(self, line):
marks = line.split(' ') """
Check and add the verse's MarkType. Returns ``True`` if the given line
contains a correct verse mark otherwise ``False``.
``line``
The line to check for marks (unicode).
"""
marks = line.split(u' ')
if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes: if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes:
self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]] self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]]
if len(marks) == 2: if len(marks) == 2:
#TODO: may check, because of only digits are allowed # If we have a digit, we append it to current_verse_type.
self.current_verse_type += marks[1] if marks[1].isdigit():
self.current_verse_type += marks[1]
return True
else:
return False

View File

@ -254,7 +254,8 @@ class SongImport(QtCore.QObject):
All fields have been set to this song. Write it away All fields have been set to this song. Write it away
""" """
if not self.authors: if not self.authors:
self.authors.append(u'Author unknown') self.authors.append(unicode(translate('SongsPlugin.SongImport',
'Author unknown')))
self.commit_song() self.commit_song()
def commit_song(self): def commit_song(self):

View File

@ -39,8 +39,11 @@ The basic XML is of the format::
""" """
import logging import logging
import re
from lxml import etree, objectify from lxml import etree, objectify
from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.db import Author, Song
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -77,7 +80,6 @@ class SongXMLBuilder(object):
``content`` ``content``
The actual text of the verse to be stored. The actual text of the verse to be stored.
""" """
# log.debug(u'add_verse_to_lyrics %s, %s\n%s' % (type, number, content))
verse = etree.Element(u'verse', type = unicode(type), verse = etree.Element(u'verse', type = unicode(type),
label = unicode(number)) label = unicode(number))
verse.text = etree.CDATA(content) verse.text = etree.CDATA(content)
@ -239,3 +241,153 @@ class LyricsXML(object):
song_output = u'<?xml version="1.0" encoding="UTF-8"?>' + \ song_output = u'<?xml version="1.0" encoding="UTF-8"?>' + \
u'<song version="1.0">%s</song>' % lyrics_output u'<song version="1.0">%s</song>' % lyrics_output
return song_output return song_output
class OpenLyricsParser(object):
"""
This class represents the converter for Song to/from OpenLyrics XML.
"""
def __init__(self, manager):
self.manager = manager
def song_to_xml(self, song):
"""
Convert the song to OpenLyrics Format
"""
song_xml_parser = SongXMLParser(song.lyrics)
verse_list = song_xml_parser.get_verses()
song_xml = objectify.fromstring(
u'<song version="0.7" createdIn="OpenLP 2.0"/>')
properties = etree.SubElement(song_xml, u'properties')
titles = etree.SubElement(properties, u'titles')
self._add_text_to_element(u'title', titles, song.title)
if song.alternate_title:
self._add_text_to_element(u'title', titles, song.alternate_title)
if song.theme_name:
themes = etree.SubElement(properties, u'themes')
self._add_text_to_element(u'theme', themes, song.theme_name)
self._add_text_to_element(u'copyright', properties, song.copyright)
self._add_text_to_element(u'verseOrder', properties, song.verse_order)
if song.ccli_number:
self._add_text_to_element(u'ccliNo', properties, song.ccli_number)
authors = etree.SubElement(properties, u'authors')
for author in song.authors:
self._add_text_to_element(u'author', authors, author.display_name)
lyrics = etree.SubElement(song_xml, u'lyrics')
for verse in verse_list:
verse_tag = u'%s%s' % (
verse[0][u'type'][0].lower(), verse[0][u'label'])
element = \
self._add_text_to_element(u'verse', lyrics, None, verse_tag)
element = self._add_text_to_element(u'lines', element)
for line in unicode(verse[1]).split(u'\n'):
self._add_text_to_element(u'line', element, line)
return self._extract_xml(song_xml)
def xml_to_song(self, xml):
"""
Create a Song from OpenLyrics format xml
"""
# No xml get out of here
if not xml:
return 0
song = Song()
if xml[:5] == u'<?xml':
xml = xml[38:]
song_xml = objectify.fromstring(xml)
properties = song_xml.properties
song.copyright = unicode(properties.copyright.text)
song.verse_order = unicode(properties.verseOrder.text)
if song.verse_order == u'None':
song.verse_order = u''
song.topics = []
song.book = None
theme_name = None
try:
song.ccli_number = unicode(properties.ccliNo.text)
except:
song.ccli_number = u''
try:
theme_name = unicode(properties.themes.theme)
except:
pass
if theme_name:
song.theme_name = theme_name
else:
song.theme_name = u''
# Process Titles
for title in properties.titles.title:
if not song.title:
song.title = unicode(title.text)
song.search_title = unicode(song.title)
song.alternate_title = u''
else:
song.alternate_title = unicode(title.text)
song.search_title += u'@' + song.alternate_title
song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'',
unicode(song.search_title)).lower()
# Process Lyrics
sxml = SongXMLBuilder()
search_text = u''
for lyrics in song_xml.lyrics:
for verse in song_xml.lyrics.verse:
text = u''
for line in verse.lines.line:
line = unicode(line)
if not text:
text = line
else:
text += u'\n' + line
type = VerseType.expand_string(verse.attrib[u'name'][0])
sxml.add_verse_to_lyrics(type, verse.attrib[u'name'][1], text)
search_text = search_text + text
song.search_lyrics = search_text.lower()
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
song.comments = u''
song.song_number = u''
# Process Authors
for author in properties.authors.author:
self._process_author(author.text, song)
self.manager.save_object(song)
return song.id
def _add_text_to_element(self, tag, parent, text=None, label=None):
if label:
element = etree.Element(tag, name = unicode(label))
else:
element = etree.Element(tag)
if text:
element.text = unicode(text)
parent.append(element)
return element
def _dump_xml(self, xml):
"""
Debugging aid to dump XML so that we can see what we have.
"""
return etree.tostring(xml, encoding=u'UTF-8',
xml_declaration=True, pretty_print=True)
def _extract_xml(self, xml):
"""
Extract our newly created XML song.
"""
return etree.tostring(xml, encoding=u'UTF-8',
xml_declaration=True)
def _process_author(self, name, song):
"""
Find or create an Author from display_name.
"""
name = unicode(name)
author = self.manager.get_object_filtered(Author,
Author.display_name == name)
if author:
# should only be one! so take the first
song.authors.append(author)
else:
# Need a new author
new_author = Author.populate(first_name=name.rsplit(u' ', 1)[0],
last_name=name.rsplit(u' ', 1)[1], display_name=name)
self.manager.save_object(new_author)
song.authors.append(new_author)

View File

@ -25,6 +25,7 @@
############################################################################### ###############################################################################
import logging import logging
import re
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
@ -55,6 +56,7 @@ class SongsPlugin(Plugin):
self.manager = Manager(u'songs', init_schema) self.manager = Manager(u'songs', init_schema)
self.icon_path = u':/plugins/plugin_songs.png' self.icon_path = u':/plugins/plugin_songs.png'
self.icon = build_icon(self.icon_path) self.icon = build_icon(self.icon_path)
self.whitespace = re.compile(r'\W+')
def getSettingsTab(self): def getSettingsTab(self):
visible_name = self.getString(StringContent.VisibleName) visible_name = self.getString(StringContent.VisibleName)
@ -63,6 +65,7 @@ class SongsPlugin(Plugin):
def initialise(self): def initialise(self):
log.info(u'Songs Initialising') log.info(u'Songs Initialising')
Plugin.initialise(self) Plugin.initialise(self)
self.toolsReindexItem.setVisible(True)
self.mediaItem.displayResultsSong( self.mediaItem.displayResultsSong(
self.manager.get_all_objects(Song, order_by_ref=Song.search_title)) self.manager.get_all_objects(Song, order_by_ref=Song.search_title))
@ -106,6 +109,57 @@ class SongsPlugin(Plugin):
# No menu items for now. # No menu items for now.
pass 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): def onSongImportItemClicked(self):
if self.mediaItem: if self.mediaItem:
self.mediaItem.onImportClick() self.mediaItem.onImportClick()
@ -206,4 +260,6 @@ class SongsPlugin(Plugin):
""" """
log.info(u'Songs Finalising') log.info(u'Songs Finalising')
self.manager.finalise() self.manager.finalise()
self.toolsReindexItem.setVisible(False)
Plugin.finalise(self) Plugin.finalise(self)

File diff suppressed because it is too large Load Diff

View File

@ -81,6 +81,7 @@
<qresource prefix="wizards"> <qresource prefix="wizards">
<file>wizard_importsong.bmp</file> <file>wizard_importsong.bmp</file>
<file>wizard_importbible.bmp</file> <file>wizard_importbible.bmp</file>
<file>wizard_createtheme.bmp</file>
</qresource> </qresource>
<qresource prefix="services"> <qresource prefix="services">
<file>service_collapse_all.png</file> <file>service_collapse_all.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB