This commit is contained in:
Andreas Preikschat 2011-02-17 15:35:55 +01:00
commit 0bcc877a41
147 changed files with 5063 additions and 3972 deletions

View File

@ -4,8 +4,8 @@
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman # # Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # # Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # # Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # # Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund # # Carsten Tinggaard, Frode Woldsund #

View File

@ -1,124 +0,0 @@
openlp.org 2.x Song Database Structure
========================================================================
Introduction
------------
The song database in openlp.org 2.x is similar to the 1.x format. The
biggest differences are the addition of extra tables, and the use of
SQLite version 3.
The song database contains the following tables:
- authors
- authors_songs
- song_books
- songs
- songs_topics
- topics
"authors" Table
---------------
This table holds the names of all the authors. It has the following
columns:
* id
* first_name
* last_name
* display_name
"authors_songs" Table
---------------------
This is a bridging table between the "authors" and "songs" tables, which
serves to create a many-to-many relationship between the two tables. It
has the following columns:
* author_id
* song_id
"song_books" Table
------------------
The "song_books" table holds a list of books that a congregation gets
their songs from, or old hymnals now no longer used. This table has the
following columns:
* id
* name
* publisher
"songs" Table
-------------
This table contains the songs, and each song has a list of attributes.
The "songs" table has the following columns:
* id
* song_book_id
* title
* lyrics
* verse_order
* copyright
* comments
* ccli_number
* song_number
* theme_name
* search_title
* search_lyrics
"songs_topics" Table
--------------------
This is a bridging table between the "songs" and "topics" tables, which
serves to create a many-to-many relationship between the two tables. It
has the following columns:
* song_id
* topic_id
"topics" Table
--------------
The topics table holds a selection of topics that songs can cover. This
is useful when a worship leader wants to select songs with a certain
theme. This table has the following columns:
* id
* name
The lyrics definition (more or less similar to interformat to/from ChangingSong
The tags <i></i><b></b><u></u> can also be used within the lyrics test.
! Please note that this format has been checked at http://validator.w3.org/#validate_by_upload
<lyrics lang="en_US">
<title>Amazing Grace</title>
<verse name="v1">
<theme>name of verse specific theme (optional)</theme>
<comment>any text (optional)</comment>
<part name="men">
Amazing grace, how ...
</part>
<part name="women">
A b c
D e f
</part>
...
</verse>
<verse name="c">
<theme>name of verse specific theme (optional)</theme>
<comment>any text (optional)</comment>
...
</verse>
</lyrics>
<lyrics lang="de_DE">
<title>Erstaunliche Anmut</title>
<verse name="v1">
Erstaunliche Anmut, wie
...
</verse>
<verse name="c">
...
</verse>
</lyrics>

View File

@ -6,18 +6,18 @@ Object Library
.. automodule:: openlp.core.lib .. automodule:: openlp.core.lib
:members: :members:
:mod:`BaseListWithDnD`
----------------------
.. autoclass:: openlp.core.lib.baselistwithdnd.BaseListWithDnD
:members:
:mod:`EventReceiver` :mod:`EventReceiver`
-------------------- --------------------
.. autoclass:: openlp.core.lib.eventreceiver.EventReceiver .. autoclass:: openlp.core.lib.eventreceiver.EventReceiver
:members: :members:
:mod:`ListWidgetWithDnD`
----------------------
.. autoclass:: openlp.core.lib.listwidgetwithdnd.ListWidgetWithDnD
:members:
:mod:`MediaManagerItem` :mod:`MediaManagerItem`
----------------------- -----------------------

View File

@ -1,8 +1,10 @@
.. _core-theme: .. _core-theme:
:mod:`theme` Module Theme Function Library
=================== ======================
.. automodule:: openlp.core.theme .. automodule:: openlp.core.theme
:members: :members:
.. autoclass:: openlp.core.theme.theme.Theme
:members:

View File

@ -1,7 +0,0 @@
.. _openlp:
:mod:`openlp` Module
====================
.. automodule:: openlp
:members:

View File

@ -18,7 +18,7 @@ Forms
.. automodule:: openlp.plugins.bibles.forms .. automodule:: openlp.plugins.bibles.forms
:members: :members:
.. autoclass:: openlp.plugins.bibles.forms.importwizardform.ImportWizardForm .. autoclass:: openlp.plugins.bibles.forms.bibleimportform.BibleImportForm
:members: :members:
Helper Classes & Functions Helper Classes & Functions

View File

@ -48,7 +48,7 @@ copyright = u'2004-2010 Raoul Snyman'
# The short X.Y version. # The short X.Y version.
version = '2.0' version = '2.0'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '1.9.3' release = '1.9.5'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.
@ -92,22 +92,24 @@ pygments_style = 'sphinx'
# The theme to use for HTML and HTML Help pages. Major themes that come with # The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'. # Sphinx are currently 'default' and 'sphinxdoc'.
#html_theme = 'openlp_qthelp'
html_theme = 'default' html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme # Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the # further. For a list of options available for each theme, see the
# documentation. # documentation.
html_theme_options = { if html_theme == 'default':
'sidebarbgcolor': '#3a60a9', html_theme_options = {
'relbarbgcolor': '#203b6f', 'sidebarbgcolor': '#3a60a9',
'footerbgcolor': '#26437c', 'relbarbgcolor': '#203b6f',
'headtextcolor': '#203b6f', 'footerbgcolor': '#26437c',
'linkcolor': '#26437c', 'headtextcolor': '#203b6f',
'sidebarlinkcolor': '#ceceff' 'linkcolor': '#26437c',
} 'sidebarlinkcolor': '#ceceff'
}
# Add any paths that contain custom themes here, relative to this directory. # Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = [] html_theme_path = [u'../themes']
# The name for this set of Sphinx documents. If None, it defaults to # The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation". # "<project> v<release> documentation".

View File

@ -149,15 +149,15 @@ Or, as root::
root@linux: # nividia-settings root@linux: # nividia-settings
If you do not want to write the changes to your ``xorg.conf`` file simply run If you do not want to write the changes to your ``xorg.conf`` file simply run
the nVidia Settings program (``nvidia-settings``) from your desktop's menu, the nVidia Settings program (:command:`nvidia-settings`) from your desktop's
usually in an administration or system menu, or from the terminal as a normal menu, usually in an administration or system menu, or from the terminal as a
user run:: normal user run::
user@linux:~ $ nvidia-settings user@linux:~ $ nvidia-settings
Once you have opened nVidia Settings, click on Once you have opened nVidia Settings, click on :guilabel:`X Server Display
:guilabel:`X Server Display Configuration`. Then select the monitor you are Configuration`. Then select the monitor you are wanting to use as your second
wanting to use as your second monitor and click :guilabel:`Configure`. monitor and click :guilabel:`Configure`.
.. image:: pics/nvlinux1.png .. image:: pics/nvlinux1.png

View File

@ -17,10 +17,3 @@ Contents:
mediamanager mediamanager
songs songs
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -0,0 +1,68 @@
{#
openlp_qthelp/layout.html
~~~~~~~~~~~~~~~~~
Sphinx layout template for the openlp_qthelp theme.
:copyright: Copyright 2004-2010 Raoul Snyman.
:license: GPL
#}
{% extends "basic/layout.html" %}
{% set script_files = script_files + ['_static/theme_extras.js'] %}
{% set css_files = css_files + ['_static/print.css'] %}
{# do not display relbars #}
{% block relbar1 %}{% endblock %}
{% block relbar2 %}{% endblock %}
{% macro nav() %}
<p>
{%- block openlp_qthelprel1 %}
{%- endblock %}
{%- if prev %}
«&#160;&#160;<a href="{{ prev.link|e }}">{{ prev.title }}</a>
&#160;&#160;::&#160;&#160;
{%- endif %}
<a class="uplink" href="{{ pathto(master_doc) }}">{{ _('Contents') }}</a>
{%- if next %}
&#160;&#160;::&#160;&#160;
<a href="{{ next.link|e }}">{{ next.title }}</a>&#160;&#160;»
{%- endif %}
{%- block openlp_qthelprel2 %}
{%- endblock %}
</p>
{% endmacro %}
{% block content %}
<!-- div class="header">
{%- block openlp_qthelpheader %}
{%- if theme_full_logo != "false" %}
<a href="{{ pathto('index') }}">
<img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
</a>
{%- else %}
{%- if logo -%}
<img class="rightlogo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
{%- endif -%}
<h1 class="heading"><a href="{{ pathto('index') }}">
<span>{{ shorttitle|e }}</span></a></h1>
<h2 class="heading"><span>{{ title|striptags|e }}</span></h2>
{%- endif %}
{%- endblock %}
</div -->
<div class="topnav">
{{ nav() }}
</div>
<div class="content">
{#{%- if display_toc %}
<div id="toc">
<h3>Table Of Contents</h3>
{{ toc }}
</div>
{%- endif %}#}
{% block body %}{% endblock %}
</div>
<div class="bottomnav">
{{ nav() }}
</div>
{% endblock %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

View File

@ -0,0 +1,372 @@
/*
* openlp_qthelp.css_t
* ~~~~~~~~~~~
*
* Sphinx stylesheet -- openlp_qthelp theme.
*
* Adapted from http://openlp_qthelp-os.org/docs/Haiku-doc.css.
* Original copyright message:
*
* Copyright 2008-2009, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Francois Revol <revol@free.fr>
* Stephan Assmus <superstippi@gmx.de>
* Braden Ewing <brewin@gmail.com>
* Humdinger <humdingerb@gmail.com>
*
* :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@import url("basic.css");
html {
margin: 0px;
padding: 0px;
background-color: #fff;
background-image: none;
}
body {
line-height: 1.5;
margin: auto;
padding: 0px;
font-family: "DejaVu Sans", Arial, Helvetica, sans-serif;
min-width: 59em;
max-width: 70em;
color: {{ theme_textcolor }};
}
div.footer {
padding: 8px;
font-size: 11px;
text-align: center;
letter-spacing: 0.5px;
}
/* link colors and text decoration */
a:link {
font-weight: bold;
text-decoration: none;
color: {{ theme_linkcolor }};
}
a:visited {
font-weight: bold;
text-decoration: none;
color: {{ theme_visitedlinkcolor }};
}
a:hover, a:active {
text-decoration: underline;
color: {{ theme_hoverlinkcolor }};
}
/* Some headers act as anchors, don't give them a hover effect */
h1 a:hover, a:active {
text-decoration: none;
color: {{ theme_headingcolor }};
}
h2 a:hover, a:active {
text-decoration: none;
color: {{ theme_headingcolor }};
}
h3 a:hover, a:active {
text-decoration: none;
color: {{ theme_headingcolor }};
}
h4 a:hover, a:active {
text-decoration: none;
color: {{ theme_headingcolor }};
}
a.headerlink {
color: #a7ce38;
padding-left: 5px;
}
a.headerlink:hover {
color: #a7ce38;
}
/* basic text elements */
div.content {
margin-top: 20px;
margin-left: 40px;
margin-right: 40px;
margin-bottom: 50px;
font-size: 0.9em;
}
/* heading and navigation */
div.header {
position: relative;
left: 0px;
top: 0px;
height: 85px;
/* background: #eeeeee; */
padding: 0 40px;
}
div.header h1 {
font-size: 1.6em;
font-weight: normal;
letter-spacing: 1px;
color: {{ theme_headingcolor }};
border: 0;
margin: 0;
padding-top: 15px;
}
div.header h1 a {
font-weight: normal;
color: {{ theme_headingcolor }};
}
div.header h2 {
font-size: 1.3em;
font-weight: normal;
letter-spacing: 1px;
text-transform: uppercase;
color: #aaa;
border: 0;
margin-top: -3px;
padding: 0;
}
div.header img.rightlogo {
float: right;
}
div.title {
font-size: 1.3em;
font-weight: bold;
color: {{ theme_headingcolor }};
border-bottom: dotted thin #e0e0e0;
margin-bottom: 25px;
}
div.topnav {
/* background: #e0e0e0; */
}
div.topnav p {
margin-top: 0;
margin-left: 40px;
margin-right: 40px;
margin-bottom: 0px;
text-align: right;
font-size: 0.8em;
}
div.bottomnav {
background: #eeeeee;
}
div.bottomnav p {
margin-right: 40px;
text-align: right;
font-size: 0.8em;
}
a.uplink {
font-weight: normal;
}
/* contents box */
table.index {
margin: 0px 0px 30px 30px;
padding: 1px;
border-width: 1px;
border-style: dotted;
border-color: #e0e0e0;
}
table.index tr.heading {
background-color: #e0e0e0;
text-align: center;
font-weight: bold;
font-size: 1.1em;
}
table.index tr.index {
background-color: #eeeeee;
}
table.index td {
padding: 5px 20px;
}
table.index a:link, table.index a:visited {
font-weight: normal;
text-decoration: none;
color: {{ theme_linkcolor }};
}
table.index a:hover, table.index a:active {
text-decoration: underline;
color: {{ theme_hoverlinkcolor }};
}
/* Haiku User Guide styles and layout */
/* Rounded corner boxes */
/* Common declarations */
div.admonition {
-webkit-border-radius: 10px;
-khtml-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
border-style: dotted;
border-width: thin;
border-color: #dcdcdc;
padding: 10px 15px 10px 15px;
margin-bottom: 15px;
margin-top: 15px;
}
div.note {
padding: 10px 15px 10px 80px;
background: #e4ffde url(alert_info_32.png) 15px 15px no-repeat;
min-height: 42px;
}
div.warning {
padding: 10px 15px 10px 80px;
background: #fffbc6 url(alert_warning_32.png) 15px 15px no-repeat;
min-height: 42px;
}
div.seealso {
background: #e4ffde;
}
/* More layout and styles */
h1 {
font-size: 1.3em;
font-weight: bold;
color: {{ theme_headingcolor }};
border-bottom: dotted thin #e0e0e0;
margin-top: 30px;
}
h2 {
font-size: 1.2em;
font-weight: normal;
color: {{ theme_headingcolor }};
border-bottom: dotted thin #e0e0e0;
margin-top: 30px;
}
h3 {
font-size: 1.1em;
font-weight: normal;
color: {{ theme_headingcolor }};
margin-top: 30px;
}
h4 {
font-size: 1.0em;
font-weight: normal;
color: {{ theme_headingcolor }};
margin-top: 30px;
}
p {
text-align: justify;
}
p.last {
margin-bottom: 0;
}
ol {
padding-left: 20px;
}
ul {
padding-left: 5px;
margin-top: 3px;
}
li {
line-height: 1.3;
}
div.content ul > li {
-moz-background-clip:border;
-moz-background-inline-policy:continuous;
-moz-background-origin:padding;
background: transparent url(bullet_orange.png) no-repeat scroll left 0.45em;
list-style-image: none;
list-style-type: none;
padding: 0 0 0 1.666em;
margin-bottom: 3px;
}
td {
vertical-align: top;
}
tt {
background-color: #e2e2e2;
font-size: 1.0em;
font-family: monospace;
}
pre {
border-color: #0c3762;
border-style: dotted;
border-width: thin;
margin: 0 0 12px 0;
padding: 0.8em;
background-color: #f0f0f0;
}
hr {
border-top: 1px solid #ccc;
border-bottom: 0;
border-right: 0;
border-left: 0;
margin-bottom: 10px;
margin-top: 20px;
}
/* printer only pretty stuff */
@media print {
.noprint {
display: none;
}
/* for acronyms we want their definitions inlined at print time */
acronym[title]:after {
font-size: small;
content: " (" attr(title) ")";
font-style: italic;
}
/* and not have mozilla dotted underline */
acronym {
border: none;
}
div.topnav, div.bottomnav, div.header, table.index {
display: none;
}
div.content {
margin: 0px;
padding: 0px;
}
html {
background: #FFF;
}
}
.viewcode-back {
font-family: "DejaVu Sans", Arial, Helvetica, sans-serif;
}
div.viewcode-block:target {
background-color: #f4debf;
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
margin: -1px -12px;
padding: 0 12px;
}

View File

@ -0,0 +1,12 @@
[theme]
inherit = basic
stylesheet = openlp_qthelp.css
pygments_style = autumn
[options]
full_logo = false
textcolor = #333333
headingcolor = #203b6f
linkcolor = #26437c
visitedlinkcolor = #26437c
hoverlinkcolor = #26437c

View File

@ -76,7 +76,7 @@ class OpenLP(QtGui.QApplication):
""" """
Load and store current Application Version Load and store current Application Version
""" """
if u'--dev-version' in sys.argv: if u'--dev-version' in sys.argv or u'-d' in sys.argv:
# If we're running the dev version, let's use bzr to get the version # If we're running the dev version, let's use bzr to get the version
try: try:
# If bzrlib is availble, use it # If bzrlib is availble, use it
@ -194,7 +194,10 @@ class OpenLP(QtGui.QApplication):
# now kill the splashscreen # now kill the splashscreen
self.splash.finish(self.mainWindow) self.splash.finish(self.mainWindow)
self.mainWindow.repaint() self.mainWindow.repaint()
VersionThread(self.mainWindow, app_version).start() update_check = QtCore.QSettings().value(
u'general/update check', QtCore.QVariant(True)).toBool()
if update_check:
VersionThread(self.mainWindow, app_version).start()
return self.exec_() return self.exec_()
def hookException(self, exctype, value, traceback): def hookException(self, exctype, value, traceback):
@ -213,6 +216,7 @@ class OpenLP(QtGui.QApplication):
Sets the Busy Cursor for the Application Sets the Busy Cursor for the Application
""" """
self.setOverrideCursor(QtCore.Qt.BusyCursor) self.setOverrideCursor(QtCore.Qt.BusyCursor)
self.processEvents()
def setNormalCursor(self): def setNormalCursor(self):
""" """
@ -280,4 +284,4 @@ if __name__ == u'__main__':
""" """
Instantiate and run the application. Instantiate and run the application.
""" """
main() main()

View File

@ -315,10 +315,11 @@ def check_directory_exists(dir):
``dir`` ``dir``
Theme directory to make sure exists Theme directory to make sure exists
""" """
log.debug(u'check_directory_exists') log.debug(u'check_directory_exists %s' % dir)
if not os.path.exists(dir): if not os.path.exists(dir):
os.makedirs(dir) os.makedirs(dir)
from listwidgetwithdnd import ListWidgetWithDnD
from theme import ThemeLevel, ThemeXML, BackgroundGradientType, \ from theme import ThemeLevel, ThemeXML, BackgroundGradientType, \
BackgroundType, HorizontalType, VerticalType BackgroundType, HorizontalType, VerticalType
from displaytags import DisplayTags from displaytags import DisplayTags
@ -339,4 +340,3 @@ from dockwidget import OpenLPDockWidget
from renderer import Renderer from renderer import Renderer
from rendermanager import RenderManager from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem from mediamanageritem import MediaManagerItem
from baselistwithdnd import BaseListWithDnD

View File

@ -86,10 +86,10 @@ class BaseModel(object):
""" """
Creates an instance of a class and populates it, returning the instance Creates an instance of a class and populates it, returning the instance
""" """
me = cls() instance = cls()
for key in kwargs: for key in kwargs:
me.__setattr__(key, kwargs[key]) instance.__setattr__(key, kwargs[key])
return me return instance
class Manager(object): class Manager(object):
""" """

View File

@ -60,8 +60,8 @@ class DisplayTags(object):
DisplayTags.html_expands.append(tag) DisplayTags.html_expands.append(tag)
@staticmethod @staticmethod
def remove_html_tag(id): def remove_html_tag(tag_id):
""" """
Removes amd individual html_expands list. Removes an individual html_expands tag.
""" """
DisplayTags.html_expands.pop(id) DisplayTags.html_expands.pop(tag_id)

View File

@ -31,6 +31,8 @@ import logging
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.lib import build_icon
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class OpenLPDockWidget(QtGui.QDockWidget): class OpenLPDockWidget(QtGui.QDockWidget):
@ -47,4 +49,4 @@ class OpenLPDockWidget(QtGui.QDockWidget):
if name: if name:
self.setObjectName(name) self.setObjectName(name)
if icon: if icon:
self.setWindowIcon(icon) self.setWindowIcon(build_icon(icon))

View File

@ -28,7 +28,8 @@ import logging
from PyQt4 import QtWebKit from PyQt4 import QtWebKit
from openlp.core.lib import BackgroundType, BackgroundGradientType from openlp.core.lib import BackgroundType, BackgroundGradientType, \
VerticalType
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -314,7 +315,7 @@ body {
</html> </html>
""" """
def build_html(item, screen, alert, islive): def build_html(item, screen, alert, islive, background):
""" """
Build the full web paged structure for display Build the full web paged structure for display
@ -332,7 +333,9 @@ def build_html(item, screen, alert, islive):
theme = item.themedata theme = item.themedata
webkitvers = webkit_version() webkitvers = webkit_version()
# Image generated and poked in # Image generated and poked in
if item.bg_image_bytes: if background:
image = u'src="data:image/png;base64,%s"' % background
elif item.bg_image_bytes:
image = u'src="data:image/png;base64,%s"' % item.bg_image_bytes image = u'src="data:image/png;base64,%s"' % item.bg_image_bytes
else: else:
image = u'style="display:none;"' image = u'style="display:none;"'
@ -534,12 +537,7 @@ def build_lyrics_format_css(theme, width, height):
align = u'right' align = u'right'
else: else:
align = u'left' align = u'left'
if theme.display_vertical_align == 2: valign = VerticalType.to_string(theme.display_vertical_align)
valign = u'bottom'
elif theme.display_vertical_align == 1:
valign = u'middle'
else:
valign = u'top'
if theme.font_main_outline: if theme.font_main_outline:
left_margin = int(theme.font_main_outline_size) * 2 left_margin = int(theme.font_main_outline_size) * 2
else: else:
@ -632,13 +630,7 @@ def build_alert_css(alertTab, width):
""" """
if not alertTab: if not alertTab:
return u'' return u''
align = u'' align = VerticalType.to_string(alertTab.location)
if alertTab.location == 2:
align = u'bottom'
elif alertTab.location == 1:
align = u'middle'
else:
align = u'top'
alert = style % (width, align, alertTab.font_face, alertTab.font_size, alert = style % (width, align, alertTab.font_face, alertTab.font_size,
alertTab.font_color, alertTab.bg_color) alertTab.font_color, alertTab.bg_color)
return alert return alert

View File

@ -61,10 +61,10 @@ class Image(object):
image = None image = None
image_bytes = None image_bytes = None
class ImageManager(QtCore.QObject): class ImageManager(QtCore.QObject):
""" """
Image Manager handles the conversion and sizing of images. Image Manager handles the conversion and sizing of images.
""" """
log.info(u'Image Manager loaded') log.info(u'Image Manager loaded')

View File

@ -28,17 +28,17 @@ Extend QListWidget to handle drag and drop functionality
""" """
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
class BaseListWithDnD(QtGui.QListWidget): class ListWidgetWithDnD(QtGui.QListWidget):
""" """
Provide a list widget to store objects and handle drag and drop events Provide a list widget to store objects and handle drag and drop events
""" """
def __init__(self, parent=None): def __init__(self, parent=None, name=u''):
""" """
Initialise the list widget Initialise the list widget
""" """
QtGui.QListWidget.__init__(self, parent) QtGui.QListWidget.__init__(self, parent)
# this must be set by the class which is inheriting self.mimeDataText = name
assert(self.PluginName) assert(self.mimeDataText)
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
""" """
@ -47,9 +47,10 @@ class BaseListWithDnD(QtGui.QListWidget):
just tell it what plugin to call just tell it what plugin to call
""" """
if event.buttons() != QtCore.Qt.LeftButton: if event.buttons() != QtCore.Qt.LeftButton:
event.ignore()
return return
drag = QtGui.QDrag(self) drag = QtGui.QDrag(self)
mimeData = QtCore.QMimeData() mimeData = QtCore.QMimeData()
drag.setMimeData(mimeData) drag.setMimeData(mimeData)
mimeData.setText(self.PluginName) mimeData.setText(self.mimeDataText)
drag.start(QtCore.Qt.CopyAction) drag.start(QtCore.Qt.CopyAction)

View File

@ -33,7 +33,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import context_menu_action, context_menu_separator, \ from openlp.core.lib import context_menu_action, context_menu_separator, \
SettingsManager, OpenLPToolbar, ServiceItem, StringContent, build_icon, \ SettingsManager, OpenLPToolbar, ServiceItem, StringContent, build_icon, \
translate, Receiver translate, Receiver, ListWidgetWithDnD
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -73,11 +73,6 @@ class MediaManagerItem(QtGui.QWidget):
assumes that the new action is to load a file. If not, you assumes that the new action is to load a file. If not, you
need to override the ``OnNew`` method. need to override the ``OnNew`` method.
``self.ListViewWithDnD_class``
This must be a **class**, not an object, descended from
``openlp.core.lib.BaseListWithDnD`` that is not used in any
other part of OpenLP.
``self.PreviewFunction`` ``self.PreviewFunction``
This must be a method which returns a QImage to represent the This must be a method which returns a QImage to represent the
item (usually a preview). No scaling is required, that is item (usually a preview). No scaling is required, that is
@ -98,16 +93,11 @@ class MediaManagerItem(QtGui.QWidget):
visible_title = self.plugin.getString(StringContent.VisibleName) visible_title = self.plugin.getString(StringContent.VisibleName)
self.title = unicode(visible_title[u'title']) self.title = unicode(visible_title[u'title'])
self.settingsSection = self.plugin.name.lower() self.settingsSection = self.plugin.name.lower()
if isinstance(icon, QtGui.QIcon): self.icon = None
self.icon = icon if icon:
elif isinstance(icon, basestring): self.icon = build_icon(icon)
self.icon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(icon)),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
else:
self.icon = None
self.toolbar = None self.toolbar = None
self.remoteTriggered = None self.remoteTriggered = None
self.serviceItemIconName = None
self.singleServiceItem = True self.singleServiceItem = True
self.pageLayout = QtGui.QVBoxLayout(self) self.pageLayout = QtGui.QVBoxLayout(self)
self.pageLayout.setSpacing(0) self.pageLayout.setSpacing(0)
@ -163,7 +153,7 @@ class MediaManagerItem(QtGui.QWidget):
``icon`` ``icon``
The icon of the button. This can be an instance of QIcon, or a The icon of the button. This can be an instance of QIcon, or a
string cotaining either the absolute path to the image, or an string containing either the absolute path to the image, or an
internal resource path starting with ':/'. internal resource path starting with ':/'.
``slot`` ``slot``
@ -207,68 +197,50 @@ class MediaManagerItem(QtGui.QWidget):
""" """
Create buttons for the media item toolbar Create buttons for the media item toolbar
""" """
toolbar_actions = []
## Import Button ## ## Import Button ##
if self.hasImportIcon: if self.hasImportIcon:
import_string = self.plugin.getString(StringContent.Import) toolbar_actions.append([StringContent.Import,
self.addToolbarButton( u':/general/general_import.png', self.onImportClick])
import_string[u'title'],
import_string[u'tooltip'],
u':/general/general_import.png', self.onImportClick)
## Load Button ## ## Load Button ##
if self.hasFileIcon: if self.hasFileIcon:
load_string = self.plugin.getString(StringContent.Load) toolbar_actions.append([StringContent.Load,
self.addToolbarButton( u':/general/general_open.png', self.onFileClick])
load_string[u'title'],
load_string[u'tooltip'],
u':/general/general_open.png', self.onFileClick)
## New Button ## ## New Button ##
if self.hasNewIcon: if self.hasNewIcon:
new_string = self.plugin.getString(StringContent.New) toolbar_actions.append([StringContent.New,
self.addToolbarButton( u':/general/general_new.png', self.onNewClick])
new_string[u'title'],
new_string[u'tooltip'],
u':/general/general_new.png', self.onNewClick)
## Edit Button ## ## Edit Button ##
if self.hasEditIcon: if self.hasEditIcon:
edit_string = self.plugin.getString(StringContent.Edit) toolbar_actions.append([StringContent.Edit,
self.addToolbarButton( u':/general/general_edit.png', self.onEditClick])
edit_string[u'title'],
edit_string[u'tooltip'],
u':/general/general_edit.png', self.onEditClick)
## Delete Button ## ## Delete Button ##
if self.hasDeleteIcon: if self.hasDeleteIcon:
delete_string = self.plugin.getString(StringContent.Delete) toolbar_actions.append([StringContent.Delete,
self.addToolbarButton( u':/general/general_delete.png', self.onDeleteClick])
delete_string[u'title'],
delete_string[u'tooltip'],
u':/general/general_delete.png', self.onDeleteClick)
## Separator Line ## ## Separator Line ##
self.addToolbarSeparator() self.addToolbarSeparator()
## Preview ## ## Preview ##
preview_string = self.plugin.getString(StringContent.Preview) toolbar_actions.append([StringContent.Preview,
self.addToolbarButton( u':/general/general_preview.png', self.onPreviewClick])
preview_string[u'title'], ## Live Button ##
preview_string[u'tooltip'], toolbar_actions.append([StringContent.Live,
u':/general/general_preview.png', self.onPreviewClick) u':/general/general_live.png', self.onLiveClick])
## Live Button ##
live_string = self.plugin.getString(StringContent.Live)
self.addToolbarButton(
live_string[u'title'],
live_string[u'tooltip'],
u':/general/general_live.png', self.onLiveClick)
## Add to service Button ## ## Add to service Button ##
service_string = self.plugin.getString(StringContent.Service) toolbar_actions.append([StringContent.Service,
self.addToolbarButton( u':/general/general_add.png', self.onAddClick])
service_string[u'title'], for action in toolbar_actions:
service_string[u'tooltip'], self.addToolbarButton(
u':/general/general_add.png', self.onAddClick) self.plugin.getString(action[0])[u'title'],
self.plugin.getString(action[0])[u'tooltip'],
action[1], action[2])
def addListViewToToolBar(self): def addListViewToToolBar(self):
""" """
Creates the main widget for listing items the media item is tracking Creates the main widget for listing items the media item is tracking
""" """
# Add the List widget # Add the List widget
self.listView = self.ListViewWithDnD_class(self) self.listView = ListWidgetWithDnD(self, self.title)
self.listView.uniformItemSizes = True self.listView.uniformItemSizes = True
self.listView.setSpacing(1) self.listView.setSpacing(1)
self.listView.setSelectionMode( self.listView.setSelectionMode(
@ -280,7 +252,6 @@ class MediaManagerItem(QtGui.QWidget):
self.pageLayout.addWidget(self.listView) self.pageLayout.addWidget(self.listView)
# define and add the context menu # define and add the context menu
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
name_string = self.plugin.getString(StringContent.Name)
if self.hasEditIcon: if self.hasEditIcon:
self.listView.addAction( self.listView.addAction(
context_menu_action( context_menu_action(
@ -371,33 +342,34 @@ class MediaManagerItem(QtGui.QWidget):
count += 1 count += 1
return filelist return filelist
def validate(self, file, thumb): def validate(self, image, thumb):
""" """
Validates to see if the file still exists or thumbnail is up to date Validates whether an image still exists and, if it does, is the
thumbnail representation of the image up to date.
""" """
if not os.path.exists(file): if not os.path.exists(image):
return False return False
if os.path.exists(thumb): if os.path.exists(thumb):
filedate = os.stat(file).st_mtime imageDate = os.stat(image).st_mtime
thumbdate = os.stat(thumb).st_mtime thumbDate = os.stat(thumb).st_mtime
# if file updated rebuild icon # If image has been updated rebuild icon
if filedate > thumbdate: if imageDate > thumbDate:
self.iconFromFile(file, thumb) self.iconFromFile(image, thumb)
else: else:
self.iconFromFile(file, thumb) self.iconFromFile(image, thumb)
return True return True
def iconFromFile(self, file, thumb): def iconFromFile(self, image, thumb):
""" """
Create a thumbnail icon from a given file Create a thumbnail icon from a given image.
``file`` ``image``
The file to create the icon from The image file to create the icon from.
``thumb`` ``thumb``
The filename to save the thumbnail to The filename to save the thumbnail to
""" """
icon = build_icon(unicode(file)) icon = build_icon(unicode(image))
pixmap = icon.pixmap(QtCore.QSize(88, 50)) pixmap = icon.pixmap(QtCore.QSize(88, 50))
ext = os.path.splitext(thumb)[1].lower() ext = os.path.splitext(thumb)[1].lower()
pixmap.save(thumb, ext[1:]) pixmap.save(thumb, ext[1:])
@ -408,12 +380,16 @@ class MediaManagerItem(QtGui.QWidget):
u'defined by the plugin') u'defined by the plugin')
def onNewClick(self): def onNewClick(self):
raise NotImplementedError(u'MediaManagerItem.onNewClick needs to be ' """
u'defined by the plugin') Hook for plugins to define behaviour for adding new items.
"""
pass
def onEditClick(self): def onEditClick(self):
raise NotImplementedError(u'MediaManagerItem.onEditClick needs to be ' """
u'defined by the plugin') Hook for plugins to define behaviour for editing items.
"""
pass
def onDeleteClick(self): def onDeleteClick(self):
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to ' raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to '
@ -500,7 +476,7 @@ class MediaManagerItem(QtGui.QWidget):
""" """
if not self.listView.selectedIndexes() and not self.remoteTriggered: if not self.listView.selectedIndexes() and not self.remoteTriggered:
QtGui.QMessageBox.information(self, QtGui.QMessageBox.information(self,
translate('OpenLP.MediaManagerItem', 'No items selected'), translate('OpenLP.MediaManagerItem', 'No Items Selected'),
translate('OpenLP.MediaManagerItem', translate('OpenLP.MediaManagerItem',
'You must select one or more items')) 'You must select one or more items'))
else: else:
@ -512,7 +488,7 @@ class MediaManagerItem(QtGui.QWidget):
'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() == serviceItem.name.lower(): elif self.plugin.name.lower() == serviceItem.name.lower():
self.generateSlideData(serviceItem) self.generateSlideData(serviceItem)
self.parent.serviceManager.addServiceItem(serviceItem, self.parent.serviceManager.addServiceItem(serviceItem,
replace=True) replace=True)
@ -529,10 +505,7 @@ class MediaManagerItem(QtGui.QWidget):
Common method for generating a service item Common method for generating a service item
""" """
serviceItem = ServiceItem(self.parent) serviceItem = ServiceItem(self.parent)
if self.serviceItemIconName: serviceItem.add_icon(self.parent.icon_path)
serviceItem.add_icon(self.serviceItemIconName)
else:
serviceItem.add_icon(self.parent.icon_path)
if self.generateSlideData(serviceItem, item, xmlVersion): if self.generateSlideData(serviceItem, item, xmlVersion):
return serviceItem return serviceItem
else: else:
@ -544,3 +517,25 @@ class MediaManagerItem(QtGui.QWidget):
individual service items need to be processed by the plugins individual service items need to be processed by the plugins
""" """
pass pass
def _getIdOfItemToGenerate(self, item, remoteItem):
"""
Utility method to check items being submitted for slide generation.
``item``
The item to check.
``remoteItem``
The id to assign if the slide generation was remotely triggered.
"""
if item is None:
if self.remoteTriggered is None:
item = self.listView.currentItem()
if item is None:
return False
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
else:
item_id = remoteItem
else:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
return item_id

View File

@ -31,6 +31,7 @@ import logging
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Receiver from openlp.core.lib import Receiver
from openlp.core.lib.ui import UiStrings
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -42,7 +43,11 @@ class PluginStatus(object):
Inactive = 0 Inactive = 0
Disabled = -1 Disabled = -1
class StringContent(object): class StringContent(object):
"""
Provide standard strings for objects to use.
"""
Name = u'name' Name = u'name'
Import = u'import' Import = u'import'
Load = u'load' Load = u'load'
@ -54,6 +59,7 @@ class StringContent(object):
Service = u'service' Service = u'service'
VisibleName = u'visible_name' VisibleName = u'visible_name'
class Plugin(QtCore.QObject): class Plugin(QtCore.QObject):
""" """
Base class for openlp plugins to inherit from. Base class for openlp plugins to inherit from.
@ -108,7 +114,8 @@ class Plugin(QtCore.QObject):
""" """
log.info(u'loaded') log.info(u'loaded')
def __init__(self, name, version=None, pluginHelpers=None): def __init__(self, name, version=None, pluginHelpers=None,
mediaItemClass=None, settingsTabClass=None):
""" """
This is the constructor for the plugin object. This provides an easy This is the constructor for the plugin object. This provides an easy
way for descendent plugins to populate common data. This method *must* way for descendent plugins to populate common data. This method *must*
@ -116,7 +123,7 @@ class Plugin(QtCore.QObject):
class MyPlugin(Plugin): class MyPlugin(Plugin):
def __init__(self): def __init__(self):
Plugin.__init(self, u'MyPlugin', u'0.1') Plugin.__init__(self, u'MyPlugin', u'0.1')
``name`` ``name``
Defaults to *None*. The name of the plugin. Defaults to *None*. The name of the plugin.
@ -126,6 +133,12 @@ class Plugin(QtCore.QObject):
``pluginHelpers`` ``pluginHelpers``
Defaults to *None*. A list of helper objects. Defaults to *None*. A list of helper objects.
``mediaItemClass``
The class name of the plugin's media item.
``settingsTabClass``
The class name of the plugin's settings tab.
""" """
QtCore.QObject.__init__(self) QtCore.QObject.__init__(self)
self.name = name self.name = name
@ -135,6 +148,8 @@ class Plugin(QtCore.QObject):
self.version = version self.version = version
self.settingsSection = self.name.lower() self.settingsSection = self.name.lower()
self.icon = None self.icon = None
self.mediaItemClass = mediaItemClass
self.settingsTabClass = settingsTabClass
self.weight = 0 self.weight = 0
self.status = PluginStatus.Inactive self.status = PluginStatus.Inactive
# Set up logging # Set up logging
@ -193,7 +208,9 @@ class Plugin(QtCore.QObject):
Construct a MediaManagerItem object with all the buttons and things Construct a MediaManagerItem object with all the buttons and things
you need, and return it for integration into openlp.org. you need, and return it for integration into openlp.org.
""" """
pass if self.mediaItemClass:
return self.mediaItemClass(self, self, self.icon)
return None
def addImportMenuItem(self, importMenu): def addImportMenuItem(self, importMenu):
""" """
@ -224,9 +241,13 @@ class Plugin(QtCore.QObject):
def getSettingsTab(self): def getSettingsTab(self):
""" """
Create a tab for the settings window. Create a tab for the settings window to display the configurable
options for this plugin to the user.
""" """
pass if self.settingsTabClass:
return self.settingsTabClass(self.name,
self.getString(StringContent.VisibleName)[u'title'])
return None
def addToMenu(self, menubar): def addToMenu(self, menubar):
""" """
@ -314,8 +335,39 @@ class Plugin(QtCore.QObject):
""" """
return self.textStrings[name] return self.textStrings[name]
def setPluginTextStrings(self): def setPluginUiTextStrings(self, tooltips):
""" """
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
""" """
pass ## Load Action ##
self.__setNameTextString(StringContent.Load,
UiStrings.Load, tooltips[u'load'])
## Import Action ##
self.__setNameTextString(StringContent.Import,
UiStrings.Import, tooltips[u'import'])
## New Action ##
self.__setNameTextString(StringContent.New,
UiStrings.Add, tooltips[u'new'])
## Edit Action ##
self.__setNameTextString(StringContent.Edit,
UiStrings.Edit, tooltips[u'edit'])
## Delete Action ##
self.__setNameTextString(StringContent.Delete,
UiStrings.Delete, tooltips[u'delete'])
## Preview Action ##
self.__setNameTextString(StringContent.Preview,
UiStrings.Preview, tooltips[u'preview'])
## Send Live Action ##
self.__setNameTextString(StringContent.Live,
UiStrings.Live, tooltips[u'live'])
## Add to Service Action ##
self.__setNameTextString(StringContent.Service,
UiStrings.Service, tooltips[u'service'])
def __setNameTextString(self, name, title, tooltip):
"""
Utility method for creating a plugin's textStrings. This method makes
use of the singular name of the plugin object so must only be called
after this has been set.
"""
self.textStrings[name] = {u'title': title, u'tooltip': tooltip}

View File

@ -68,7 +68,6 @@ class RenderManager(object):
self.theme_level = u'' self.theme_level = u''
self.override_background = None self.override_background = None
self.theme_data = None self.theme_data = None
self.alertTab = None
self.force_page = False self.force_page = False
def update_display(self): def update_display(self):
@ -261,4 +260,4 @@ class RenderManager(object):
log.debug(u'calculate default %d, %d, %f', log.debug(u'calculate default %d, %d, %f',
self.width, self.height, self.screen_ratio ) self.width, self.height, self.screen_ratio )
# 90% is start of footer # 90% is start of footer
self.footer_start = int(self.height * 0.90) self.footer_start = int(self.height * 0.90)

View File

@ -93,15 +93,15 @@ class SearchEdit(QtGui.QLineEdit):
``event`` ``event``
The event that happened. The event that happened.
""" """
sz = self.clearButton.size() size = self.clearButton.size()
frameWidth = self.style().pixelMetric( frameWidth = self.style().pixelMetric(
QtGui.QStyle.PM_DefaultFrameWidth) QtGui.QStyle.PM_DefaultFrameWidth)
self.clearButton.move(self.rect().right() - frameWidth - sz.width(), self.clearButton.move(self.rect().right() - frameWidth - size.width(),
(self.rect().bottom() + 1 - sz.height()) / 2) (self.rect().bottom() + 1 - size.height()) / 2)
if hasattr(self, u'menuButton'): if hasattr(self, u'menuButton'):
sz = self.menuButton.size() size = self.menuButton.size()
self.menuButton.move(self.rect().left() + frameWidth + 2, self.menuButton.move(self.rect().left() + frameWidth + 2,
(self.rect().bottom() + 1 - sz.height()) / 2) (self.rect().bottom() + 1 - size.height()) / 2)
def currentSearchType(self): def currentSearchType(self):
""" """

View File

@ -28,11 +28,13 @@ The :mod:`serviceitem` provides the service item functionality including the
type and capability of an item. type and capability of an item.
""" """
import datetime
import logging import logging
import os import os
import uuid import uuid
from openlp.core.lib import build_icon, clean_tags, expand_tags from openlp.core.lib import build_icon, clean_tags, expand_tags
from openlp.core.lib.ui import UiStrings
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -59,6 +61,8 @@ class ItemCapabilities(object):
OnLoadUpdate = 8 OnLoadUpdate = 8
AddIfNewItem = 9 AddIfNewItem = 9
ProvidesOwnDisplay = 10 ProvidesOwnDisplay = 10
AllowsDetailedTitleDisplay = 11
AllowsVarableStartTime = 12
class ServiceItem(object): class ServiceItem(object):
@ -104,6 +108,8 @@ class ServiceItem(object):
self.data_string = u'' self.data_string = u''
self.edit_id = None self.edit_id = None
self.xml_version = None self.xml_version = None
self.start_time = 0
self.media_length = 0
self._new_item() self._new_item()
def _new_item(self): def _new_item(self):
@ -256,7 +262,9 @@ class ServiceItem(object):
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 u'xml_version': self.xml_version,
u'start_time': self.start_time,
u'media_length': self.media_length
} }
service_data = [] service_data = []
if self.service_item_type == ServiceItemType.Text: if self.service_item_type == ServiceItemType.Text:
@ -300,6 +308,10 @@ class ServiceItem(object):
self.data_string = header[u'data'] self.data_string = header[u'data']
if u'xml_version' in header: if u'xml_version' in header:
self.xml_version = header[u'xml_version'] self.xml_version = header[u'xml_version']
if u'start_time' in header:
self.start_time = header[u'start_time']
if u'media_length' in header:
self.media_length = header[u'media_length']
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)
@ -314,6 +326,20 @@ class ServiceItem(object):
path, text_image[u'title'], text_image[u'image'] ) path, text_image[u'title'], text_image[u'image'] )
self._new_item() self._new_item()
def get_display_title(self):
"""
Returns the title of the service item.
"""
if self.is_text():
return self.title
else:
if ItemCapabilities.AllowsDetailedTitleDisplay in self.capabilities:
return self._raw_frames[0][u'title']
elif len(self._raw_frames) > 1:
return self.title
else:
return self._raw_frames[0][u'title']
def merge(self, other): def merge(self, other):
""" """
Updates the _uuid with the value from the original one Updates the _uuid with the value from the original one
@ -405,3 +431,24 @@ class ServiceItem(object):
return self._raw_frames[row][u'path'] return self._raw_frames[row][u'path']
except IndexError: except IndexError:
return u'' return u''
def get_media_time(self):
"""
Returns the start and finish time for a media item
"""
start = None
end = None
if self.start_time != 0:
start = UiStrings.StartTimeCode % \
unicode(datetime.timedelta(seconds=self.start_time))
if self.media_length != 0:
end = UiStrings.LengthTime % \
unicode(datetime.timedelta(seconds=self.media_length))
if not start and not end:
return None
elif start and not end:
return start
elif not start and end:
return end
else:
return u'%s : %s' % (start, end)

View File

@ -47,13 +47,16 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
# Default dictionary based on the current locale. # Default dictionary based on the current locale.
if ENCHANT_AVAILABLE: if ENCHANT_AVAILABLE:
try: try:
self.dict = enchant.Dict() self.dictionary = enchant.Dict()
except DictNotFoundError: except DictNotFoundError:
self.dict = enchant.Dict(u'en_US') self.dictionary = enchant.Dict(u'en_US')
self.highlighter = Highlighter(self.document()) self.highlighter = Highlighter(self.document())
self.highlighter.setDict(self.dict) self.highlighter.spellingDictionary = self.dictionary
def mousePressEvent(self, event): def mousePressEvent(self, event):
"""
Handle mouse clicks within the text edit region.
"""
if event.button() == QtCore.Qt.RightButton: if event.button() == QtCore.Qt.RightButton:
# Rewrite the mouse event to a left button event so the cursor is # Rewrite the mouse event to a left button event so the cursor is
# moved to the location of the pointer. # moved to the location of the pointer.
@ -63,6 +66,9 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
QtGui.QPlainTextEdit.mousePressEvent(self, event) QtGui.QPlainTextEdit.mousePressEvent(self, event)
def contextMenuEvent(self, event): def contextMenuEvent(self, event):
"""
Provide the context menu for the text edit region.
"""
popupMenu = self.createStandardContextMenu() popupMenu = self.createStandardContextMenu()
# Select the word under the cursor. # Select the word under the cursor.
cursor = self.textCursor() cursor = self.textCursor()
@ -74,10 +80,10 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
# suggestions if it is. # suggestions if it is.
if ENCHANT_AVAILABLE and self.textCursor().hasSelection(): if ENCHANT_AVAILABLE and self.textCursor().hasSelection():
text = unicode(self.textCursor().selectedText()) text = unicode(self.textCursor().selectedText())
if not self.dict.check(text): if not self.dictionary.check(text):
spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit', spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
'Spelling Suggestions')) 'Spelling Suggestions'))
for word in self.dict.suggest(text): for word in self.dictionary.suggest(text):
action = SpellAction(word, spell_menu) action = SpellAction(word, spell_menu)
action.correct.connect(self.correctWord) action.correct.connect(self.correctWord)
spell_menu.addAction(action) spell_menu.addAction(action)
@ -126,28 +132,32 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
cursor.insertText(html[u'start tag']) cursor.insertText(html[u'start tag'])
cursor.insertText(html[u'end tag']) cursor.insertText(html[u'end tag'])
class Highlighter(QtGui.QSyntaxHighlighter):
class Highlighter(QtGui.QSyntaxHighlighter):
"""
Provides a text highlighter for pointing out spelling errors in text.
"""
WORDS = u'(?iu)[\w\']+' WORDS = u'(?iu)[\w\']+'
def __init__(self, *args): def __init__(self, *args):
QtGui.QSyntaxHighlighter.__init__(self, *args) QtGui.QSyntaxHighlighter.__init__(self, *args)
self.dict = None self.spellingDictionary = None
def setDict(self, dict):
self.dict = dict
def highlightBlock(self, text): def highlightBlock(self, text):
if not self.dict: """
Highlight misspelt words in a block of text
"""
if not self.spellingDictionary:
return return
text = unicode(text) text = unicode(text)
format = QtGui.QTextCharFormat() charFormat = QtGui.QTextCharFormat()
format.setUnderlineColor(QtCore.Qt.red) charFormat.setUnderlineColor(QtCore.Qt.red)
format.setUnderlineStyle(QtGui.QTextCharFormat.SpellCheckUnderline) charFormat.setUnderlineStyle(QtGui.QTextCharFormat.SpellCheckUnderline)
for word_object in re.finditer(self.WORDS, text): for word_object in re.finditer(self.WORDS, text):
if not self.dict.check(word_object.group()): if not self.spellingDictionary.check(word_object.group()):
self.setFormat(word_object.start(), self.setFormat(word_object.start(),
word_object.end() - word_object.start(), format) word_object.end() - word_object.start(), charFormat)
class SpellAction(QtGui.QAction): class SpellAction(QtGui.QAction):
""" """

View File

@ -91,21 +91,30 @@ class ThemeLevel(object):
Song = 3 Song = 3
class BackgroundType(object): class BackgroundType(object):
"""
Type enumeration for backgrounds.
"""
Solid = 0 Solid = 0
Gradient = 1 Gradient = 1
Image = 2 Image = 2
@staticmethod @staticmethod
def to_string(type): def to_string(background_type):
if type == BackgroundType.Solid: """
Return a string representation of a background type.
"""
if background_type == BackgroundType.Solid:
return u'solid' return u'solid'
elif type == BackgroundType.Gradient: elif background_type == BackgroundType.Gradient:
return u'gradient' return u'gradient'
elif type == BackgroundType.Image: elif background_type == BackgroundType.Image:
return u'image' return u'image'
@staticmethod @staticmethod
def from_string(type_string): def from_string(type_string):
"""
Return a background type for the given string.
"""
if type_string == u'solid': if type_string == u'solid':
return BackgroundType.Solid return BackgroundType.Solid
elif type_string == u'gradient': elif type_string == u'gradient':
@ -114,6 +123,9 @@ class BackgroundType(object):
return BackgroundType.Image return BackgroundType.Image
class BackgroundGradientType(object): class BackgroundGradientType(object):
"""
Type enumeration for background gradients.
"""
Horizontal = 0 Horizontal = 0
Vertical = 1 Vertical = 1
Circular = 2 Circular = 2
@ -121,20 +133,26 @@ class BackgroundGradientType(object):
LeftBottom = 4 LeftBottom = 4
@staticmethod @staticmethod
def to_string(type): def to_string(gradient_type):
if type == BackgroundGradientType.Horizontal: """
Return a string representation of a background gradient type.
"""
if gradient_type == BackgroundGradientType.Horizontal:
return u'horizontal' return u'horizontal'
elif type == BackgroundGradientType.Vertical: elif gradient_type == BackgroundGradientType.Vertical:
return u'vertical' return u'vertical'
elif type == BackgroundGradientType.Circular: elif gradient_type == BackgroundGradientType.Circular:
return u'circular' return u'circular'
elif type == BackgroundGradientType.LeftTop: elif gradient_type == BackgroundGradientType.LeftTop:
return u'leftTop' return u'leftTop'
elif type == BackgroundGradientType.LeftBottom: elif gradient_type == BackgroundGradientType.LeftBottom:
return u'leftBottom' return u'leftBottom'
@staticmethod @staticmethod
def from_string(type_string): def from_string(type_string):
"""
Return a background gradient type for the given string.
"""
if type_string == u'horizontal': if type_string == u'horizontal':
return BackgroundGradientType.Horizontal return BackgroundGradientType.Horizontal
elif type_string == u'vertical': elif type_string == u'vertical':
@ -146,20 +164,53 @@ class BackgroundGradientType(object):
elif type_string == u'leftBottom': elif type_string == u'leftBottom':
return BackgroundGradientType.LeftBottom return BackgroundGradientType.LeftBottom
class HorizontalType(object): class HorizontalType(object):
"""
Type enumeration for horizontal alignment.
"""
Left = 0 Left = 0
Center = 1 Center = 2
Right = 2 Right = 1
@staticmethod
def to_string(horizontal_type):
"""
Return a string representation of a horizontal type.
"""
if horizontal_type == HorizontalType.Right:
return u'right'
elif horizontal_type == HorizontalType.Center:
return u'center'
else:
return u'left'
class VerticalType(object): class VerticalType(object):
"""
Type enumeration for vertical alignment.
"""
Top = 0 Top = 0
Middle = 1 Middle = 1
Bottom = 2 Bottom = 2
boolean_list = [u'italics', u'override', u'outline', u'shadow', @staticmethod
def to_string(vertical_type):
"""
Return a string representation of a vertical type.
"""
if vertical_type == VerticalType.Bottom:
return u'bottom'
elif vertical_type == VerticalType.Middle:
return u'middle'
else:
return u'top'
BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow',
u'slide_transition'] u'slide_transition']
integer_list = [u'size', 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']
@ -514,9 +565,9 @@ class ThemeXML(object):
return return
field = self._de_hump(element) field = self._de_hump(element)
tag = master + u'_' + field tag = master + u'_' + field
if field in boolean_list: if field in BOOLEAN_LIST:
setattr(self, tag, str_to_bool(value)) setattr(self, tag, str_to_bool(value))
elif field in integer_list: elif field in INTEGER_LIST:
setattr(self, tag, int(value)) setattr(self, tag, int(value))
else: else:
# make string value unicode # make string value unicode
@ -559,8 +610,7 @@ class ThemeXML(object):
self.background_end_color, self.background_end_color,
self.background_direction) self.background_direction)
else: else:
filename = \ filename = os.path.split(self.background_filename)[1]
os.path.split(self.background_filename)[1]
self.add_background_image(filename) self.add_background_image(filename)
self.add_font(self.font_main_name, self.add_font(self.font_main_name,
self.font_main_color, self.font_main_color,

View File

@ -61,7 +61,7 @@ class OpenLPToolbar(QtGui.QToolBar):
``icon`` ``icon``
The icon of the button. This can be an instance of QIcon, or a The icon of the button. This can be an instance of QIcon, or a
string cotaining either the absolute path to the image, or an string containing either the absolute path to the image, or an
internal resource path starting with ':/'. internal resource path starting with ':/'.
``tooltip`` ``tooltip``
@ -73,13 +73,13 @@ class OpenLPToolbar(QtGui.QToolBar):
``checkable`` ``checkable``
If *True* the button has two, *off* and *on*, states. Default is If *True* the button has two, *off* and *on*, states. Default is
*False*, which means the buttons has only one state. *False*, which means the buttons has only one state.
``shortcut`` ``shortcut``
The primary shortcut for this action The primary shortcut for this action
``alternate`` ``alternate``
The alternate shortcut for this action The alternate shortcut for this action
``context`` ``context``
Specify the context in which this shortcut is valid Specify the context in which this shortcut is valid
""" """

285
openlp/core/lib/ui.py Normal file
View File

@ -0,0 +1,285 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 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 #
###############################################################################
"""
The :mod:`ui` module provides standard UI components for OpenLP.
"""
import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, Receiver, translate
log = logging.getLogger(__name__)
class UiStrings(object):
"""
Provide standard strings for objects to use.
"""
# These strings should need a good reason to be retranslated elsewhere.
# Should some/more/less of these have an &amp; attached?
Add = translate('OpenLP.Ui', '&Add')
Advanced = translate('OpenLP.Ui', 'Advanced')
AllFiles = translate('OpenLP.Ui', 'All Files')
Authors = translate('OpenLP.Ui', 'Authors')
CreateService = translate('OpenLP.Ui', 'Create a new service.')
Delete = translate('OpenLP.Ui', '&Delete')
Edit = translate('OpenLP.Ui', '&Edit')
Error = translate('OpenLP.Ui', 'Error')
Import = translate('OpenLP.Ui', 'Import')
LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
Live = translate('OpenLP.Ui', 'Live')
Load = translate('OpenLP.Ui', 'Load')
New = translate('OpenLP.Ui', 'New')
NewService = translate('OpenLP.Ui', 'New Service')
OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0')
OpenService = translate('OpenLP.Ui', 'Open Service')
Preview = translate('OpenLP.Ui', 'Preview')
ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background')
ResetBG = translate('OpenLP.Ui', 'Reset Background')
ResetLiveBG = translate('OpenLP.Ui', 'Reset Live Background')
SaveService = translate('OpenLP.Ui', 'Save Service')
Service = translate('OpenLP.Ui', 'Service')
StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s'))
Theme = translate('OpenLP.Ui', 'Theme')
Themes = translate('OpenLP.Ui', 'Themes')
def add_welcome_page(parent, image):
"""
Generate an opening welcome page for a wizard using a provided image.
``parent``
A ``QWizard`` object to add the welcome page to.
``image``
A splash image for the wizard.
"""
parent.welcomePage = QtGui.QWizardPage()
parent.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
QtGui.QPixmap(image))
parent.welcomePage.setObjectName(u'WelcomePage')
parent.welcomeLayout = QtGui.QVBoxLayout(parent.welcomePage)
parent.welcomeLayout.setObjectName(u'WelcomeLayout')
parent.titleLabel = QtGui.QLabel(parent.welcomePage)
parent.titleLabel.setObjectName(u'TitleLabel')
parent.welcomeLayout.addWidget(parent.titleLabel)
parent.welcomeLayout.addSpacing(40)
parent.informationLabel = QtGui.QLabel(parent.welcomePage)
parent.informationLabel.setWordWrap(True)
parent.informationLabel.setObjectName(u'InformationLabel')
parent.welcomeLayout.addWidget(parent.informationLabel)
parent.welcomeLayout.addStretch()
parent.addPage(parent.welcomePage)
def create_accept_reject_button_box(parent, okay=False):
"""
Creates a standard dialog button box with two buttons. The buttons default
to save and cancel but the ``okay`` parameter can be used to make the
buttons okay and cancel instead.
The button box is connected to the parent's ``accept()`` and ``reject()``
methods to handle the default ``accepted()`` and ``rejected()`` signals.
``parent``
The parent object. This should be a ``QWidget`` descendant.
``okay``
If true creates an okay/cancel combination instead of save/cancel.
"""
button_box = QtGui.QDialogButtonBox(parent)
accept_button = QtGui.QDialogButtonBox.Save
if okay:
accept_button = QtGui.QDialogButtonBox.Ok
button_box.setStandardButtons(accept_button | QtGui.QDialogButtonBox.Cancel)
button_box.setObjectName(u'%sButtonBox' % parent)
QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'accepted()'),
parent.accept)
QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'rejected()'),
parent.reject)
return button_box
def critical_error_message_box(title=None, message=None, parent=None,
question=False):
"""
Provides a standard critical message box for errors that OpenLP displays
to users.
``title``
The title for the message box.
``message``
The message to display to the user.
``parent``
The parent UI element to attach the dialog to.
``question``
Should this message box question the user.
"""
if question:
return QtGui.QMessageBox.critical(parent, UiStrings.Error, message,
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
data = {u'message': message}
data[u'title'] = title if title else UiStrings.Error
return Receiver.send_message(u'openlp_error_message', data)
def media_item_combo_box(parent, name):
"""
Provide a standard combo box for media items.
"""
combo = QtGui.QComboBox(parent)
combo.setObjectName(name)
combo.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength)
combo.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
return combo
def create_delete_push_button(parent, icon=None):
"""
Creates a standard push button with a delete label and optional icon. The
button is connected to the parent's ``onDeleteButtonClicked()`` method to
handle the ``clicked()`` signal.
``parent``
The parent object. This should be a ``QWidget`` descendant.
``icon``
An icon to display on the button. This can be either a ``QIcon``, a
resource path or a file name.
"""
delete_button = QtGui.QPushButton(parent)
delete_button.setObjectName(u'deleteButton')
delete_icon = icon if icon else u':/general/general_delete.png'
delete_button.setIcon(build_icon(delete_icon))
delete_button.setText(UiStrings.Delete)
delete_button.setToolTip(
translate('OpenLP.Ui', 'Delete the selected item.'))
QtCore.QObject.connect(delete_button,
QtCore.SIGNAL(u'clicked()'), parent.onDeleteButtonClicked)
return delete_button
def create_up_down_push_button_set(parent):
"""
Creates a standard set of two push buttons, one for up and the other for
down, for use with lists. The buttons use arrow icons and no text and are
connected to the parent's ``onUpButtonClicked()`` and
``onDownButtonClicked()`` to handle their respective ``clicked()`` signals.
``parent``
The parent object. This should be a ``QWidget`` descendant.
"""
up_button = QtGui.QPushButton(parent)
up_button.setIcon(build_icon(u':/services/service_up.png'))
up_button.setObjectName(u'upButton')
up_button.setToolTip(
translate('OpenLP.Ui', 'Move selection up one position.'))
down_button = QtGui.QPushButton(parent)
down_button.setIcon(build_icon(u':/services/service_down.png'))
down_button.setObjectName(u'downButton')
down_button.setToolTip(
translate('OpenLP.Ui', 'Move selection down one position.'))
QtCore.QObject.connect(up_button,
QtCore.SIGNAL(u'clicked()'), parent.onUpButtonClicked)
QtCore.QObject.connect(down_button,
QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked)
return up_button, down_button
def base_action(parent, name):
"""
Return the most basic action with the object name set.
"""
action = QtGui.QAction(parent)
action.setObjectName(name)
return action
def checkable_action(parent, name, checked=None):
"""
Return a standard action with the checkable attribute set.
"""
action = base_action(parent, name)
action.setCheckable(True)
if checked is not None:
action.setChecked(checked)
return action
def icon_action(parent, name, icon, checked=None):
"""
Return a standard action with an icon.
"""
if checked is not None:
action = checkable_action(parent, name, checked)
else:
action = base_action(parent, name)
action.setIcon(build_icon(icon))
return action
def shortcut_action(parent, text, shortcuts, function):
"""
Return a shortcut enabled action.
"""
action = QtGui.QAction(text, parent)
action.setShortcuts(shortcuts)
action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), function)
return action
def add_widget_completer(cache, widget):
"""
Adds a text autocompleter to a widget.
``cache``
The list of items to use as suggestions.
``widget``
The object to use the completer.
"""
completer = QtGui.QCompleter(cache)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
widget.setCompleter(completer)
def create_valign_combo(form, parent, layout):
"""
Creates a standard label and combo box for asking users to select a
vertical alignment.
``form``
The UI screen that the label and combo will appear on.
``parent``
The parent object. This should be a ``QWidget`` descendant.
``layout``
A layout object to add the label and combo widgets to.
"""
verticalLabel = QtGui.QLabel(parent)
verticalLabel.setObjectName(u'VerticalLabel')
verticalLabel.setText(translate('OpenLP.Ui', '&Vertical Align:'))
form.verticalComboBox = QtGui.QComboBox(parent)
form.verticalComboBox.setObjectName(u'VerticalComboBox')
form.verticalComboBox.addItem(translate('OpenLP.Ui', 'Top'))
form.verticalComboBox.addItem(translate('OpenLP.Ui', 'Middle'))
form.verticalComboBox.addItem(translate('OpenLP.Ui', 'Bottom'))
verticalLabel.setBuddy(form.verticalComboBox)
layout.addRow(verticalLabel, form.verticalComboBox)

View File

@ -33,11 +33,14 @@ processing version 1 themes in OpenLP version 2.
from xml.etree.ElementTree import ElementTree, XML from xml.etree.ElementTree import ElementTree, XML
from PyQt4 import QtGui from PyQt4 import QtGui
DELPHI_COLORS = {u'clRed': 0xFF0000, DELPHI_COLORS = {
u'clBlue': 0x0000FF, u'clAqua': 0x00FFFF, u'clBlack': 0x000000, u'clBlue': 0x0000FF,
u'clYellow': 0xFFFF00, u'clFuchsia': 0xFF00FF, u'clGray': 0x808080, u'clGreen': 0x008000,
u'clBlack': 0x000000, u'clLime': 0x00FF00, u'clMaroon': 0x800000, u'clNavy': 0x000080,
u'clWhite': 0xFFFFFF} u'clOlive': 0x808000, u'clPurple': 0x800080, u'clRed': 0xFF0000,
u'clSilver': 0xC0C0C0, u'clTeal': 0x008080, u'clWhite': 0xFFFFFF,
u'clYellow': 0xFFFF00
}
BLANK_STYLE_XML = \ BLANK_STYLE_XML = \
'''<?xml version="1.0" encoding="iso-8859-1"?> '''<?xml version="1.0" encoding="iso-8859-1"?>
@ -68,38 +71,45 @@ class Theme(object):
Theme name Theme name
``BackgroundMode`` ``BackgroundMode``
The behaviour of the background. Valid modes are: The behaviour of the background. Valid modes are:
- 0 - Transparent
- 1 - Opaque * ``0`` - Transparent
* ``1`` - Opaque
``BackgroundType`` ``BackgroundType``
The content of the background. Valid types are: The content of the background. Valid types are:
- 0 - solid color
- 1 - gradient color * ``0`` - solid color
- 2 - image * ``1`` - gradient color
* ``2`` - image
``BackgroundParameter1`` ``BackgroundParameter1``
Extra information about the background. The contents of this attribute Extra information about the background. The contents of this attribute
depend on the BackgroundType: depend on the BackgroundType:
- image: image filename
- gradient: start color * ``image`` - image filename
- solid: color * ``gradient`` - start color
* ``solid`` - color
``BackgroundParameter2`` ``BackgroundParameter2``
Extra information about the background. The contents of this attribute Extra information about the background. The contents of this attribute
depend on the BackgroundType: depend on the BackgroundType:
- image: border color
- gradient: end color * ``image`` - border color
- solid: N/A * ``gradient`` - end color
* ``solid`` - N/A
``BackgroundParameter3`` ``BackgroundParameter3``
Extra information about the background. The contents of this attribute Extra information about the background. The contents of this attribute
depend on the BackgroundType: depend on the BackgroundType:
- image: N/A
- gradient: The direction of the gradient. Valid entries are: * ``image`` - N/A
- 0 -> vertical * ``gradient`` - The direction of the gradient. Valid entries are:
- 1 -> horizontal
- solid: N/A * ``0`` - vertical
* ``1`` - horizontal
* ``solid`` - N/A
``FontName`` ``FontName``
Name of the font to use for the main font. Name of the font to use for the main font.
@ -115,36 +125,41 @@ class Theme(object):
``Shadow`` ``Shadow``
The shadow type to apply to the main font. The shadow type to apply to the main font.
- 0 - no shadow
- non-zero - use shadow * ``0`` - no shadow
* non-zero - use shadow
``ShadowColor`` ``ShadowColor``
Color for the shadow Color for the shadow
``Outline`` ``Outline``
The outline to apply to the main font The outline to apply to the main font
- 0 - no outline
- non-zero - use outline * ``0`` - no outline
* non-zero - use outline
``OutlineColor`` ``OutlineColor``
Color for the outline (or None if Outline is 0) Color for the outline (or None if Outline is 0)
``HorizontalAlign`` ``HorizontalAlign``
The horizontal alignment to apply to text. Valid alignments are: The horizontal alignment to apply to text. Valid alignments are:
- 0 - left align
- 1 - right align * ``0`` - left align
- 2 - centre align * ``1`` - right align
* ``2`` - centre align
``VerticalAlign`` ``VerticalAlign``
The vertical alignment to apply to the text. Valid alignments are: The vertical alignment to apply to the text. Valid alignments are:
- 0 - top align
- 1 - bottom align * ``0`` - top align
- 2 - centre align * ``1`` - bottom align
* ``2`` - centre align
``WrapStyle`` ``WrapStyle``
The wrap style to apply to the text. Valid styles are: The wrap style to apply to the text. Valid styles are:
- 0 - normal
- 1 - lyrics * ``0`` - normal
* ``1`` - lyrics
""" """
def __init__(self, xml): def __init__(self, xml):
""" """
@ -184,7 +199,6 @@ class Theme(object):
if element.tag != u'Theme': if element.tag != u'Theme':
element_text = element.text element_text = element.text
val = 0 val = 0
# easy!
if element_text is None: if element_text is None:
val = element_text val = element_text
# strings need special handling to sort the colours out # strings need special handling to sort the colours out

View File

@ -28,7 +28,7 @@ The :mod:`ui` module provides the core user interface for OpenLP
""" """
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.lib import translate, Receiver from openlp.core.lib import translate
class HideMode(object): class HideMode(object):
""" """
@ -51,36 +51,9 @@ class HideMode(object):
Theme = 2 Theme = 2
Screen = 3 Screen = 3
def criticalErrorMessageBox(title=None, message=None, parent=None,
question=False):
"""
Provides a standard critical message box for errors that OpenLP displays
to users.
``title``
The title for the message box.
``message``
The message to display to the user.
``parent``
The parent UI element to attach the dialog to.
``question``
Should this message box question the user.
"""
error = translate('OpenLP.Ui', 'Error')
if question:
return QtGui.QMessageBox.critical(parent, error, message,
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
data = {u'message': message}
data[u'title'] = title if title else error
return Receiver.send_message(u'openlp_error_message', data)
from themeform import ThemeForm from themeform import ThemeForm
from filerenameform import FileRenameForm from filerenameform import FileRenameForm
from starttimeform import StartTimeForm
from maindisplay import MainDisplay from maindisplay import MainDisplay
from servicenoteform import ServiceNoteForm from servicenoteform import ServiceNoteForm
from serviceitemeditform import ServiceItemEditForm from serviceitemeditform import ServiceItemEditForm
@ -99,6 +72,6 @@ from mediadockmanager import MediaDockManager
from servicemanager import ServiceManager from servicemanager import ServiceManager
from thememanager import ThemeManager from thememanager import ThemeManager
__all__ = ['criticalErrorMessageBox', 'SplashScreen', 'AboutForm', __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay',
'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager', 'SlideController', 'ServiceManager', 'ThemeManager', 'MediaDockManager',
'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm'] 'ServiceItemEditForm']

View File

@ -164,9 +164,10 @@ class Ui_AboutDialog(object):
self.licenseTextEdit.setPlainText(translate('OpenLP.AboutForm', self.licenseTextEdit.setPlainText(translate('OpenLP.AboutForm',
'Copyright \xa9 2004-2011 Raoul Snyman\n' 'Copyright \xa9 2004-2011 Raoul Snyman\n'
'Portions copyright \xa9 2004-2011 ' 'Portions copyright \xa9 2004-2011 '
'Tim Bentley, Jonathan Corwin, Michael Gorven, Scott Guerrieri, ' 'Tim Bentley, Jonathan Corwin, Michael Gorven, Scott Guerrieri,\n'
'Christian Richter, Maikel Stuivenberg, Martin Thompson, Jon ' 'Meinert Jordan, Andreas Preikschat, Christian Richter, Philip\n'
'Tibble, Carsten Tinggaard\n' 'Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Carstenn'
'Tinggaard, Frode Woldsund\n'
'\n' '\n'
'This program is free software; you can redistribute it and/or ' 'This program is free software; you can redistribute it and/or '
'modify it under the terms of the GNU General Public License as ' 'modify it under the terms of the GNU General Public License as '

View File

@ -29,6 +29,7 @@ The :mod:`advancedtab` provides an advanced settings facility.
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate from openlp.core.lib import SettingsTab, translate
from openlp.core.lib.ui import UiStrings
class AdvancedTab(SettingsTab): class AdvancedTab(SettingsTab):
""" """
@ -112,7 +113,7 @@ class AdvancedTab(SettingsTab):
""" """
Setup the interface translation strings. Setup the interface translation strings.
""" """
self.tabTitleVisible = translate('OpenLP.AdvancedTab', 'Advanced') self.tabTitleVisible = UiStrings.Advanced
self.uiGroupBox.setTitle(translate('OpenLP.AdvancedTab', 'UI Settings')) self.uiGroupBox.setTitle(translate('OpenLP.AdvancedTab', 'UI Settings'))
self.recentLabel.setText( self.recentLabel.setText(
translate('OpenLP.AdvancedTab', translate('OpenLP.AdvancedTab',

View File

@ -23,27 +23,27 @@
# 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 #
############################################################################### ###############################################################################
''' """
The :mod:`DisplayTagTab` provides an Tag Edit facility. The Base set are The :mod:`DisplayTagTab` provides an Tag Edit facility. The Base set are
protected and included each time loaded. Custom tags can be defined and saved. protected and included each time loaded. Custom tags can be defined and saved.
The Custom Tag arrays are saved in a pickle so QSettings works on them. Base The Custom Tag arrays are saved in a pickle so QSettings works on them. Base
Tags cannot be changed. Tags cannot be changed.
"""
'''
import cPickle import cPickle
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate, DisplayTags from openlp.core.lib import SettingsTab, translate, DisplayTags
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import UiStrings, critical_error_message_box
class DisplayTagTab(SettingsTab): class DisplayTagTab(SettingsTab):
''' """
The :class:`DisplayTagTab` manages the settings tab . The :class:`DisplayTagTab` manages the settings tab .
''' """
def __init__(self): def __init__(self):
''' """
Initialise the settings tab Initialise the settings tab
''' """
SettingsTab.__init__(self, u'Display Tags') SettingsTab.__init__(self, u'Display Tags')
def resizeEvent(self, event=None): def resizeEvent(self, event=None):
@ -67,9 +67,9 @@ class DisplayTagTab(SettingsTab):
self.selected = -1 self.selected = -1
def setupUi(self): def setupUi(self):
''' """
Configure the UI elements for the tab. Configure the UI elements for the tab.
''' """
self.setObjectName(u'DisplayTagTab') self.setObjectName(u'DisplayTagTab')
self.tabTitleVisible = \ self.tabTitleVisible = \
translate(u'OpenLP.DisplayTagTab', 'Display Tags') translate(u'OpenLP.DisplayTagTab', 'Display Tags')
@ -164,8 +164,7 @@ class DisplayTagTab(SettingsTab):
self.startTagLabel.setText( self.startTagLabel.setText(
translate('OpenLP.DisplayTagTab', 'Start tag')) translate('OpenLP.DisplayTagTab', 'Start tag'))
self.endTagLabel.setText(translate('OpenLP.DisplayTagTab', 'End tag')) self.endTagLabel.setText(translate('OpenLP.DisplayTagTab', 'End tag'))
self.deletePushButton.setText( self.deletePushButton.setText(UiStrings.Delete)
translate('OpenLP.DisplayTagTab', 'Delete'))
self.defaultPushButton.setText( self.defaultPushButton.setText(
translate('OpenLP.DisplayTagTab', 'Default')) translate('OpenLP.DisplayTagTab', 'Default'))
self.newPushButton.setText(translate('OpenLP.DisplayTagTab', 'New')) self.newPushButton.setText(translate('OpenLP.DisplayTagTab', 'New'))
@ -276,7 +275,7 @@ class DisplayTagTab(SettingsTab):
""" """
for html in DisplayTags.get_html_tags(): for html in DisplayTags.get_html_tags():
if self._strip(html[u'start tag']) == u'n': if self._strip(html[u'start tag']) == u'n':
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.DisplayTagTab', 'Update Error'), translate('OpenLP.DisplayTagTab', 'Update Error'),
translate('OpenLP.DisplayTagTab', translate('OpenLP.DisplayTagTab',
'Tag "n" already defined.')) 'Tag "n" already defined.'))
@ -317,7 +316,7 @@ class DisplayTagTab(SettingsTab):
for linenumber, html1 in enumerate(html_expands): for linenumber, html1 in enumerate(html_expands):
if self._strip(html1[u'start tag']) == tag and \ if self._strip(html1[u'start tag']) == tag and \
linenumber != self.selected: linenumber != self.selected:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.DisplayTagTab', 'Update Error'), translate('OpenLP.DisplayTagTab', 'Update Error'),
unicode(translate('OpenLP.DisplayTagTab', unicode(translate('OpenLP.DisplayTagTab',
'Tag %s already defined.')) % tag) 'Tag %s already defined.')) % tag)

View File

@ -46,6 +46,15 @@ class Ui_ExceptionDialog(object):
self.messageLabel.setObjectName(u'messageLabel') self.messageLabel.setObjectName(u'messageLabel')
self.messageLayout.addWidget(self.messageLabel) self.messageLayout.addWidget(self.messageLabel)
self.exceptionLayout.addLayout(self.messageLayout) self.exceptionLayout.addLayout(self.messageLayout)
self.descriptionExplanation = QtGui.QLabel(exceptionDialog)
self.descriptionExplanation.setObjectName(u'descriptionExplanation')
self.exceptionLayout.addWidget(self.descriptionExplanation)
self.descriptionTextEdit = QtGui.QPlainTextEdit(exceptionDialog)
self.descriptionTextEdit.setObjectName(u'descriptionTextEdit')
self.exceptionLayout.addWidget(self.descriptionTextEdit)
self.descriptionWordCount = QtGui.QLabel(exceptionDialog)
self.descriptionWordCount.setObjectName(u'descriptionWordCount')
self.exceptionLayout.addWidget(self.descriptionWordCount)
self.exceptionTextEdit = QtGui.QPlainTextEdit(exceptionDialog) self.exceptionTextEdit = QtGui.QPlainTextEdit(exceptionDialog)
self.exceptionTextEdit.setReadOnly(True) self.exceptionTextEdit.setReadOnly(True)
self.exceptionTextEdit.setObjectName(u'exceptionTextEdit') self.exceptionTextEdit.setObjectName(u'exceptionTextEdit')
@ -65,19 +74,31 @@ class Ui_ExceptionDialog(object):
self.saveReportButton.setObjectName(u'saveReportButton') self.saveReportButton.setObjectName(u'saveReportButton')
self.exceptionButtonBox.addButton(self.saveReportButton, self.exceptionButtonBox.addButton(self.saveReportButton,
QtGui.QDialogButtonBox.ActionRole) QtGui.QDialogButtonBox.ActionRole)
self.attachFileButton = QtGui.QPushButton(exceptionDialog)
self.attachFileButton.setIcon(build_icon(u':/general/general_open.png'))
self.attachFileButton.setObjectName(u'attachFileButton')
self.exceptionButtonBox.addButton(self.attachFileButton,
QtGui.QDialogButtonBox.ActionRole)
self.retranslateUi(exceptionDialog) self.retranslateUi(exceptionDialog)
QtCore.QObject.connect(self.descriptionTextEdit,
QtCore.SIGNAL(u'textChanged()'), self.onDescriptionUpdated)
QtCore.QObject.connect(self.exceptionButtonBox, QtCore.QObject.connect(self.exceptionButtonBox,
QtCore.SIGNAL(u'rejected()'), exceptionDialog.reject) QtCore.SIGNAL(u'rejected()'), exceptionDialog.reject)
QtCore.QObject.connect(self.sendReportButton, QtCore.QObject.connect(self.sendReportButton,
QtCore.SIGNAL(u'pressed()'), self.onSendReportButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onSendReportButtonPressed)
QtCore.QObject.connect(self.saveReportButton, QtCore.QObject.connect(self.saveReportButton,
QtCore.SIGNAL(u'pressed()'), self.onSaveReportButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onSaveReportButtonPressed)
QtCore.QObject.connect(self.attachFileButton,
QtCore.SIGNAL(u'pressed()'), self.onAttachFileButtonPressed)
QtCore.QMetaObject.connectSlotsByName(exceptionDialog) QtCore.QMetaObject.connectSlotsByName(exceptionDialog)
def retranslateUi(self, exceptionDialog): def retranslateUi(self, exceptionDialog):
exceptionDialog.setWindowTitle( exceptionDialog.setWindowTitle(
translate('OpenLP.ExceptionDialog', 'Error Occurred')) translate('OpenLP.ExceptionDialog', 'Error Occurred'))
self.descriptionExplanation.setText(translate('OpenLP.ExceptionDialog',
'Please enter a description of what you were doing to cause this '
'error \n(Minimum 20 characters)'))
self.messageLabel.setText(translate('OpenLP.ExceptionDialog', 'Oops! ' self.messageLabel.setText(translate('OpenLP.ExceptionDialog', 'Oops! '
'OpenLP hit a problem, and couldn\'t recover. The text in the box ' 'OpenLP hit a problem, and couldn\'t recover. The text in the box '
'below contains information that might be helpful to the OpenLP ' 'below contains information that might be helpful to the OpenLP '
@ -88,3 +109,5 @@ class Ui_ExceptionDialog(object):
'Send E-Mail')) 'Send E-Mail'))
self.saveReportButton.setText(translate('OpenLP.ExceptionDialog', self.saveReportButton.setText(translate('OpenLP.ExceptionDialog',
'Save to File')) 'Save to File'))
self.attachFileButton.setText(translate('OpenLP.ExceptionDialog',
'Attach File'))

View File

@ -56,6 +56,7 @@ except ImportError:
from openlp.core.lib import translate, SettingsManager from openlp.core.lib import translate, SettingsManager
from openlp.core.lib.mailto import mailto from openlp.core.lib.mailto import mailto
from openlp.core.lib.ui import UiStrings
from exceptiondialog import Ui_ExceptionDialog from exceptiondialog import Ui_ExceptionDialog
@ -70,8 +71,15 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
self.setupUi(self) self.setupUi(self)
self.settingsSection = u'crashreport' self.settingsSection = u'crashreport'
def exec_(self):
self.descriptionTextEdit.setPlainText(u'')
self.onDescriptionUpdated()
self.fileAttachment = None
return QtGui.QDialog.exec_(self)
def _createReport(self): def _createReport(self):
openlp_version = self.parent().applicationVersion[u'full'] openlp_version = self.parent().applicationVersion[u'full']
description = unicode(self.descriptionTextEdit.toPlainText())
traceback = unicode(self.exceptionTextEdit.toPlainText()) traceback = unicode(self.exceptionTextEdit.toPlainText())
system = unicode(translate('OpenLP.ExceptionForm', system = unicode(translate('OpenLP.ExceptionForm',
'Platform: %s\n')) % platform.platform() 'Platform: %s\n')) % platform.platform()
@ -90,7 +98,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
system = system + u'Desktop: KDE SC\n' system = system + u'Desktop: KDE SC\n'
elif os.environ.get(u'GNOME_DESKTOP_SESSION_ID'): elif os.environ.get(u'GNOME_DESKTOP_SESSION_ID'):
system = system + u'Desktop: GNOME\n' system = system + u'Desktop: GNOME\n'
return (openlp_version, traceback, system, libraries) return (openlp_version, description, traceback, system, libraries)
def onSaveReportButtonPressed(self): def onSaveReportButtonPressed(self):
""" """
@ -99,6 +107,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
report = unicode(translate('OpenLP.ExceptionForm', report = unicode(translate('OpenLP.ExceptionForm',
'**OpenLP Bug Report**\n' '**OpenLP Bug Report**\n'
'Version: %s\n\n' 'Version: %s\n\n'
'--- Details of the Exception. ---\n\n%s\n\n '
'--- Exception Traceback ---\n%s\n' '--- Exception Traceback ---\n%s\n'
'--- System information ---\n%s\n' '--- System information ---\n%s\n'
'--- Library Versions ---\n%s\n')) '--- Library Versions ---\n%s\n'))
@ -132,18 +141,47 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
body = unicode(translate('OpenLP.ExceptionForm', body = unicode(translate('OpenLP.ExceptionForm',
'*OpenLP Bug Report*\n' '*OpenLP Bug Report*\n'
'Version: %s\n\n' 'Version: %s\n\n'
'--- Please enter the report below this line. ---\n\n\n' '--- Details of the Exception. ---\n\n%s\n\n '
'--- Exception Traceback ---\n%s\n' '--- Exception Traceback ---\n%s\n'
'--- System information ---\n%s\n' '--- System information ---\n%s\n'
'--- Library Versions ---\n%s\n', '--- Library Versions ---\n%s\n',
'Please add the information that bug reports are favoured written ' 'Please add the information that bug reports are favoured written '
'in English.')) 'in English.'))
content = self._createReport() content = self._createReport()
for line in content[1].split(u'\n'): for line in content[2].split(u'\n'):
if re.search(r'[/\\]openlp[/\\]', line): if re.search(r'[/\\]openlp[/\\]', line):
source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line) source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line)
if u':' in line: if u':' in line:
exception = line.split(u'\n')[-1].split(u':')[0] exception = line.split(u'\n')[-1].split(u':')[0]
subject = u'Bug report: %s in %s' % (exception, source) subject = u'Bug report: %s in %s' % (exception, source)
mailto(address=u'bugs@openlp.org', subject=subject, if self.fileAttachment:
body=body % content) mailto(address=u'bugs@openlp.org', subject=subject,
body=body % content, attach=self.fileAttachment)
else:
mailto(address=u'bugs@openlp.org', subject=subject,
body=body % content)
def onDescriptionUpdated(self):
count = int(20 - len(self.descriptionTextEdit.toPlainText()))
if count < 0:
count = 0
self.__buttonState(True)
else:
self.__buttonState(False)
self.descriptionWordCount.setText(
unicode(translate('OpenLP.ExceptionDialog',
'Description characters to enter : %s')) % count )
def onAttachFileButtonPressed(self):
files = QtGui.QFileDialog.getOpenFileName(
self,translate('ImagePlugin.ExceptionDialog',
'Select Attachment'),
SettingsManager.get_last_dir(u'exceptions'),
u'%s (*.*) (*)' % UiStrings.AllFiles)
log.info(u'New files(s) %s', unicode(files))
if files:
self.fileAttachment = unicode(files)
def __buttonState(self, state):
self.saveReportButton.setEnabled(state)
self.sendReportButton.setEnabled(state)

View File

@ -27,30 +27,28 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.lib.ui import create_accept_reject_button_box
class Ui_FileRenameDialog(object): class Ui_FileRenameDialog(object):
def setupUi(self, FileRenameDialog): def setupUi(self, fileRenameDialog):
FileRenameDialog.setObjectName(u'FileRenameDialog') fileRenameDialog.setObjectName(u'fileRenameDialog')
FileRenameDialog.resize(300, 10) fileRenameDialog.resize(300, 10)
self.dialogLayout = QtGui.QGridLayout(FileRenameDialog) self.dialogLayout = QtGui.QGridLayout(fileRenameDialog)
self.dialogLayout.setObjectName(u'dialogLayout') self.dialogLayout.setObjectName(u'dialogLayout')
self.fileNameLabel = QtGui.QLabel(FileRenameDialog) self.fileNameLabel = QtGui.QLabel(fileRenameDialog)
self.fileNameLabel.setObjectName(u'fileNameLabel') self.fileNameLabel.setObjectName(u'fileNameLabel')
self.dialogLayout.addWidget(self.fileNameLabel, 0, 0) self.dialogLayout.addWidget(self.fileNameLabel, 0, 0)
self.fileNameEdit = QtGui.QLineEdit(FileRenameDialog) self.fileNameEdit = QtGui.QLineEdit(fileRenameDialog)
self.fileNameEdit.setValidator(QtGui.QRegExpValidator( self.fileNameEdit.setValidator(QtGui.QRegExpValidator(
QtCore.QRegExp(r'[^/\\?*|<>\[\]":<>+%]+'), self)) QtCore.QRegExp(r'[^/\\?*|<>\[\]":<>+%]+'), self))
self.fileNameEdit.setObjectName(u'fileNameEdit') self.fileNameEdit.setObjectName(u'fileNameEdit')
self.dialogLayout.addWidget(self.fileNameEdit, 0, 1) self.dialogLayout.addWidget(self.fileNameEdit, 0, 1)
self.buttonBox = QtGui.QDialogButtonBox(FileRenameDialog) self.buttonBox = create_accept_reject_button_box(fileRenameDialog, True)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2) self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2)
self.retranslateUi(FileRenameDialog) self.retranslateUi(fileRenameDialog)
self.setMaximumHeight(self.sizeHint().height()) self.setMaximumHeight(self.sizeHint().height())
QtCore.QMetaObject.connectSlotsByName(FileRenameDialog) QtCore.QMetaObject.connectSlotsByName(fileRenameDialog)
def retranslateUi(self, FileRenameDialog): def retranslateUi(self, fileRenameDialog):
self.fileNameLabel.setText(translate('OpenLP.FileRenameForm', self.fileNameLabel.setText(translate('OpenLP.FileRenameForm',
'New File Name:')) 'New File Name:'))

View File

@ -24,7 +24,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from PyQt4 import QtCore, QtGui from PyQt4 import QtGui
from filerenamedialog import Ui_FileRenameDialog from filerenamedialog import Ui_FileRenameDialog
@ -37,10 +37,6 @@ class FileRenameForm(QtGui.QDialog, Ui_FileRenameDialog):
def __init__(self, parent): def __init__(self, parent):
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
self.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
self.reject)
def exec_(self, copy=False): def exec_(self, copy=False):
""" """
@ -51,5 +47,5 @@ class FileRenameForm(QtGui.QDialog, Ui_FileRenameDialog):
'File Copy')) 'File Copy'))
else: else:
self.setWindowTitle(translate('OpenLP.FileRenameForm', self.setWindowTitle(translate('OpenLP.FileRenameForm',
'File Rename')) 'File Rename'))
return QtGui.QDialog.exec_(self) return QtGui.QDialog.exec_(self)

View File

@ -51,6 +51,7 @@ class ValidEdit(QtGui.QLineEdit):
else: else:
return self.text() return self.text()
class GeneralTab(SettingsTab): class GeneralTab(SettingsTab):
""" """
GeneralTab is the general settings tab in the settings dialog. GeneralTab is the general settings tab in the settings dialog.
@ -113,6 +114,9 @@ class GeneralTab(SettingsTab):
self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox) self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.showSplashCheckBox.setObjectName(u'showSplashCheckBox') self.showSplashCheckBox.setObjectName(u'showSplashCheckBox')
self.startupLayout.addWidget(self.showSplashCheckBox) self.startupLayout.addWidget(self.showSplashCheckBox)
self.checkForUpdatesCheckBox = QtGui.QCheckBox(self.startupGroupBox)
self.checkForUpdatesCheckBox.setObjectName(u'checkForUpdatesCheckBox')
self.startupLayout.addWidget(self.checkForUpdatesCheckBox)
self.leftLayout.addWidget(self.startupGroupBox) self.leftLayout.addWidget(self.startupGroupBox)
self.settingsGroupBox = QtGui.QGroupBox(self.leftColumn) self.settingsGroupBox = QtGui.QGroupBox(self.leftColumn)
self.settingsGroupBox.setObjectName(u'settingsGroupBox') self.settingsGroupBox.setObjectName(u'settingsGroupBox')
@ -249,6 +253,8 @@ class GeneralTab(SettingsTab):
'Automatically open the last service')) 'Automatically open the last service'))
self.showSplashCheckBox.setText( self.showSplashCheckBox.setText(
translate('OpenLP.GeneralTab', 'Show the splash screen')) translate('OpenLP.GeneralTab', 'Show the splash screen'))
self.checkForUpdatesCheckBox.setText(
translate('OpenLP.GeneralTab', 'Check for updates to OpenLP'))
self.settingsGroupBox.setTitle( self.settingsGroupBox.setTitle(
translate('OpenLP.GeneralTab', 'Application Settings')) translate('OpenLP.GeneralTab', 'Application Settings'))
self.saveCheckServiceCheckBox.setText(translate('OpenLP.GeneralTab', self.saveCheckServiceCheckBox.setText(translate('OpenLP.GeneralTab',
@ -317,6 +323,8 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(False)).toBool()) QtCore.QVariant(False)).toBool())
self.showSplashCheckBox.setChecked(settings.value(u'show splash', self.showSplashCheckBox.setChecked(settings.value(u'show splash',
QtCore.QVariant(True)).toBool()) QtCore.QVariant(True)).toBool())
self.checkForUpdatesCheckBox.setChecked(settings.value(u'update check',
QtCore.QVariant(True)).toBool())
self.autoPreviewCheckBox.setChecked(settings.value(u'auto preview', self.autoPreviewCheckBox.setChecked(settings.value(u'auto preview',
QtCore.QVariant(False)).toBool()) QtCore.QVariant(False)).toBool())
self.timeoutSpinBox.setValue(settings.value(u'loop delay', self.timeoutSpinBox.setValue(settings.value(u'loop delay',
@ -363,6 +371,8 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(self.autoOpenCheckBox.isChecked())) QtCore.QVariant(self.autoOpenCheckBox.isChecked()))
settings.setValue(u'show splash', settings.setValue(u'show splash',
QtCore.QVariant(self.showSplashCheckBox.isChecked())) QtCore.QVariant(self.showSplashCheckBox.isChecked()))
settings.setValue(u'update check',
QtCore.QVariant(self.checkForUpdatesCheckBox.isChecked()))
settings.setValue(u'save prompt', settings.setValue(u'save prompt',
QtCore.QVariant(self.saveCheckServiceCheckBox.isChecked())) QtCore.QVariant(self.saveCheckServiceCheckBox.isChecked()))
settings.setValue(u'auto preview', settings.setValue(u'auto preview',

View File

@ -67,11 +67,12 @@ class MainDisplay(DisplayWidget):
self.isLive = live self.isLive = live
self.alertTab = None self.alertTab = None
self.hideMode = None self.hideMode = None
self.override = {}
mainIcon = build_icon(u':/icon/openlp-logo-16x16.png') mainIcon = build_icon(u':/icon/openlp-logo-16x16.png')
self.setWindowIcon(mainIcon) self.setWindowIcon(mainIcon)
self.retranslateUi() self.retranslateUi()
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 | QtCore.Qt.Tool |
QtCore.Qt.WindowStaysOnTopHint) QtCore.Qt.WindowStaysOnTopHint)
if self.isLive: if self.isLive:
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -105,13 +106,16 @@ class MainDisplay(DisplayWidget):
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.videoWidget) Phonon.createPath(self.mediaObject, self.videoWidget)
Phonon.createPath(self.mediaObject, self.audio) Phonon.createPath(self.mediaObject, self.audio)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
self.videoStart)
self.webView = QtWebKit.QWebView(self) self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0, self.webView.setGeometry(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height()) self.screen[u'size'].width(), self.screen[u'size'].height())
self.page = self.webView.page() self.page = self.webView.page()
self.frame = self.page.mainFrame() self.frame = self.page.mainFrame()
QtCore.QObject.connect(self.webView, QtCore.QObject.connect(self.webView,
QtCore.SIGNAL(u'loadFinished(bool)'), self.isLoaded) QtCore.SIGNAL(u'loadFinished(bool)'), self.isWebLoaded)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical, self.frame.setScrollBarPolicy(QtCore.Qt.Vertical,
@ -137,14 +141,14 @@ class MainDisplay(DisplayWidget):
painter_image.begin(initialFrame) painter_image.begin(initialFrame)
painter_image.fillRect(initialFrame.rect(), QtCore.Qt.white) painter_image.fillRect(initialFrame.rect(), QtCore.Qt.white)
painter_image.drawImage( painter_image.drawImage(
(self.screens.current[u'size'].width() - (self.screens.current[u'size'].width() -
splash_image.width()) / 2, splash_image.width()) / 2,
(self.screens.current[u'size'].height() (self.screens.current[u'size'].height()
- splash_image.height()) / 2, splash_image) - splash_image.height()) / 2, splash_image)
serviceItem = ServiceItem() serviceItem = ServiceItem()
serviceItem.bg_image_bytes = image_to_byte(initialFrame) serviceItem.bg_image_bytes = image_to_byte(initialFrame)
self.webView.setHtml(build_html(serviceItem, self.screen, self.webView.setHtml(build_html(serviceItem, self.screen,
self.parent.alertTab, self.isLive)) self.alertTab, self.isLive, None))
self.initialFrame = True self.initialFrame = True
# To display or not to display? # To display or not to display?
if not self.screen[u'primary']: if not self.screen[u'primary']:
@ -162,7 +166,7 @@ class MainDisplay(DisplayWidget):
""" """
log.debug(u'text to display') log.debug(u'text to display')
# Wait for the webview to update before displaying text. # Wait for the webview to update before displaying text.
while not self.loaded: while not self.webLoaded:
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
self.frame.evaluateJavaScript(u'show_text("%s")' % \ self.frame.evaluateJavaScript(u'show_text("%s")' % \
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"')) slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
@ -204,14 +208,17 @@ class MainDisplay(DisplayWidget):
""" """
self.imageManager.add_image(name, path) self.imageManager.add_image(name, path)
self.image(name) self.image(name)
if hasattr(self, u'serviceItem'):
self.override[u'image'] = name
self.override[u'theme'] = self.serviceItem.themedata.theme_name
def image(self, name): def image(self, name):
""" """
Add an image as the background. The image is converted to a bytestream Add an image as the background. The image has already been added
on route. to the cache.
`Image` `Image`
The Image to be displayed can be QImage or QPixmap The name of the image to be displayed
""" """
log.debug(u'image to display') log.debug(u'image to display')
image = self.imageManager.get_image_bytes(name) image = self.imageManager.get_image_bytes(name)
@ -244,6 +251,7 @@ class MainDisplay(DisplayWidget):
self.displayImage(self.serviceItem.bg_image_bytes) self.displayImage(self.serviceItem.bg_image_bytes)
else: else:
self.displayImage(None) self.displayImage(None)
self.override = {}
# Update the preview frame. # Update the preview frame.
Receiver.send_message(u'maindisplay_active') Receiver.send_message(u'maindisplay_active')
@ -260,6 +268,7 @@ class MainDisplay(DisplayWidget):
self.phononActive = False self.phononActive = False
else: else:
self.frame.evaluateJavaScript(u'show_video("close");') self.frame.evaluateJavaScript(u'show_video("close");')
self.override = {}
# Update the preview frame. # Update the preview frame.
Receiver.send_message(u'maindisplay_active') Receiver.send_message(u'maindisplay_active')
@ -313,12 +322,14 @@ class MainDisplay(DisplayWidget):
Loads and starts a video to run with the option of sound Loads and starts a video to run with the option of sound
""" """
log.debug(u'video') log.debug(u'video')
self.loaded = True self.webLoaded = True
# We are running a background theme
self.override[u'theme'] = u''
self.override[u'video'] = True
vol = float(volume)/float(10) vol = float(volume)/float(10)
if isBackground or not self.usePhonon: if isBackground or not self.usePhonon:
js = u'show_video("init", "%s", %s, true); show_video("play");' % \ js = u'show_video("init", "%s", %s, true); show_video("play");' % \
(videoPath.replace(u'\\', u'\\\\'), \ (videoPath.replace(u'\\', u'\\\\'), str(vol))
str(vol))
self.frame.evaluateJavaScript(js) self.frame.evaluateJavaScript(js)
else: else:
self.phononActive = True self.phononActive = True
@ -333,12 +344,19 @@ class MainDisplay(DisplayWidget):
Receiver.send_message(u'maindisplay_active') Receiver.send_message(u'maindisplay_active')
return self.preview() return self.preview()
def isLoaded(self): def videoStart(self, newState, oldState):
"""
Start the video at a predetermined point.
"""
if newState == Phonon.PlayingState:
self.mediaObject.seek(self.serviceItem.start_time * 1000)
def isWebLoaded(self):
""" """
Called by webView event to show display is fully loaded Called by webView event to show display is fully loaded
""" """
log.debug(u'loaded') log.debug(u'Webloaded')
self.loaded = True self.webLoaded = True
def preview(self): def preview(self):
""" """
@ -357,7 +375,7 @@ class MainDisplay(DisplayWidget):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
# Wait for the webview to update before geting the preview. # Wait for the webview to update before geting the preview.
# Important otherwise first preview will miss the background ! # Important otherwise first preview will miss the background !
while not self.loaded: while not self.webLoaded:
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
# if was hidden keep it hidden # if was hidden keep it hidden
if self.isLive: if self.isLive:
@ -379,18 +397,31 @@ class MainDisplay(DisplayWidget):
HTML to the display HTML to the display
""" """
log.debug(u'buildHtml') log.debug(u'buildHtml')
self.loaded = False self.webLoaded = False
self.initialFrame = False self.initialFrame = False
self.serviceItem = serviceItem self.serviceItem = serviceItem
background = None
# We have an image override so keep the image till the theme changes
if self.override:
# We have an video override so allow it to be stopped
if u'video' in self.override:
Receiver.send_message(u'video_background_replaced')
self.override = {}
elif self.override[u'theme'] != serviceItem.themedata.theme_name:
Receiver.send_message(u'live_theme_changed')
self.override = {}
else:
background = self.imageManager. \
get_image_bytes(self.override[u'image'])
if self.serviceItem.themedata.background_filename: if self.serviceItem.themedata.background_filename:
self.serviceItem.bg_image_bytes = self.imageManager. \ self.serviceItem.bg_image_bytes = self.imageManager. \
get_image_bytes(self.serviceItem.themedata.theme_name) get_image_bytes(self.serviceItem.themedata.theme_name)
html = build_html(self.serviceItem, self.screen, self.parent.alertTab, html = build_html(self.serviceItem, self.screen, self.alertTab,
self.isLive) self.isLive, background)
log.debug(u'buildHtml - pre setHtml') log.debug(u'buildHtml - pre setHtml')
self.webView.setHtml(html) self.webView.setHtml(html)
log.debug(u'buildHtml - post setHtml') log.debug(u'buildHtml - post setHtml')
if serviceItem.foot_text and serviceItem.foot_text: if 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.hideMode and self.isLive: if self.hideMode and self.isLive:

View File

@ -28,11 +28,13 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
icon_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ThemeManager, SlideController, PluginForm, MediaDockManager, \ ThemeManager, SlideController, PluginForm, MediaDockManager, \
ShortcutListForm ShortcutListForm
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate
from openlp.core.utils import AppLocation, add_actions, LanguageManager, \ from openlp.core.utils import AppLocation, add_actions, LanguageManager, \
ActionList ActionList
@ -76,10 +78,10 @@ class Ui_MainWindow(object):
self.MainContentLayout.setMargin(0) self.MainContentLayout.setMargin(0)
self.MainContentLayout.setObjectName(u'MainContentLayout') self.MainContentLayout.setObjectName(u'MainContentLayout')
mainWindow.setCentralWidget(self.MainContent) mainWindow.setCentralWidget(self.MainContent)
self.ControlSplitter = QtGui.QSplitter(self.MainContent) self.controlSplitter = QtGui.QSplitter(self.MainContent)
self.ControlSplitter.setOrientation(QtCore.Qt.Horizontal) self.controlSplitter.setOrientation(QtCore.Qt.Horizontal)
self.ControlSplitter.setObjectName(u'ControlSplitter') self.controlSplitter.setObjectName(u'controlSplitter')
self.MainContentLayout.addWidget(self.ControlSplitter) self.MainContentLayout.addWidget(self.controlSplitter)
# Create slide controllers # Create slide controllers
self.previewController = SlideController(self, self.settingsmanager, self.previewController = SlideController(self, self.settingsmanager,
self.screens) self.screens)
@ -87,10 +89,10 @@ class Ui_MainWindow(object):
self.screens, True) self.screens, True)
previewVisible = QtCore.QSettings().value( previewVisible = QtCore.QSettings().value(
u'user interface/preview panel', QtCore.QVariant(True)).toBool() u'user interface/preview panel', QtCore.QVariant(True)).toBool()
self.previewController.Panel.setVisible(previewVisible) self.previewController.panel.setVisible(previewVisible)
liveVisible = QtCore.QSettings().value(u'user interface/live panel', liveVisible = QtCore.QSettings().value(u'user interface/live panel',
QtCore.QVariant(True)).toBool() QtCore.QVariant(True)).toBool()
self.liveController.Panel.setVisible(liveVisible) self.liveController.panel.setVisible(liveVisible)
# Create menu # Create menu
self.MenuBar = QtGui.QMenuBar(mainWindow) self.MenuBar = QtGui.QMenuBar(mainWindow)
self.MenuBar.setObjectName(u'MenuBar') self.MenuBar.setObjectName(u'MenuBar')
@ -101,9 +103,9 @@ class Ui_MainWindow(object):
self.FileExportMenu = QtGui.QMenu(self.FileMenu) self.FileExportMenu = QtGui.QMenu(self.FileMenu)
self.FileExportMenu.setObjectName(u'FileExportMenu') self.FileExportMenu.setObjectName(u'FileExportMenu')
# View Menu # View Menu
self.ViewMenu = QtGui.QMenu(self.MenuBar) self.viewMenu = QtGui.QMenu(self.MenuBar)
self.ViewMenu.setObjectName(u'ViewMenu') self.viewMenu.setObjectName(u'viewMenu')
self.ViewModeMenu = QtGui.QMenu(self.ViewMenu) self.ViewModeMenu = QtGui.QMenu(self.viewMenu)
self.ViewModeMenu.setObjectName(u'ViewModeMenu') self.ViewModeMenu.setObjectName(u'ViewModeMenu')
# Tools Menu # Tools Menu
self.ToolsMenu = QtGui.QMenu(self.MenuBar) self.ToolsMenu = QtGui.QMenu(self.MenuBar)
@ -124,135 +126,106 @@ class Ui_MainWindow(object):
self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel') self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel')
self.StatusBar.addPermanentWidget(self.DefaultThemeLabel) self.StatusBar.addPermanentWidget(self.DefaultThemeLabel)
# Create the MediaManager # Create the MediaManager
self.MediaManagerDock = OpenLPDockWidget( self.mediaManagerDock = OpenLPDockWidget(mainWindow,
mainWindow, u'MediaManagerDock', u'mediaManagerDock', u':/system/system_mediamanager.png')
build_icon(u':/system/system_mediamanager.png')) self.mediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE)
self.MediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE) self.mediaManagerDock.setMinimumWidth(
self.MediaManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_left) self.settingsmanager.mainwindow_left)
# Create the media toolbox # Create the media toolbox
self.MediaToolBox = QtGui.QToolBox(self.MediaManagerDock) self.MediaToolBox = QtGui.QToolBox(self.mediaManagerDock)
self.MediaToolBox.setObjectName(u'MediaToolBox') self.MediaToolBox.setObjectName(u'MediaToolBox')
self.MediaManagerDock.setWidget(self.MediaToolBox) self.mediaManagerDock.setWidget(self.MediaToolBox)
mainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea, mainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea,
self.MediaManagerDock) self.mediaManagerDock)
# Create the service manager # Create the service manager
self.ServiceManagerDock = OpenLPDockWidget( self.serviceManagerDock = OpenLPDockWidget(mainWindow,
mainWindow, u'ServiceManagerDock', u'serviceManagerDock', u':/system/system_servicemanager.png')
build_icon(u':/system/system_servicemanager.png')) self.serviceManagerDock.setMinimumWidth(
self.ServiceManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right) self.settingsmanager.mainwindow_right)
self.ServiceManagerContents = ServiceManager(mainWindow, self.ServiceManagerContents = ServiceManager(mainWindow,
self.ServiceManagerDock) self.serviceManagerDock)
self.ServiceManagerDock.setWidget(self.ServiceManagerContents) self.serviceManagerDock.setWidget(self.ServiceManagerContents)
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self.ServiceManagerDock) self.serviceManagerDock)
# Create the theme manager # Create the theme manager
self.ThemeManagerDock = OpenLPDockWidget( self.themeManagerDock = OpenLPDockWidget(mainWindow,
mainWindow, u'ThemeManagerDock', u'themeManagerDock', u':/system/system_thememanager.png')
build_icon(u':/system/system_thememanager.png')) self.themeManagerDock.setMinimumWidth(
self.ThemeManagerDock.setMinimumWidth(
self.settingsmanager.mainwindow_right) self.settingsmanager.mainwindow_right)
self.ThemeManagerContents = ThemeManager(mainWindow, self.ThemeManagerContents = ThemeManager(mainWindow,
self.ThemeManagerDock) self.themeManagerDock)
self.ThemeManagerContents.setObjectName(u'ThemeManagerContents') self.ThemeManagerContents.setObjectName(u'ThemeManagerContents')
self.ThemeManagerDock.setWidget(self.ThemeManagerContents) self.themeManagerDock.setWidget(self.ThemeManagerContents)
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
self.ThemeManagerDock) self.themeManagerDock)
# Create the menu items # Create the menu items
self.FileNewItem = QtGui.QAction(mainWindow) self.FileNewItem = icon_action(mainWindow, u'FileNewItem',
self.FileNewItem.setIcon(build_icon(u':/general/general_new.png')) u':/general/general_new.png')
self.FileNewItem.setObjectName(u'FileNewItem')
mainWindow.actionList.add_action(self.FileNewItem, u'File') mainWindow.actionList.add_action(self.FileNewItem, u'File')
self.FileOpenItem = QtGui.QAction(mainWindow) self.FileOpenItem = icon_action(mainWindow, u'FileOpenItem',
self.FileOpenItem.setIcon(build_icon(u':/general/general_open.png')) u':/general/general_open.png')
self.FileOpenItem.setObjectName(u'FileOpenItem')
mainWindow.actionList.add_action(self.FileOpenItem, u'File') mainWindow.actionList.add_action(self.FileOpenItem, u'File')
self.FileSaveItem = QtGui.QAction(mainWindow) self.FileSaveItem = icon_action(mainWindow, u'FileSaveItem',
self.FileSaveItem.setIcon(build_icon(u':/general/general_save.png')) u':/general/general_save.png')
self.FileSaveItem.setObjectName(u'FileSaveItem')
mainWindow.actionList.add_action(self.FileSaveItem, u'File') mainWindow.actionList.add_action(self.FileSaveItem, u'File')
self.FileSaveAsItem = QtGui.QAction(mainWindow) self.FileSaveAsItem = base_action(mainWindow, u'FileSaveAsItem')
self.FileSaveAsItem.setObjectName(u'FileSaveAsItem')
mainWindow.actionList.add_action(self.FileSaveAsItem, u'File') mainWindow.actionList.add_action(self.FileSaveAsItem, u'File')
self.FileExitItem = QtGui.QAction(mainWindow) self.printServiceOrderItem = base_action(
self.FileExitItem.setIcon(build_icon(u':/system/system_exit.png')) mainWindow, u'printServiceItem')
self.FileExitItem.setObjectName(u'FileExitItem') mainWindow.actionList.add_action(
self.printServiceOrderItem, u'Print Service Order')
self.FileExitItem = icon_action(mainWindow, u'FileExitItem',
u':/system/system_exit.png')
mainWindow.actionList.add_action(self.FileExitItem, u'File') mainWindow.actionList.add_action(self.FileExitItem, u'File')
self.ImportThemeItem = QtGui.QAction(mainWindow) self.ImportThemeItem = base_action(mainWindow, u'ImportThemeItem')
self.ImportThemeItem.setObjectName(u'ImportThemeItem')
mainWindow.actionList.add_action(self.ImportThemeItem, u'Import') mainWindow.actionList.add_action(self.ImportThemeItem, u'Import')
self.ImportLanguageItem = QtGui.QAction(mainWindow) self.ImportLanguageItem = base_action(mainWindow, u'ImportLanguageItem')
self.ImportLanguageItem.setObjectName(u'ImportLanguageItem')
mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import') mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import')
self.ExportThemeItem = QtGui.QAction(mainWindow) self.ExportThemeItem = base_action(mainWindow, u'ExportThemeItem')
self.ExportThemeItem.setObjectName(u'ExportThemeItem')
mainWindow.actionList.add_action(self.ExportThemeItem, u'Export') mainWindow.actionList.add_action(self.ExportThemeItem, u'Export')
self.ExportLanguageItem = QtGui.QAction(mainWindow) self.ExportLanguageItem = base_action(mainWindow, u'ExportLanguageItem')
self.ExportLanguageItem.setObjectName(u'ExportLanguageItem')
mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export') mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export')
self.ViewMediaManagerItem = QtGui.QAction(mainWindow) self.ViewMediaManagerItem = icon_action(mainWindow,
self.ViewMediaManagerItem.setCheckable(True) u'ViewMediaManagerItem', u':/system/system_mediamanager.png',
self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible()) self.mediaManagerDock.isVisible())
self.ViewMediaManagerItem.setIcon( self.ViewThemeManagerItem = icon_action(mainWindow,
build_icon(u':/system/system_mediamanager.png')) u'ViewThemeManagerItem', u':/system/system_thememanager.png',
self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem') self.themeManagerDock.isVisible())
self.ViewThemeManagerItem = QtGui.QAction(mainWindow)
self.ViewThemeManagerItem.setCheckable(True)
self.ViewThemeManagerItem.setChecked(self.ThemeManagerDock.isVisible())
self.ViewThemeManagerItem.setIcon(
build_icon(u':/system/system_thememanager.png'))
self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem')
mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View') mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View')
self.ViewServiceManagerItem = QtGui.QAction(mainWindow) self.ViewServiceManagerItem = icon_action(mainWindow,
self.ViewServiceManagerItem.setCheckable(True) u'ViewServiceManagerItem', u':/system/system_servicemanager.png',
self.ViewServiceManagerItem.setChecked( self.serviceManagerDock.isVisible())
self.ServiceManagerDock.isVisible())
self.ViewServiceManagerItem.setIcon(
build_icon(u':/system/system_servicemanager.png'))
self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem')
mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View') mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View')
self.ViewPreviewPanel = QtGui.QAction(mainWindow) self.ViewPreviewPanel = checkable_action(mainWindow,
self.ViewPreviewPanel.setCheckable(True) u'ViewPreviewPanel', previewVisible)
self.ViewPreviewPanel.setChecked(previewVisible)
self.ViewPreviewPanel.setObjectName(u'ViewPreviewPanel')
mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View') mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View')
self.ViewLivePanel = QtGui.QAction(mainWindow) self.ViewLivePanel = checkable_action(mainWindow, u'ViewLivePanel',
self.ViewLivePanel.setCheckable(True) liveVisible)
self.ViewLivePanel.setChecked(liveVisible)
self.ViewLivePanel.setObjectName(u'ViewLivePanel')
mainWindow.actionList.add_action(self.ViewLivePanel, u'View') mainWindow.actionList.add_action(self.ViewLivePanel, u'View')
self.ModeDefaultItem = QtGui.QAction(mainWindow) self.ModeDefaultItem = checkable_action(mainWindow, u'ModeDefaultItem')
self.ModeDefaultItem.setCheckable(True)
self.ModeDefaultItem.setObjectName(u'ModeDefaultItem')
mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode') mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode')
self.ModeSetupItem = QtGui.QAction(mainWindow) self.ModeSetupItem = checkable_action(mainWindow, u'ModeLiveItem')
self.ModeSetupItem.setCheckable(True)
self.ModeSetupItem.setObjectName(u'ModeLiveItem')
mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode') mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode')
self.ModeLiveItem = QtGui.QAction(mainWindow) self.ModeLiveItem = checkable_action(mainWindow, u'ModeLiveItem')
self.ModeLiveItem.setCheckable(True)
self.ModeLiveItem.setObjectName(u'ModeLiveItem')
mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode') mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode')
self.ModeGroup = QtGui.QActionGroup(mainWindow) self.ModeGroup = QtGui.QActionGroup(mainWindow)
self.ModeGroup.addAction(self.ModeDefaultItem) self.ModeGroup.addAction(self.ModeDefaultItem)
self.ModeGroup.addAction(self.ModeSetupItem) self.ModeGroup.addAction(self.ModeSetupItem)
self.ModeGroup.addAction(self.ModeLiveItem) self.ModeGroup.addAction(self.ModeLiveItem)
self.ModeDefaultItem.setChecked(True) self.ModeDefaultItem.setChecked(True)
self.ToolsAddToolItem = QtGui.QAction(mainWindow) self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png')) u':/tools/tools_add.png')
self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem')
mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools') mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools')
self.SettingsPluginListItem = QtGui.QAction(mainWindow) self.ToolsOpenDataFolder = icon_action(mainWindow,
self.SettingsPluginListItem.setIcon( u'ToolsOpenDataFolder', u':/general/general_open.png')
build_icon(u':/system/settings_plugin_list.png')) mainWindow.actionList.add_action(self.ToolsOpenDataFolder, u'Tools')
self.SettingsPluginListItem.setObjectName(u'SettingsPluginListItem') self.settingsPluginListItem = icon_action(mainWindow,
mainWindow.actionList.add_action(self.SettingsPluginListItem, u'settingsPluginListItem', u':/system/settings_plugin_list.png')
mainWindow.actionList.add_action(self.settingsPluginListItem,
u'Settings') u'Settings')
# i18n Language Items # i18n Language Items
self.AutoLanguageItem = QtGui.QAction(mainWindow) self.AutoLanguageItem = checkable_action(mainWindow,
self.AutoLanguageItem.setObjectName(u'AutoLanguageItem') u'AutoLanguageItem')
self.AutoLanguageItem.setCheckable(True)
mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings') mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings')
self.LanguageGroup = QtGui.QActionGroup(mainWindow) self.LanguageGroup = QtGui.QActionGroup(mainWindow)
self.LanguageGroup.setExclusive(True) self.LanguageGroup.setExclusive(True)
@ -262,39 +235,28 @@ class Ui_MainWindow(object):
qmList = LanguageManager.get_qm_list() qmList = LanguageManager.get_qm_list()
savedLanguage = LanguageManager.get_language() savedLanguage = LanguageManager.get_language()
for key in sorted(qmList.keys()): for key in sorted(qmList.keys()):
languageItem = QtGui.QAction(mainWindow) languageItem = checkable_action(mainWindow, key)
languageItem.setObjectName(key)
languageItem.setCheckable(True)
if qmList[key] == savedLanguage: if qmList[key] == savedLanguage:
languageItem.setChecked(True) languageItem.setChecked(True)
add_actions(self.LanguageGroup, [languageItem]) add_actions(self.LanguageGroup, [languageItem])
self.SettingsShortcutsItem = QtGui.QAction(mainWindow) self.SettingsShortcutsItem = icon_action(mainWindow,
self.SettingsShortcutsItem.setIcon( u'SettingsShortcutsItem',
build_icon(u':/system/system_configure_shortcuts.png')) u':/system/system_configure_shortcuts.png')
self.SettingsShortcutsItem.setObjectName(u'SettingsShortcutsItem') self.SettingsConfigureItem = icon_action(mainWindow,
self.SettingsConfigureItem = QtGui.QAction(mainWindow) u'SettingsConfigureItem', u':/system/system_settings.png')
self.SettingsConfigureItem.setIcon(
build_icon(u':/system/system_settings.png'))
self.SettingsConfigureItem.setObjectName(u'SettingsConfigureItem')
mainWindow.actionList.add_action(self.SettingsShortcutsItem, mainWindow.actionList.add_action(self.SettingsShortcutsItem,
u'Settings') u'Settings')
self.HelpDocumentationItem = QtGui.QAction(mainWindow) self.HelpDocumentationItem = icon_action(mainWindow,
self.HelpDocumentationItem.setIcon( u'HelpDocumentationItem', u':/system/system_help_contents.png')
build_icon(u':/system/system_help_contents.png'))
self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem')
self.HelpDocumentationItem.setEnabled(False) self.HelpDocumentationItem.setEnabled(False)
mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help') mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help')
self.HelpAboutItem = QtGui.QAction(mainWindow) self.HelpAboutItem = icon_action(mainWindow, u'HelpAboutItem',
self.HelpAboutItem.setIcon( u':/system/system_about.png')
build_icon(u':/system/system_about.png'))
self.HelpAboutItem.setObjectName(u'HelpAboutItem')
mainWindow.actionList.add_action(self.HelpAboutItem, u'Help') mainWindow.actionList.add_action(self.HelpAboutItem, u'Help')
self.HelpOnlineHelpItem = QtGui.QAction(mainWindow) self.HelpOnlineHelpItem = base_action(mainWindow, u'HelpOnlineHelpItem')
self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem')
self.HelpOnlineHelpItem.setEnabled(False) self.HelpOnlineHelpItem.setEnabled(False)
mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help') mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help')
self.HelpWebSiteItem = QtGui.QAction(mainWindow) self.HelpWebSiteItem = base_action(mainWindow, u'HelpWebSiteItem')
self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem')
mainWindow.actionList.add_action(self.HelpWebSiteItem, u'Help') mainWindow.actionList.add_action(self.HelpWebSiteItem, u'Help')
add_actions(self.FileImportMenu, add_actions(self.FileImportMenu,
(self.ImportThemeItem, self.ImportLanguageItem)) (self.ImportThemeItem, self.ImportLanguageItem))
@ -302,26 +264,27 @@ class Ui_MainWindow(object):
(self.ExportThemeItem, self.ExportLanguageItem)) (self.ExportThemeItem, self.ExportLanguageItem))
self.FileMenuActions = (self.FileNewItem, self.FileOpenItem, self.FileMenuActions = (self.FileNewItem, self.FileOpenItem,
self.FileSaveItem, self.FileSaveAsItem, None, self.FileSaveItem, self.FileSaveAsItem, None,
self.FileImportMenu.menuAction(), self.FileExportMenu.menuAction(), self.printServiceOrderItem, None, self.FileImportMenu.menuAction(),
self.FileExitItem) self.FileExportMenu.menuAction(), self.FileExitItem)
add_actions(self.ViewModeMenu, (self.ModeDefaultItem, add_actions(self.ViewModeMenu, (self.ModeDefaultItem,
self.ModeSetupItem, self.ModeLiveItem)) self.ModeSetupItem, self.ModeLiveItem))
add_actions(self.ViewMenu, (self.ViewModeMenu.menuAction(), add_actions(self.viewMenu, (self.ViewModeMenu.menuAction(),
None, self.ViewMediaManagerItem, self.ViewServiceManagerItem, None, self.ViewMediaManagerItem, self.ViewServiceManagerItem,
self.ViewThemeManagerItem, None, self.ViewPreviewPanel, self.ViewThemeManagerItem, None, self.ViewPreviewPanel,
self.ViewLivePanel)) self.ViewLivePanel))
# i18n add Language Actions # i18n add Language Actions
add_actions(self.SettingsLanguageMenu, (self.AutoLanguageItem, None)) add_actions(self.SettingsLanguageMenu, (self.AutoLanguageItem, None))
add_actions(self.SettingsLanguageMenu, self.LanguageGroup.actions()) add_actions(self.SettingsLanguageMenu, self.LanguageGroup.actions())
add_actions(self.SettingsMenu, (self.SettingsPluginListItem, add_actions(self.SettingsMenu, (self.settingsPluginListItem,
self.SettingsLanguageMenu.menuAction(), None, self.SettingsLanguageMenu.menuAction(), None,
self.SettingsShortcutsItem, self.SettingsConfigureItem)) self.SettingsShortcutsItem, self.SettingsConfigureItem))
add_actions(self.ToolsMenu, (self.ToolsAddToolItem, None)) add_actions(self.ToolsMenu, (self.ToolsAddToolItem, None))
add_actions(self.ToolsMenu, (self.ToolsOpenDataFolder, None))
add_actions(self.HelpMenu, (self.HelpDocumentationItem, add_actions(self.HelpMenu, (self.HelpDocumentationItem,
self.HelpOnlineHelpItem, None, self.HelpWebSiteItem, self.HelpOnlineHelpItem, None, self.HelpWebSiteItem,
self.HelpAboutItem)) self.HelpAboutItem))
add_actions(self.MenuBar, (self.FileMenu.menuAction(), add_actions(self.MenuBar, (self.FileMenu.menuAction(),
self.ViewMenu.menuAction(), self.ToolsMenu.menuAction(), self.viewMenu.menuAction(), self.ToolsMenu.menuAction(),
self.SettingsMenu.menuAction(), self.HelpMenu.menuAction())) self.SettingsMenu.menuAction(), self.HelpMenu.menuAction()))
# Initialise the translation # Initialise the translation
self.retranslateUi(mainWindow) self.retranslateUi(mainWindow)
@ -337,39 +300,35 @@ class Ui_MainWindow(object):
""" """
Set up the translation system Set up the translation system
""" """
mainWindow.mainTitle = translate('OpenLP.MainWindow', 'OpenLP 2.0') mainWindow.mainTitle = UiStrings.OLPV2
mainWindow.setWindowTitle(mainWindow.mainTitle) mainWindow.setWindowTitle(mainWindow.mainTitle)
self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File')) self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import')) self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
self.FileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export')) self.FileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export'))
self.ViewMenu.setTitle(translate('OpenLP.MainWindow', '&View')) self.viewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
self.ViewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode')) self.ViewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
self.ToolsMenu.setTitle(translate('OpenLP.MainWindow', '&Tools')) self.ToolsMenu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
self.SettingsMenu.setTitle(translate('OpenLP.MainWindow', '&Settings')) self.SettingsMenu.setTitle(translate('OpenLP.MainWindow', '&Settings'))
self.SettingsLanguageMenu.setTitle(translate('OpenLP.MainWindow', self.SettingsLanguageMenu.setTitle(translate('OpenLP.MainWindow',
'&Language')) '&Language'))
self.HelpMenu.setTitle(translate('OpenLP.MainWindow', '&Help')) self.HelpMenu.setTitle(translate('OpenLP.MainWindow', '&Help'))
self.MediaManagerDock.setWindowTitle( self.mediaManagerDock.setWindowTitle(
translate('OpenLP.MainWindow', 'Media Manager')) translate('OpenLP.MainWindow', 'Media Manager'))
self.ServiceManagerDock.setWindowTitle( self.serviceManagerDock.setWindowTitle(
translate('OpenLP.MainWindow', 'Service Manager')) translate('OpenLP.MainWindow', 'Service Manager'))
self.ThemeManagerDock.setWindowTitle( self.themeManagerDock.setWindowTitle(
translate('OpenLP.MainWindow', 'Theme Manager')) translate('OpenLP.MainWindow', 'Theme Manager'))
self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New')) self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New'))
self.FileNewItem.setToolTip( self.FileNewItem.setToolTip(UiStrings.NewService)
translate('OpenLP.MainWindow', 'New Service')) self.FileNewItem.setStatusTip(UiStrings.CreateService)
self.FileNewItem.setStatusTip(
translate('OpenLP.MainWindow', 'Create a new service.'))
self.FileNewItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+N')) self.FileNewItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+N'))
self.FileOpenItem.setText(translate('OpenLP.MainWindow', '&Open')) self.FileOpenItem.setText(translate('OpenLP.MainWindow', '&Open'))
self.FileOpenItem.setToolTip( self.FileOpenItem.setToolTip(UiStrings.OpenService)
translate('OpenLP.MainWindow', 'Open Service'))
self.FileOpenItem.setStatusTip( self.FileOpenItem.setStatusTip(
translate('OpenLP.MainWindow', 'Open an existing service.')) translate('OpenLP.MainWindow', 'Open an existing service.'))
self.FileOpenItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+O')) self.FileOpenItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+O'))
self.FileSaveItem.setText(translate('OpenLP.MainWindow', '&Save')) self.FileSaveItem.setText(translate('OpenLP.MainWindow', '&Save'))
self.FileSaveItem.setToolTip( self.FileSaveItem.setToolTip(UiStrings.SaveService)
translate('OpenLP.MainWindow', 'Save Service'))
self.FileSaveItem.setStatusTip( self.FileSaveItem.setStatusTip(
translate('OpenLP.MainWindow', 'Save the current service to disk.')) translate('OpenLP.MainWindow', 'Save the current service to disk.'))
self.FileSaveItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+S')) self.FileSaveItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+S'))
@ -381,6 +340,12 @@ class Ui_MainWindow(object):
'Save the current service under a new name.')) 'Save the current service under a new name.'))
self.FileSaveAsItem.setShortcut( self.FileSaveAsItem.setShortcut(
translate('OpenLP.MainWindow', 'Ctrl+Shift+S')) translate('OpenLP.MainWindow', 'Ctrl+Shift+S'))
self.printServiceOrderItem.setText(
translate('OpenLP.MainWindow', 'Print Service Order'))
self.printServiceOrderItem.setStatusTip(translate('OpenLP.MainWindow',
'Print the current Service Order.'))
self.printServiceOrderItem.setShortcut(
translate('OpenLP.MainWindow', 'Ctrl+P'))
self.FileExitItem.setText( self.FileExitItem.setText(
translate('OpenLP.MainWindow', 'E&xit')) translate('OpenLP.MainWindow', 'E&xit'))
self.FileExitItem.setStatusTip( self.FileExitItem.setStatusTip(
@ -439,11 +404,11 @@ class Ui_MainWindow(object):
'Toggle the visibility of the live panel.')) 'Toggle the visibility of the live panel.'))
self.ViewLivePanel.setShortcut( self.ViewLivePanel.setShortcut(
translate('OpenLP.MainWindow', 'F12')) translate('OpenLP.MainWindow', 'F12'))
self.SettingsPluginListItem.setText(translate('OpenLP.MainWindow', self.settingsPluginListItem.setText(translate('OpenLP.MainWindow',
'&Plugin List')) '&Plugin List'))
self.SettingsPluginListItem.setStatusTip( self.settingsPluginListItem.setStatusTip(
translate('OpenLP.MainWindow', 'List the Plugins')) translate('OpenLP.MainWindow', 'List the Plugins'))
self.SettingsPluginListItem.setShortcut( self.settingsPluginListItem.setShortcut(
translate('OpenLP.MainWindow', 'Alt+F7')) translate('OpenLP.MainWindow', 'Alt+F7'))
self.HelpDocumentationItem.setText( self.HelpDocumentationItem.setText(
translate('OpenLP.MainWindow', '&User Guide')) translate('OpenLP.MainWindow', '&User Guide'))
@ -468,6 +433,10 @@ class Ui_MainWindow(object):
translate('OpenLP.MainWindow', 'Add &Tool...')) translate('OpenLP.MainWindow', 'Add &Tool...'))
self.ToolsAddToolItem.setStatusTip(translate('OpenLP.MainWindow', self.ToolsAddToolItem.setStatusTip(translate('OpenLP.MainWindow',
'Add an application to the list of tools.')) 'Add an application to the list of tools.'))
self.ToolsOpenDataFolder.setText(
translate('OpenLP.MainWindow', 'Open &Data Folder...'))
self.ToolsOpenDataFolder.setStatusTip(translate('OpenLP.MainWindow',
'Open the folder where songs, bibles and other data resides.'))
self.ModeDefaultItem.setText( self.ModeDefaultItem.setText(
translate('OpenLP.MainWindow', '&Default')) translate('OpenLP.MainWindow', '&Default'))
self.ModeDefaultItem.setStatusTip(translate('OpenLP.MainWindow', self.ModeDefaultItem.setStatusTip(translate('OpenLP.MainWindow',
@ -537,20 +506,22 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'toggled(bool)'), self.setPreviewPanelVisibility) QtCore.SIGNAL(u'toggled(bool)'), self.setPreviewPanelVisibility)
QtCore.QObject.connect(self.ViewLivePanel, QtCore.QObject.connect(self.ViewLivePanel,
QtCore.SIGNAL(u'toggled(bool)'), self.setLivePanelVisibility) QtCore.SIGNAL(u'toggled(bool)'), self.setLivePanelVisibility)
QtCore.QObject.connect(self.MediaManagerDock, QtCore.QObject.connect(self.mediaManagerDock,
QtCore.SIGNAL(u'visibilityChanged(bool)'), QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.ViewMediaManagerItem.setChecked) self.ViewMediaManagerItem.setChecked)
QtCore.QObject.connect(self.ServiceManagerDock, QtCore.QObject.connect(self.serviceManagerDock,
QtCore.SIGNAL(u'visibilityChanged(bool)'), QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.ViewServiceManagerItem.setChecked) self.ViewServiceManagerItem.setChecked)
QtCore.QObject.connect(self.ThemeManagerDock, QtCore.QObject.connect(self.themeManagerDock,
QtCore.SIGNAL(u'visibilityChanged(bool)'), QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.ViewThemeManagerItem.setChecked) self.ViewThemeManagerItem.setChecked)
QtCore.QObject.connect(self.HelpWebSiteItem, QtCore.QObject.connect(self.HelpWebSiteItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked) QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
QtCore.QObject.connect(self.HelpAboutItem, QtCore.QObject.connect(self.HelpAboutItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked) QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked)
QtCore.QObject.connect(self.SettingsPluginListItem, QtCore.QObject.connect(self.ToolsOpenDataFolder,
QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked)
QtCore.QObject.connect(self.settingsPluginListItem,
QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked) QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked)
QtCore.QObject.connect(self.SettingsConfigureItem, QtCore.QObject.connect(self.SettingsConfigureItem,
QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked) QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
@ -563,10 +534,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.ServiceManagerContents.onLoadServiceClicked) self.ServiceManagerContents.onLoadServiceClicked)
QtCore.QObject.connect(self.FileSaveItem, QtCore.QObject.connect(self.FileSaveItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onSaveServiceClicked) self.ServiceManagerContents.saveFile)
QtCore.QObject.connect(self.FileSaveAsItem, QtCore.QObject.connect(self.FileSaveAsItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onSaveServiceAsClicked) self.ServiceManagerContents.saveFileAs)
QtCore.QObject.connect(self.printServiceOrderItem,
QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.printServiceOrder)
# i18n set signals for languages # i18n set signals for languages
QtCore.QObject.connect(self.AutoLanguageItem, QtCore.QObject.connect(self.AutoLanguageItem,
QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage) QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage)
@ -735,6 +709,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.pluginForm.load() self.pluginForm.load()
self.pluginForm.exec_() self.pluginForm.exec_()
def onToolsOpenDataFolderClicked(self):
"""
Open data folder
"""
path = AppLocation.get_data_path()
QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + path))
def onSettingsConfigureItemClicked(self): def onSettingsConfigureItemClicked(self):
""" """
Show the Settings dialog Show the Settings dialog
@ -758,37 +739,32 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
""" """
Put OpenLP into "Default" view mode. Put OpenLP into "Default" view mode.
""" """
settings = QtCore.QSettings() self.setViewMode(True, True, True, True, True, u'default')
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'default')
self.setViewMode(True, True, True, True, True)
def onModeSetupItemClicked(self): def onModeSetupItemClicked(self):
""" """
Put OpenLP into "Setup" view mode. Put OpenLP into "Setup" view mode.
""" """
settings = QtCore.QSettings() self.setViewMode(True, True, False, True, False, u'setup')
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'setup')
self.setViewMode(True, True, False, True, False)
def onModeLiveItemClicked(self): def onModeLiveItemClicked(self):
""" """
Put OpenLP into "Live" view mode. Put OpenLP into "Live" view mode.
""" """
settings = QtCore.QSettings() self.setViewMode(False, True, False, False, True, u'live')
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
u'live')
self.setViewMode(False, True, False, False, True)
def setViewMode(self, media=True, service=True, theme=True, preview=True, def setViewMode(self, media=True, service=True, theme=True, preview=True,
live=True): live=True, mode=u''):
""" """
Set OpenLP to a different view mode. Set OpenLP to a different view mode.
""" """
self.MediaManagerDock.setVisible(media) if mode:
self.ServiceManagerDock.setVisible(service) settings = QtCore.QSettings()
self.ThemeManagerDock.setVisible(theme) settings.setValue(u'%s/view mode' % self.generalSettingsSection,
mode)
self.mediaManagerDock.setVisible(media)
self.serviceManagerDock.setVisible(service)
self.themeManagerDock.setVisible(theme)
self.setPreviewPanelVisibility(preview) self.setPreviewPanelVisibility(preview)
self.setLivePanelVisibility(live) self.setLivePanelVisibility(live)
@ -807,15 +783,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Hook to close the main window and display windows on exit Hook to close the main window and display windows on exit
""" """
if self.ServiceManagerContents.isModified(): if self.ServiceManagerContents.isModified():
ret = QtGui.QMessageBox.question(self, ret = self.ServiceManagerContents.saveModifiedService()
translate('OpenLP.MainWindow', 'Save Changes to Service?'),
translate('OpenLP.MainWindow', 'Your service has changed. '
'Do you want to save those changes?'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Cancel |
QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Save),
QtGui.QMessageBox.Save)
if ret == QtGui.QMessageBox.Save: if ret == QtGui.QMessageBox.Save:
if self.ServiceManagerContents.saveFile(): if self.ServiceManagerContents.saveFile():
self.cleanUp() self.cleanUp()
@ -847,7 +815,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.cleanUp() self.cleanUp()
event.accept() event.accept()
def cleanUp(self): def cleanUp(self):
""" """
Runs all the cleanup code before OpenLP shuts down Runs all the cleanup code before OpenLP shuts down
@ -914,16 +881,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
theme) theme)
def toggleMediaManager(self, visible): def toggleMediaManager(self, visible):
if self.MediaManagerDock.isVisible() != visible: if self.mediaManagerDock.isVisible() != visible:
self.MediaManagerDock.setVisible(visible) self.mediaManagerDock.setVisible(visible)
def toggleServiceManager(self, visible): def toggleServiceManager(self, visible):
if self.ServiceManagerDock.isVisible() != visible: if self.serviceManagerDock.isVisible() != visible:
self.ServiceManagerDock.setVisible(visible) self.serviceManagerDock.setVisible(visible)
def toggleThemeManager(self, visible): def toggleThemeManager(self, visible):
if self.ThemeManagerDock.isVisible() != visible: if self.themeManagerDock.isVisible() != visible:
self.ThemeManagerDock.setVisible(visible) self.themeManagerDock.setVisible(visible)
def setPreviewPanelVisibility(self, visible): def setPreviewPanelVisibility(self, visible):
""" """
@ -935,7 +902,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
True - Visible True - Visible
False - Hidden False - Hidden
""" """
self.previewController.Panel.setVisible(visible) self.previewController.panel.setVisible(visible)
QtCore.QSettings().setValue(u'user interface/preview panel', QtCore.QSettings().setValue(u'user interface/preview panel',
QtCore.QVariant(visible)) QtCore.QVariant(visible))
self.ViewPreviewPanel.setChecked(visible) self.ViewPreviewPanel.setChecked(visible)
@ -950,7 +917,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
True - Visible True - Visible
False - Hidden False - Hidden
""" """
self.liveController.Panel.setVisible(visible) self.liveController.panel.setVisible(visible)
QtCore.QSettings().setValue(u'user interface/live panel', QtCore.QSettings().setValue(u'user interface/live panel',
QtCore.QVariant(visible)) QtCore.QVariant(visible))
self.ViewLivePanel.setChecked(visible) self.ViewLivePanel.setChecked(visible)
@ -1000,8 +967,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0] u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
self.FileMenu.clear() self.FileMenu.clear()
add_actions(self.FileMenu, self.FileMenuActions[:-1]) add_actions(self.FileMenu, self.FileMenuActions[:-1])
existingRecentFiles = [file for file in self.recentFiles existingRecentFiles = [recentFile for recentFile in self.recentFiles
if QtCore.QFile.exists(file)] if QtCore.QFile.exists(recentFile)]
recentFilesToDisplay = existingRecentFiles[0:recentFileCount] recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
if recentFilesToDisplay: if recentFilesToDisplay:
self.FileMenu.addSeparator() self.FileMenu.addSeparator()

View File

@ -28,13 +28,15 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import PluginStatus, StringContent, translate from openlp.core.lib import PluginStatus, Receiver, StringContent, translate
from plugindialog import Ui_PluginViewDialog from plugindialog import Ui_PluginViewDialog
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class PluginForm(QtGui.QDialog, Ui_PluginViewDialog): class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
"""
The plugin form provides user control over the plugins OpenLP uses.
"""
def __init__(self, parent=None): def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.parent = parent self.parent = parent
@ -129,7 +131,9 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
if self.programaticChange: if self.programaticChange:
return return
if status == 0: if status == 0:
Receiver.send_message(u'cursor_busy')
self.activePlugin.toggleStatus(PluginStatus.Active) self.activePlugin.toggleStatus(PluginStatus.Active)
Receiver.send_message(u'cursor_normal')
else: else:
self.activePlugin.toggleStatus(PluginStatus.Inactive) self.activePlugin.toggleStatus(PluginStatus.Inactive)
status_text = unicode( status_text = unicode(

View File

@ -0,0 +1,137 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 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, SpellTextEdit
class Ui_PrintServiceOrderDialog(object):
def setupUi(self, printServiceOrderDialog):
printServiceOrderDialog.setObjectName(u'printServiceOrderDialog')
self.dialogLayout = QtGui.QGridLayout(printServiceOrderDialog)
self.dialogLayout.setObjectName(u'dialogLayout')
self.perviewLayout = QtGui.QVBoxLayout()
self.perviewLayout.setObjectName(u'perviewLayout')
self.previewLabel = QtGui.QLabel(printServiceOrderDialog)
self.previewLabel.setSizePolicy(
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
self.previewLabel.setObjectName(u'previewLabel')
self.perviewLayout.addWidget(self.previewLabel)
self.previewWidget = QtGui.QPrintPreviewWidget(
self.printer, self, QtCore.Qt.Widget)
self.previewWidget.setEnabled(True)
self.previewWidget.setSizePolicy(
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding)
self.previewWidget.setObjectName(u'previewWidget')
# Give the previewWidget a fixed size, to prevent resizing when clicking
# the zoom buttons.
self.previewWidget.setFixedWidth(350)
self.perviewLayout.addWidget(self.previewWidget)
self.dialogLayout.addLayout(self.perviewLayout, 0, 0, 1, 1)
self.settingsLayout = QtGui.QVBoxLayout()
self.settingsLayout.setObjectName(u'settingsLayout')
self.serviceTitleLayout = QtGui.QGridLayout()
self.serviceTitleLayout.setObjectName(u'serviceTitleLayout')
self.serviceTitleLineEdit = QtGui.QLineEdit(printServiceOrderDialog)
self.serviceTitleLineEdit.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
self.serviceTitleLineEdit.setObjectName(u'serviceTitleLineEdit')
self.serviceTitleLayout.addWidget(self.serviceTitleLineEdit, 1, 1, 1, 1)
self.serviceTitleLabel = QtGui.QLabel(printServiceOrderDialog)
self.serviceTitleLabel.setSizePolicy(
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
self.serviceTitleLabel.setObjectName(u'serviceTitleLabel')
self.serviceTitleLayout.addWidget(self.serviceTitleLabel, 1, 0, 1, 1)
self.settingsLayout.addLayout(self.serviceTitleLayout)
self.printSlideTextCheckBox = QtGui.QCheckBox(printServiceOrderDialog)
self.printSlideTextCheckBox.setObjectName(u'printSlideTextCheckBox')
self.settingsLayout.addWidget(self.printSlideTextCheckBox)
self.printNotesCheckBox = QtGui.QCheckBox(printServiceOrderDialog)
self.printNotesCheckBox.setObjectName(u'printNotesCheckBox')
self.settingsLayout.addWidget(self.printNotesCheckBox)
self.printMetaDataCheckBox = QtGui.QCheckBox(printServiceOrderDialog)
self.printMetaDataCheckBox.setObjectName(u'printMetaDataCheckBox')
self.settingsLayout.addWidget(self.printMetaDataCheckBox)
spacerItem = QtGui.QSpacerItem(20, 40,
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.settingsLayout.addItem(spacerItem)
self.customNotesLabel = QtGui.QLabel(self)
self.customNotesLabel.setObjectName(u'customNotesLabel')
self.settingsLayout.addWidget(self.customNotesLabel)
self.customNoteEdit = SpellTextEdit(self)
self.customNoteEdit.setObjectName(u'customNoteEdit')
self.settingsLayout.addWidget(self.customNoteEdit)
self.dialogLayout.addLayout(self.settingsLayout, 0, 3, 1, 1)
self.buttonLayout = QtGui.QHBoxLayout()
self.buttonLayout.setObjectName(u'buttonLayout')
spacerItem = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.buttonLayout.addItem(spacerItem)
self.cancelButton = QtGui.QPushButton(printServiceOrderDialog)
self.cancelButton.setObjectName(u'cancelButton')
self.buttonLayout.addWidget(self.cancelButton)
self.printButton = QtGui.QPushButton(printServiceOrderDialog)
self.printButton.setObjectName(u'printButton')
self.buttonLayout.addWidget(self.printButton)
self.dialogLayout.addLayout(self.buttonLayout, 1, 3, 1, 1)
self.zoomButtonLayout = QtGui.QHBoxLayout()
self.zoomButtonLayout.setObjectName(u'zoomButtonLayout')
spacerItem = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.zoomButtonLayout.addItem(spacerItem)
self.zoomOutButton = QtGui.QToolButton(printServiceOrderDialog)
self.zoomOutButton.setIcon(
build_icon(u':/general/general_zoom_out.png'))
self.zoomOutButton.setObjectName(u'zoomOutButton')
self.zoomButtonLayout.addWidget(self.zoomOutButton)
self.zoomInButton = QtGui.QToolButton(printServiceOrderDialog)
self.zoomInButton.setIcon(build_icon(u':/general/general_zoom_in.png'))
self.zoomInButton.setObjectName(u'zoomInButton')
self.zoomButtonLayout.addWidget(self.zoomInButton)
self.dialogLayout.addLayout(self.zoomButtonLayout, 1, 0, 1, 1)
self.retranslateUi(printServiceOrderDialog)
QtCore.QMetaObject.connectSlotsByName(printServiceOrderDialog)
def retranslateUi(self, printServiceOrderDialog):
printServiceOrderDialog.setWindowTitle(
translate('OpenLP.PrintServiceOrderForm', 'Print Service Order'))
self.previewLabel.setText(
translate('OpenLP.ServiceManager', '<b>Preview:</b>'))
self.printSlideTextCheckBox.setText(translate(
'OpenLP.PrintServiceOrderForm', 'Include slide text if available'))
self.printNotesCheckBox.setText(translate(
'OpenLP.PrintServiceOrderForm', 'Include service item notes'))
self.printMetaDataCheckBox.setText(
translate('OpenLP.PrintServiceOrderForm',
'Include play length of media items'))
self.serviceTitleLabel.setText(translate(
'OpenLP.PrintServiceOrderForm', 'Title:'))
self.serviceTitleLineEdit.setText(translate('OpenLP.ServiceManager',
'Service Order Sheet'))
self.printButton.setText(translate('OpenLP.ServiceManager', 'Print'))
self.cancelButton.setText(translate('OpenLP.ServiceManager', 'Cancel'))
self.customNotesLabel.setText(
translate('OpenLP.ServiceManager', '<b>Custom Service Notes:</b>'))

View File

@ -0,0 +1,175 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 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 datetime
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
from openlp.core.ui.printserviceorderdialog import Ui_PrintServiceOrderDialog
class PrintServiceOrderForm(QtGui.QDialog, Ui_PrintServiceOrderDialog):
def __init__(self, parent, serviceManager):
"""
Constructor
"""
QtGui.QDialog.__init__(self, parent)
self.serviceManager = serviceManager
self.printer = QtGui.QPrinter()
self.printDialog = QtGui.QPrintDialog(self.printer, self)
self.document = QtGui.QTextDocument()
self.setupUi(self)
# Load the settings for the dialog.
settings = QtCore.QSettings()
settings.beginGroup(u'advanced')
self.printSlideTextCheckBox.setChecked(settings.value(
u'print slide text', QtCore.QVariant(False)).toBool())
self.printMetaDataCheckBox.setChecked(settings.value(
u'print file meta data', QtCore.QVariant(False)).toBool())
self.printNotesCheckBox.setChecked(settings.value(
u'print notes', QtCore.QVariant(False)).toBool())
settings.endGroup()
# Signals
QtCore.QObject.connect(self.printButton,
QtCore.SIGNAL(u'clicked()'), self.printServiceOrder)
QtCore.QObject.connect(self.zoomOutButton,
QtCore.SIGNAL(u'clicked()'), self.zoomOut)
QtCore.QObject.connect(self.zoomInButton,
QtCore.SIGNAL(u'clicked()'), self.zoomIn)
QtCore.QObject.connect(self.previewWidget,
QtCore.SIGNAL(u'paintRequested(QPrinter *)'), self.paintRequested)
QtCore.QObject.connect(self.serviceTitleLineEdit,
QtCore.SIGNAL(u'textChanged(const QString)'),
self.updatePreviewText)
QtCore.QObject.connect(self.printSlideTextCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.updatePreviewText)
QtCore.QObject.connect(self.printNotesCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.updatePreviewText)
QtCore.QObject.connect(self.printMetaDataCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'), self.updatePreviewText)
QtCore.QObject.connect(self.customNoteEdit,
QtCore.SIGNAL(u'textChanged()'), self.updatePreviewText)
QtCore.QObject.connect(self.cancelButton,
QtCore.SIGNAL(u'clicked()'), self.reject)
self.updatePreviewText()
def updatePreviewText(self):
"""
Creates the html text and updates the html of *self.document*.
"""
text = u''
if self.serviceTitleLineEdit.text():
text += u'<h2>%s</h2>' % unicode(self.serviceTitleLineEdit.text())
for item in self.serviceManager.serviceItems:
item = item[u'service_item']
# Add the title of the service item.
text += u'<h4><img src="%s" /> %s</h4>' % (item.icon,
item.get_display_title())
# Add slide text of the service item.
if self.printSlideTextCheckBox.isChecked():
if item.is_text():
# Add the text of the service item.
for slide in item.get_frames():
text += u'<p>' + slide[u'text'] + u'</p>'
elif item.is_image():
# Add the image names of the service item.
text += u'<ol>'
for slide in range(len(item.get_frames())):
text += u'<li><p>%s</p></li>' % \
item.get_frame_title(slide)
text += u'</ol>'
if item.foot_text:
# add footer
text += u'<p>%s</p>' % item.foot_text
# Add service items' notes.
if self.printNotesCheckBox.isChecked():
if item.notes:
text += u'<p><b>%s</b></p>%s' % (translate(
'OpenLP.ServiceManager', 'Notes:'),
item.notes.replace(u'\n', u'<br />'))
# Add play length of media files.
if item.is_media() and self.printMetaDataCheckBox.isChecked():
text += u'<p><b>%s</b> %s</p>' % (translate(
'OpenLP.ServiceManager', u'Playing time:'),
unicode(datetime.timedelta(seconds=item.media_length)))
if self.customNoteEdit.toPlainText():
text += u'<h4>%s</h4>%s' % (translate('OpenLP.ServiceManager',
u'Custom Service Notes:'), self.customNoteEdit.toPlainText())
self.document.setHtml(text)
self.previewWidget.updatePreview()
def paintRequested(self, printer):
"""
Paint the preview of the *self.document*.
``printer``
A *QPrinter* object.
"""
self.document.print_(printer)
def printServiceOrder(self):
"""
Called, when the *printButton* is clicked. Opens the *printDialog*.
"""
if not self.printDialog.exec_():
return
# Print the document.
self.document.print_(self.printer)
self.accept()
def zoomIn(self):
"""
Called when *zoomInButton* is clicked.
"""
self.previewWidget.zoomIn()
def zoomOut(self):
"""
Called when *zoomOutButton* is clicked.
"""
self.previewWidget.zoomOut()
def accept(self):
"""
Save the settings and close the dialog.
"""
# Save the settings for this dialog.
settings = QtCore.QSettings()
settings.beginGroup(u'advanced')
settings.setValue(u'print slide text',
QtCore.QVariant(self.printSlideTextCheckBox.isChecked()))
settings.setValue(u'print file meta data',
QtCore.QVariant(self.printMetaDataCheckBox.isChecked()))
settings.setValue(u'print notes',
QtCore.QVariant(self.printNotesCheckBox.isChecked()))
settings.endGroup()
# Close the dialog.
return QtGui.QDialog.accept(self)
def reject(self):
"""
Close the dialog, do not print the service and do not save the settings.
"""
return QtGui.QDialog.reject(self)

View File

@ -26,7 +26,9 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, build_icon from openlp.core.lib import translate
from openlp.core.lib.ui import create_accept_reject_button_box, \
create_delete_push_button, create_up_down_push_button_set
class Ui_ServiceItemEditDialog(object): class Ui_ServiceItemEditDialog(object):
def setupUi(self, serviceItemEditDialog): def setupUi(self, serviceItemEditDialog):
@ -39,30 +41,19 @@ class Ui_ServiceItemEditDialog(object):
self.dialogLayout.addWidget(self.listWidget, 0, 0) self.dialogLayout.addWidget(self.listWidget, 0, 0)
self.buttonLayout = QtGui.QVBoxLayout() self.buttonLayout = QtGui.QVBoxLayout()
self.buttonLayout.setObjectName(u'buttonLayout') self.buttonLayout.setObjectName(u'buttonLayout')
self.deleteButton = QtGui.QPushButton(serviceItemEditDialog) self.deleteButton = create_delete_push_button(serviceItemEditDialog)
self.deleteButton.setObjectName(u'deleteButton')
self.buttonLayout.addWidget(self.deleteButton) self.buttonLayout.addWidget(self.deleteButton)
self.buttonLayout.addStretch() self.buttonLayout.addStretch()
self.upButton = QtGui.QPushButton(serviceItemEditDialog) self.upButton, self.downButton = create_up_down_push_button_set(
self.upButton.setIcon(build_icon(u':/services/service_up.png')) serviceItemEditDialog)
self.upButton.setObjectName(u'upButton')
self.buttonLayout.addWidget(self.upButton) self.buttonLayout.addWidget(self.upButton)
self.downButton = QtGui.QPushButton(serviceItemEditDialog)
self.downButton.setIcon(build_icon(u':/services/service_down.png'))
self.downButton.setObjectName(u'downButton')
self.buttonLayout.addWidget(self.downButton) self.buttonLayout.addWidget(self.downButton)
self.dialogLayout.addLayout(self.buttonLayout, 0, 1) self.dialogLayout.addLayout(self.buttonLayout, 0, 1)
self.buttonBox = QtGui.QDialogButtonBox(serviceItemEditDialog) self.dialogLayout.addWidget(
self.buttonBox.setStandardButtons( create_accept_reject_button_box(serviceItemEditDialog), 1, 0, 1, 2)
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2)
self.retranslateUi(serviceItemEditDialog) self.retranslateUi(serviceItemEditDialog)
QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog) QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog)
def retranslateUi(self, serviceItemEditDialog): def retranslateUi(self, serviceItemEditDialog):
serviceItemEditDialog.setWindowTitle( serviceItemEditDialog.setWindowTitle(
translate('OpenLP.ServiceItemEditForm', 'Reorder Service Item')) translate('OpenLP.ServiceItemEditForm', 'Reorder Service Item'))
self.deleteButton.setText(translate('OpenLP.ServiceItemEditForm',
'Delete'))

View File

@ -39,17 +39,6 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
self.itemList = [] self.itemList = []
# enable drop
QtCore.QObject.connect(self.upButton,
QtCore.SIGNAL(u'clicked()'), self.onItemUp)
QtCore.QObject.connect(self.downButton,
QtCore.SIGNAL(u'clicked()'), self.onItemDown)
QtCore.QObject.connect(self.deleteButton,
QtCore.SIGNAL(u'clicked()'), self.onItemDelete)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'accepted()'), self.accept)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'rejected()'), self.reject)
QtCore.QObject.connect(self.listWidget, QtCore.QObject.connect(self.listWidget,
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged) QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
@ -81,7 +70,7 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
item_name = QtGui.QListWidgetItem(frame[u'title']) item_name = QtGui.QListWidgetItem(frame[u'title'])
self.listWidget.addItem(item_name) self.listWidget.addItem(item_name)
def onItemDelete(self): def onDeleteButtonClicked(self):
""" """
Delete the current row. Delete the current row.
""" """
@ -96,33 +85,37 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
else: else:
self.listWidget.setCurrentRow(row) self.listWidget.setCurrentRow(row)
def onItemUp(self): def onUpButtonClicked(self):
""" """
Move the current row up in the list. Move the current row up in the list.
""" """
item = self.listWidget.currentItem() self.__moveItem(u'up')
if not item:
return
row = self.listWidget.row(item)
temp = self.itemList[row]
self.itemList.remove(self.itemList[row])
self.itemList.insert(row - 1, temp)
self.loadData()
self.listWidget.setCurrentRow(row - 1)
def onItemDown(self): def onDownButtonClicked(self):
""" """
Move the current row down in the list Move the current row down in the list
""" """
self.__moveItem(u'down')
def __moveItem(self, direction=u''):
"""
Move the current item.
"""
if not direction:
return
item = self.listWidget.currentItem() item = self.listWidget.currentItem()
if not item: if not item:
return return
row = self.listWidget.row(item) row = self.listWidget.row(item)
temp = self.itemList[row] temp = self.itemList[row]
self.itemList.remove(self.itemList[row]) self.itemList.remove(self.itemList[row])
self.itemList.insert(row + 1, temp) if direction == u'up':
row -= 1
else:
row += 1
self.itemList.insert(row, temp)
self.loadData() self.loadData()
self.listWidget.setCurrentRow(row + 1) self.listWidget.setCurrentRow(row)
def onCurrentRowChanged(self, row): def onCurrentRowChanged(self, row):
""" """

View File

@ -23,10 +23,9 @@
# 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 os
import logging
import cPickle import cPickle
import logging
import os
import zipfile import zipfile
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -36,8 +35,9 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \ from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \ Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \
ThemeLevel ThemeLevel
from openlp.core.ui import criticalErrorMessageBox, ServiceNoteForm, \ from openlp.core.lib.ui import UiStrings, critical_error_message_box
ServiceItemEditForm from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.ui.printserviceorderform import PrintServiceOrderForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
split_filename split_filename
@ -67,8 +67,8 @@ class ServiceManagerList(QtGui.QTreeWidget):
class ServiceManager(QtGui.QWidget): class ServiceManager(QtGui.QWidget):
""" """
Manages the services. This involves taking text strings from plugins and Manages the services. This involves taking text strings from plugins and
adding them to the service. This service can then be zipped up with all adding them to the service. This service can then be zipped up with all
the resources used into one OSZ file for use on any OpenLP v2 installation. the resources used into one OSZ file for use on any OpenLP v2 installation.
Also handles the UI tasks of moving things up and down etc. Also handles the UI tasks of moving things up and down etc.
""" """
@ -88,6 +88,7 @@ class ServiceManager(QtGui.QWidget):
self._fileName = u'' self._fileName = u''
self.serviceNoteForm = ServiceNoteForm(self.mainwindow) self.serviceNoteForm = ServiceNoteForm(self.mainwindow)
self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow) self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow)
self.startTimeForm = StartTimeForm(self.mainwindow)
# start with the layout # start with the layout
self.layout = QtGui.QVBoxLayout(self) self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0) self.layout.setSpacing(0)
@ -95,20 +96,16 @@ class ServiceManager(QtGui.QWidget):
# Create the top toolbar # Create the top toolbar
self.toolbar = OpenLPToolbar(self) self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'New Service'), UiStrings.NewService, u':/general/general_new.png',
u':/general/general_new.png', UiStrings.CreateService, self.onNewServiceClicked)
translate('OpenLP.ServiceManager', 'Create a new service'),
self.onNewServiceClicked)
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Open Service'), UiStrings.OpenService, u':/general/general_open.png',
u':/general/general_open.png',
translate('OpenLP.ServiceManager', 'Load an existing service'), translate('OpenLP.ServiceManager', 'Load an existing service'),
self.onLoadServiceClicked) self.onLoadServiceClicked)
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Save Service'), UiStrings.SaveService, u':/general/general_save.png',
u':/general/general_save.png',
translate('OpenLP.ServiceManager', 'Save this service'), translate('OpenLP.ServiceManager', 'Save this service'),
self.onSaveServiceClicked) self.saveFile)
self.toolbar.addSeparator() self.toolbar.addSeparator()
self.themeLabel = QtGui.QLabel(translate('OpenLP.ServiceManager', self.themeLabel = QtGui.QLabel(translate('OpenLP.ServiceManager',
'Theme:'), self) 'Theme:'), self)
@ -178,8 +175,8 @@ class ServiceManager(QtGui.QWidget):
translate('OpenLP.ServiceManager', 'Move &down'), translate('OpenLP.ServiceManager', 'Move &down'),
None, None,
translate('OpenLP.ServiceManager', translate('OpenLP.ServiceManager',
'Moves the selection up the window.'), 'Moves the selection down the window.'),
self.onMoveSelectionDown, shortcut=QtCore.Qt.Key_Up) self.onMoveSelectionDown, shortcut=QtCore.Qt.Key_Down)
self.serviceManagerList.down.setVisible(False) self.serviceManagerList.down.setVisible(False)
self.serviceManagerList.up = self.orderToolbar.addToolbarButton( self.serviceManagerList.up = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move up'), translate('OpenLP.ServiceManager', 'Move up'),
@ -270,16 +267,19 @@ class ServiceManager(QtGui.QWidget):
self.notesAction = self.menu.addAction( self.notesAction = self.menu.addAction(
translate('OpenLP.ServiceManager', '&Notes')) translate('OpenLP.ServiceManager', '&Notes'))
self.notesAction.setIcon(build_icon(u':/services/service_notes.png')) self.notesAction.setIcon(build_icon(u':/services/service_notes.png'))
self.timeAction = self.menu.addAction(
translate('OpenLP.ServiceManager', '&Start Time'))
self.timeAction.setIcon(build_icon(u':/media/media_time.png'))
self.deleteAction = self.menu.addAction( self.deleteAction = self.menu.addAction(
translate('OpenLP.ServiceManager', '&Delete From Service')) translate('OpenLP.ServiceManager', '&Delete From Service'))
self.deleteAction.setIcon(build_icon(u':/general/general_delete.png')) self.deleteAction.setIcon(build_icon(u':/general/general_delete.png'))
self.sep1 = self.menu.addAction(u'') self.sep1 = self.menu.addAction(u'')
self.sep1.setSeparator(True) self.sep1.setSeparator(True)
self.previewAction = self.menu.addAction( self.previewAction = self.menu.addAction(
translate('OpenLP.ServiceManager', '&Preview Verse')) translate('OpenLP.ServiceManager', 'Show &Preview'))
self.previewAction.setIcon(build_icon(u':/general/general_preview.png')) self.previewAction.setIcon(build_icon(u':/general/general_preview.png'))
self.liveAction = self.menu.addAction( self.liveAction = self.menu.addAction(
translate('OpenLP.ServiceManager', '&Live Verse')) translate('OpenLP.ServiceManager', 'Show &Live'))
self.liveAction.setIcon(build_icon(u':/general/general_live.png')) self.liveAction.setIcon(build_icon(u':/general/general_live.png'))
self.sep2 = self.menu.addAction(u'') self.sep2 = self.menu.addAction(u'')
self.sep2.setSeparator(True) self.sep2.setSeparator(True)
@ -361,12 +361,7 @@ class ServiceManager(QtGui.QWidget):
Create a new service. Create a new service.
""" """
if self.isModified(): if self.isModified():
result = QtGui.QMessageBox.question(self.mainwindow, result = self.saveModifiedService()
translate('OpenLP.ServiceManager', 'Save Changes'),
translate('OpenLP.ServiceManager', 'The current service has '
'been modified, would you like to save it?'),
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
if result == QtGui.QMessageBox.Cancel: if result == QtGui.QMessageBox.Cancel:
return False return False
elif result == QtGui.QMessageBox.Save: elif result == QtGui.QMessageBox.Save:
@ -376,12 +371,7 @@ class ServiceManager(QtGui.QWidget):
def onLoadServiceClicked(self): def onLoadServiceClicked(self):
if self.isModified(): if self.isModified():
result = QtGui.QMessageBox.question(self.mainwindow, result = self.saveModifiedService()
translate('OpenLP.ServiceManager', 'Save Changes'),
translate('OpenLP.ServiceManager', 'The current service has '
'been modified, would you like to save it?'),
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
if result == QtGui.QMessageBox.Cancel: if result == QtGui.QMessageBox.Cancel:
return False return False
elif result == QtGui.QMessageBox.Save: elif result == QtGui.QMessageBox.Save:
@ -397,11 +387,13 @@ class ServiceManager(QtGui.QWidget):
split_filename(fileName)[0]) split_filename(fileName)[0])
self.loadFile(fileName) self.loadFile(fileName)
def onSaveServiceClicked(self): def saveModifiedService(self):
self.saveFile() return QtGui.QMessageBox.question(self.mainwindow,
translate('OpenLP.ServiceManager', 'Modified Service'),
def onSaveServiceAsClicked(self): translate('OpenLP.ServiceManager', 'The current service has '
self.saveFileAs() 'been modified. Would you like to save this service?'),
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
def onRecentServiceClicked(self): def onRecentServiceClicked(self):
sender = self.sender() sender = self.sender()
@ -469,11 +461,11 @@ class ServiceManager(QtGui.QWidget):
def saveFileAs(self): def saveFileAs(self):
""" """
Get a file name and then call :function:`ServiceManager.saveFile` to Get a file name and then call :func:`ServiceManager.saveFile` to
save the file. save the file.
""" """
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow, fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
translate('OpenLP.ServiceManager', 'Save Service'), UiStrings.SaveService,
SettingsManager.get_last_dir( SettingsManager.get_last_dir(
self.mainwindow.serviceSettingsSection), self.mainwindow.serviceSettingsSection),
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)'))) translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
@ -499,7 +491,7 @@ class ServiceManager(QtGui.QWidget):
for file in zip.namelist(): for file in zip.namelist():
ucsfile = file_is_unicode(file) ucsfile = file_is_unicode(file)
if not ucsfile: if not ucsfile:
criticalErrorMessageBox( critical_error_message_box(
message=translate('OpenLP.ServiceManager', message=translate('OpenLP.ServiceManager',
'File is not a valid service.\n' 'File is not a valid service.\n'
'The content encoding is not UTF-8.')) 'The content encoding is not UTF-8.'))
@ -514,6 +506,7 @@ class ServiceManager(QtGui.QWidget):
if filePath.endswith(u'osd'): if filePath.endswith(u'osd'):
p_file = filePath p_file = filePath
if 'p_file' in locals(): if 'p_file' in locals():
Receiver.send_message(u'cursor_busy')
fileTo = open(p_file, u'r') fileTo = open(p_file, u'r')
items = cPickle.load(fileTo) items = cPickle.load(fileTo)
fileTo.close() fileTo.close()
@ -528,13 +521,14 @@ class ServiceManager(QtGui.QWidget):
Receiver.send_message(u'%s_service_load' % Receiver.send_message(u'%s_service_load' %
serviceItem.name.lower(), serviceItem) serviceItem.name.lower(), serviceItem)
delete_file(p_file) delete_file(p_file)
Receiver.send_message(u'cursor_normal')
else: else:
criticalErrorMessageBox( critical_error_message_box(
message=translate('OpenLP.ServiceManager', message=translate('OpenLP.ServiceManager',
'File is not a valid service.')) 'File is not a valid service.'))
log.exception(u'File contains no service data') log.exception(u'File contains no service data')
except (IOError, NameError): except (IOError, NameError):
log.exception(u'Problem loading a service file') log.exception(u'Problem loading service file %s' % fileName)
finally: finally:
if fileTo: if fileTo:
fileTo.close() fileTo.close()
@ -544,9 +538,7 @@ class ServiceManager(QtGui.QWidget):
self.mainwindow.addRecentFile(fileName) self.mainwindow.addRecentFile(fileName)
self.setModified(False) self.setModified(False)
QtCore.QSettings(). \ QtCore.QSettings(). \
setValue(u'service/last file',QtCore.QVariant(fileName)) setValue(u'service/last file', QtCore.QVariant(fileName))
# Refresh Plugin lists
Receiver.send_message(u'plugin_list_refresh')
def loadLastFile(self): def loadLastFile(self):
""" """
@ -571,6 +563,7 @@ class ServiceManager(QtGui.QWidget):
self.editAction.setVisible(False) self.editAction.setVisible(False)
self.maintainAction.setVisible(False) self.maintainAction.setVisible(False)
self.notesAction.setVisible(False) self.notesAction.setVisible(False)
self.timeAction.setVisible(False)
if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit)\ if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit)\
and serviceItem[u'service_item'].edit_id: and serviceItem[u'service_item'].edit_id:
self.editAction.setVisible(True) self.editAction.setVisible(True)
@ -579,6 +572,9 @@ class ServiceManager(QtGui.QWidget):
self.maintainAction.setVisible(True) self.maintainAction.setVisible(True)
if item.parent() is None: if item.parent() is None:
self.notesAction.setVisible(True) self.notesAction.setVisible(True)
if serviceItem[u'service_item']\
.is_capable(ItemCapabilities.AllowsVarableStartTime):
self.timeAction.setVisible(True)
self.themeMenu.menuAction().setVisible(False) self.themeMenu.menuAction().setVisible(False)
if serviceItem[u'service_item'].is_text(): if serviceItem[u'service_item'].is_text():
self.themeMenu.menuAction().setVisible(True) self.themeMenu.menuAction().setVisible(True)
@ -591,6 +587,8 @@ class ServiceManager(QtGui.QWidget):
self.onDeleteFromService() self.onDeleteFromService()
if action == self.notesAction: if action == self.notesAction:
self.onServiceItemNoteForm() self.onServiceItemNoteForm()
if action == self.timeAction:
self.onStartTimeForm()
if action == self.previewAction: if action == self.previewAction:
self.makePreview() self.makePreview()
if action == self.liveAction: if action == self.liveAction:
@ -603,7 +601,17 @@ class ServiceManager(QtGui.QWidget):
if self.serviceNoteForm.exec_(): if self.serviceNoteForm.exec_():
self.serviceItems[item][u'service_item'].notes = \ self.serviceItems[item][u'service_item'].notes = \
self.serviceNoteForm.textEdit.toPlainText() self.serviceNoteForm.textEdit.toPlainText()
self.repaintServiceList(item, 0) self.repaintServiceList(item, -1)
def onStartTimeForm(self):
item = self.findServiceItem()[0]
self.startTimeForm.item = self.serviceItems[item]
if self.startTimeForm.exec_():
self.serviceItems[item][u'service_item'].start_time = \
self.startTimeForm.hourSpinBox.value() * 3600 + \
self.startTimeForm.minuteSpinBox.value() * 60 + \
self.startTimeForm.secondSpinBox.value()
self.repaintServiceList(item, -1)
def onServiceItemEditForm(self): def onServiceItemEditForm(self):
item = self.findServiceItem()[0] item = self.findServiceItem()[0]
@ -615,8 +623,7 @@ class ServiceManager(QtGui.QWidget):
def nextItem(self): def nextItem(self):
""" """
Called by the SlideController to select the Called by the SlideController to select the next service item.
next service item
""" """
if len(self.serviceManagerList.selectedItems()) == 0: if len(self.serviceManagerList.selectedItems()) == 0:
return return
@ -634,8 +641,7 @@ class ServiceManager(QtGui.QWidget):
def previousItem(self): def previousItem(self):
""" """
Called by the SlideController to select the Called by the SlideController to select the previous service item.
previous service item
""" """
if len(self.serviceManagerList.selectedItems()) == 0: if len(self.serviceManagerList.selectedItems()) == 0:
return return
@ -654,13 +660,13 @@ class ServiceManager(QtGui.QWidget):
def onSetItem(self, message): def onSetItem(self, message):
""" """
Called by a signal to select a specific item Called by a signal to select a specific item.
""" """
self.setItem(int(message[0])) self.setItem(int(message[0]))
def setItem(self, index): def setItem(self, index):
""" """
Makes a specific item in the service live Makes a specific item in the service live.
""" """
if index >= 0 and index < self.serviceManagerList.topLevelItemCount: if index >= 0 and index < self.serviceManagerList.topLevelItemCount:
item = self.serviceManagerList.topLevelItem(index) item = self.serviceManagerList.topLevelItem(index)
@ -669,8 +675,7 @@ class ServiceManager(QtGui.QWidget):
def onMoveSelectionUp(self): def onMoveSelectionUp(self):
""" """
Moves the selection up the window Moves the selection up the window. Called by the up arrow.
Called by the up arrow
""" """
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList) serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
tempItem = None tempItem = None
@ -695,8 +700,7 @@ class ServiceManager(QtGui.QWidget):
def onMoveSelectionDown(self): def onMoveSelectionDown(self):
""" """
Moves the selection down the window Moves the selection down the window. Called by the down arrow.
Called by the down arrow
""" """
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList) serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
firstItem = None firstItem = None
@ -718,7 +722,7 @@ class ServiceManager(QtGui.QWidget):
def onCollapseAll(self): def onCollapseAll(self):
""" """
Collapse all the service items Collapse all the service items.
""" """
for item in self.serviceItems: for item in self.serviceItems:
item[u'expanded'] = False item[u'expanded'] = False
@ -726,15 +730,15 @@ class ServiceManager(QtGui.QWidget):
def collapsed(self, item): def collapsed(self, item):
""" """
Record if an item is collapsed Record if an item is collapsed. Used when repainting the list to get the
Used when repainting the list to get the correct state correct state.
""" """
pos = item.data(0, QtCore.Qt.UserRole).toInt()[0] pos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
self.serviceItems[pos -1 ][u'expanded'] = False self.serviceItems[pos -1 ][u'expanded'] = False
def onExpandAll(self): def onExpandAll(self):
""" """
Collapse all the service items Collapse all the service items.
""" """
for item in self.serviceItems: for item in self.serviceItems:
item[u'expanded'] = True item[u'expanded'] = True
@ -742,70 +746,68 @@ class ServiceManager(QtGui.QWidget):
def expanded(self, item): def expanded(self, item):
""" """
Record if an item is collapsed Record if an item is collapsed. Used when repainting the list to get the
Used when repainting the list to get the correct state correct state.
""" """
pos = item.data(0, QtCore.Qt.UserRole).toInt()[0] pos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
self.serviceItems[pos -1 ][u'expanded'] = True self.serviceItems[pos -1 ][u'expanded'] = True
def onServiceTop(self): def onServiceTop(self):
""" """
Move the current ServiceItem to the top of the list Move the current ServiceItem to the top of the list.
""" """
item, count = self.findServiceItem() item, child = self.findServiceItem()
if item < len(self.serviceItems) and item is not -1: if item < len(self.serviceItems) and item is not -1:
temp = self.serviceItems[item] temp = self.serviceItems[item]
self.serviceItems.remove(self.serviceItems[item]) self.serviceItems.remove(self.serviceItems[item])
self.serviceItems.insert(0, temp) self.serviceItems.insert(0, temp)
self.repaintServiceList(0, count) self.repaintServiceList(0, child)
self.setModified(True) self.setModified(True)
def onServiceUp(self): def onServiceUp(self):
""" """
Move the current ServiceItem up in the list Move the current ServiceItem one position up in the list.
Note move up means move to top of area ie 0.
""" """
item, count = self.findServiceItem() item, child = self.findServiceItem()
if item > 0: if item > 0:
temp = self.serviceItems[item] temp = self.serviceItems[item]
self.serviceItems.remove(self.serviceItems[item]) self.serviceItems.remove(self.serviceItems[item])
self.serviceItems.insert(item - 1, temp) self.serviceItems.insert(item - 1, temp)
self.repaintServiceList(item - 1, count) self.repaintServiceList(item - 1, child)
self.setModified(True) self.setModified(True)
def onServiceDown(self): def onServiceDown(self):
""" """
Move the current ServiceItem down in the list Move the current ServiceItem one position down in the list.
Note move down means move to bottom of area i.e len().
""" """
item, count = self.findServiceItem() item, child = self.findServiceItem()
if item < len(self.serviceItems) and item is not -1: if item < len(self.serviceItems) and item is not -1:
temp = self.serviceItems[item] temp = self.serviceItems[item]
self.serviceItems.remove(self.serviceItems[item]) self.serviceItems.remove(self.serviceItems[item])
self.serviceItems.insert(item + 1, temp) self.serviceItems.insert(item + 1, temp)
self.repaintServiceList(item + 1, count) self.repaintServiceList(item + 1, child)
self.setModified(True) self.setModified(True)
def onServiceEnd(self): def onServiceEnd(self):
""" """
Move the current ServiceItem to the bottom of the list Move the current ServiceItem to the bottom of the list.
""" """
item, count = self.findServiceItem() item, child = self.findServiceItem()
if item < len(self.serviceItems) and item is not -1: if item < len(self.serviceItems) and item is not -1:
temp = self.serviceItems[item] temp = self.serviceItems[item]
self.serviceItems.remove(self.serviceItems[item]) self.serviceItems.remove(self.serviceItems[item])
self.serviceItems.insert(len(self.serviceItems), temp) self.serviceItems.insert(len(self.serviceItems), temp)
self.repaintServiceList(len(self.serviceItems) - 1, count) self.repaintServiceList(len(self.serviceItems) - 1, child)
self.setModified(True) self.setModified(True)
def onDeleteFromService(self): def onDeleteFromService(self):
""" """
Remove the current ServiceItem from the list Remove the current ServiceItem from the list.
""" """
item = self.findServiceItem()[0] item = self.findServiceItem()[0]
if item is not -1: if item != -1:
self.serviceItems.remove(self.serviceItems[item]) self.serviceItems.remove(self.serviceItems[item])
self.repaintServiceList(0, 0) self.repaintServiceList(item - 1, -1)
self.setModified(True) self.setModified(True)
def repaintServiceList(self, serviceItem, serviceItemChild): def repaintServiceList(self, serviceItem, serviceItemChild):
@ -847,7 +849,7 @@ class ServiceManager(QtGui.QWidget):
else: else:
treewidgetitem.setIcon(0, treewidgetitem.setIcon(0,
build_icon(u':/general/general_delete.png')) build_icon(u':/general/general_delete.png'))
treewidgetitem.setText(0, serviceitem.title) treewidgetitem.setText(0, serviceitem.get_display_title())
treewidgetitem.setToolTip(0, serviceitem.notes) treewidgetitem.setToolTip(0, serviceitem.notes)
treewidgetitem.setData(0, QtCore.Qt.UserRole, treewidgetitem.setData(0, QtCore.Qt.UserRole,
QtCore.QVariant(item[u'order'])) QtCore.QVariant(item[u'order']))
@ -857,6 +859,11 @@ class ServiceManager(QtGui.QWidget):
text = frame[u'title'].replace(u'\n', u' ') text = frame[u'title'].replace(u'\n', u' ')
child.setText(0, text[:40]) child.setText(0, text[:40])
child.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(count)) child.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(count))
if item[u'service_item'] \
.is_capable(ItemCapabilities.AllowsVarableStartTime):
tip = item[u'service_item'].get_media_time()
if tip:
child.setToolTip(0, tip)
if serviceItem == itemcount: if serviceItem == itemcount:
if item[u'expanded'] and serviceItemChild == count: if item[u'expanded'] and serviceItemChild == count:
self.serviceManagerList.setCurrentItem(child) self.serviceManagerList.setCurrentItem(child)
@ -867,16 +874,16 @@ class ServiceManager(QtGui.QWidget):
def validateItem(self, serviceItem): def validateItem(self, serviceItem):
""" """
Validates the service item and if the suffix matches an accepted Validates the service item and if the suffix matches an accepted
one it allows the item to be displayed one it allows the item to be displayed.
""" """
if serviceItem.is_command(): if serviceItem.is_command():
type = serviceItem._raw_frames[0][u'title'].split(u'.')[1] type = serviceItem._raw_frames[0][u'title'].split(u'.')[-1]
if type not in self.suffixes: if type not in self.suffixes:
serviceItem.is_valid = False serviceItem.is_valid = False
def cleanUp(self): def cleanUp(self):
""" """
Empties the servicePath of temporary files Empties the servicePath of temporary files.
""" """
for file in os.listdir(self.servicePath): for file in os.listdir(self.servicePath):
file_path = os.path.join(self.servicePath, file) file_path = os.path.join(self.servicePath, file)
@ -884,7 +891,7 @@ class ServiceManager(QtGui.QWidget):
def onThemeComboBoxSelected(self, currentIndex): def onThemeComboBoxSelected(self, currentIndex):
""" """
Set the theme for the current service Set the theme for the current service.
""" """
log.debug(u'onThemeComboBoxSelected') log.debug(u'onThemeComboBoxSelected')
self.service_theme = unicode(self.themeComboBox.currentText()) self.service_theme = unicode(self.themeComboBox.currentText())
@ -967,12 +974,12 @@ class ServiceManager(QtGui.QWidget):
# if not passed set to config value # if not passed set to config value
if expand is None: if expand is None:
expand = self.expandTabs expand = self.expandTabs
sitem = self.findServiceItem()[0]
item.render() item.render()
if replace: if replace:
sitem, child = self.findServiceItem()
item.merge(self.serviceItems[sitem][u'service_item']) item.merge(self.serviceItems[sitem][u'service_item'])
self.serviceItems[sitem][u'service_item'] = item self.serviceItems[sitem][u'service_item'] = item
self.repaintServiceList(sitem, 0) self.repaintServiceList(sitem, child)
self.mainwindow.liveController.replaceServiceManagerItem(item) self.mainwindow.liveController.replaceServiceManagerItem(item)
else: else:
# nothing selected for dnd # nothing selected for dnd
@ -981,17 +988,17 @@ class ServiceManager(QtGui.QWidget):
for inditem in item: for inditem in item:
self.serviceItems.append({u'service_item': inditem, self.serviceItems.append({u'service_item': inditem,
u'order': len(self.serviceItems) + 1, u'order': len(self.serviceItems) + 1,
u'expanded':expand}) u'expanded': expand})
else: else:
self.serviceItems.append({u'service_item': item, self.serviceItems.append({u'service_item': item,
u'order': len(self.serviceItems) + 1, u'order': len(self.serviceItems) + 1,
u'expanded':expand}) u'expanded': expand})
self.repaintServiceList(len(self.serviceItems) + 1, 0) self.repaintServiceList(len(self.serviceItems) - 1, -1)
else: else:
self.serviceItems.insert(self.dropPosition, self.serviceItems.insert(self.dropPosition,
{u'service_item': item, u'order': self.dropPosition, {u'service_item': item, u'order': self.dropPosition,
u'expanded':expand}) u'expanded': expand})
self.repaintServiceList(self.dropPosition, 0) self.repaintServiceList(self.dropPosition, -1)
# if rebuilding list make sure live is fixed. # if rebuilding list make sure live is fixed.
if rebuild: if rebuild:
self.mainwindow.liveController.replaceServiceManagerItem(item) self.mainwindow.liveController.replaceServiceManagerItem(item)
@ -1002,15 +1009,15 @@ class ServiceManager(QtGui.QWidget):
""" """
Send the current item to the Preview slide controller Send the current item to the Preview slide controller
""" """
item, count = self.findServiceItem() item, child = self.findServiceItem()
if self.serviceItems[item][u'service_item'].is_valid: if self.serviceItems[item][u'service_item'].is_valid:
self.mainwindow.previewController.addServiceManagerItem( self.mainwindow.previewController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], count) self.serviceItems[item][u'service_item'], child)
else: else:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', 'Your item cannot be ' translate('OpenLP.ServiceManager', 'Your item cannot be '
'displayed as there is no handler to display it')) 'displayed as there is no handler to display it'))
def getServiceItem(self): def getServiceItem(self):
""" """
@ -1026,10 +1033,10 @@ class ServiceManager(QtGui.QWidget):
""" """
Send the current item to the Live slide controller Send the current item to the Live slide controller
""" """
item, count = self.findServiceItem() item, child = self.findServiceItem()
if self.serviceItems[item][u'service_item'].is_valid: if self.serviceItems[item][u'service_item'].is_valid:
self.mainwindow.liveController.addServiceManagerItem( self.mainwindow.liveController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], count) self.serviceItems[item][u'service_item'], child)
if QtCore.QSettings().value( if QtCore.QSettings().value(
self.mainwindow.generalSettingsSection + u'/auto preview', self.mainwindow.generalSettingsSection + u'/auto preview',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
@ -1041,7 +1048,7 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems[item][u'service_item'], 0) self.serviceItems[item][u'service_item'], 0)
self.mainwindow.liveController.previewListWidget.setFocus() self.mainwindow.liveController.previewListWidget.setFocus()
else: else:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Missing Display Handler'),
translate('OpenLP.ServiceManager', 'Your item cannot be ' translate('OpenLP.ServiceManager', 'Your item cannot be '
'displayed as the plugin required to display it is missing ' 'displayed as the plugin required to display it is missing '
@ -1060,26 +1067,26 @@ class ServiceManager(QtGui.QWidget):
def findServiceItem(self): def findServiceItem(self):
""" """
Finds a ServiceItem in the list and returns the position of the Finds the selected ServiceItem in the list and returns the position of
serviceitem and its selected child item. For example, if the third child the serviceitem and its selected child item. For example, if the third
item (in the Slidecontroller known as slide) in the second service item child item (in the Slidecontroller known as slide) in the second service
is selected this will return:: item is selected this will return::
(1, 2) (1, 2)
""" """
items = self.serviceManagerList.selectedItems() items = self.serviceManagerList.selectedItems()
pos = 0 serviceItem = 0
count = -1 serviceItemChild = -1
for item in items: for item in items:
parentitem = item.parent() parentitem = item.parent()
if parentitem is None: if parentitem is None:
pos = item.data(0, QtCore.Qt.UserRole).toInt()[0] serviceItem = item.data(0, QtCore.Qt.UserRole).toInt()[0]
else: else:
pos = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0] serviceItem = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
count = item.data(0, QtCore.Qt.UserRole).toInt()[0] serviceItemChild = item.data(0, QtCore.Qt.UserRole).toInt()[0]
# adjust for zero based arrays # Adjust for zero based arrays.
pos = pos - 1 serviceItem -= 1
return pos, count return serviceItem, serviceItemChild
def dragEnterEvent(self, event): def dragEnterEvent(self, event):
""" """
@ -1105,7 +1112,7 @@ class ServiceManager(QtGui.QWidget):
item = self.serviceManagerList.itemAt(event.pos()) item = self.serviceManagerList.itemAt(event.pos())
# 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, child = self.findServiceItem()
# If no items selected # If no items selected
if startpos == -1: if startpos == -1:
return return
@ -1116,7 +1123,7 @@ class ServiceManager(QtGui.QWidget):
serviceItem = self.serviceItems[startpos] serviceItem = self.serviceItems[startpos]
self.serviceItems.remove(serviceItem) self.serviceItems.remove(serviceItem)
self.serviceItems.insert(endpos, serviceItem) self.serviceItems.insert(endpos, serviceItem)
self.repaintServiceList(endpos, startCount) self.repaintServiceList(endpos, child)
else: else:
# we are not over anything so drop # we are not over anything so drop
replace = False replace = False
@ -1182,17 +1189,24 @@ class ServiceManager(QtGui.QWidget):
def listRequest(self, message=None): def listRequest(self, message=None):
data = [] data = []
curindex = self.findServiceItem()[0] item = self.findServiceItem()[0]
if curindex >= 0 and curindex < len(self.serviceItems): if item >= 0 and item < len(self.serviceItems):
curitem = self.serviceItems[curindex] curitem = self.serviceItems[item]
else: else:
curitem = None curitem = None
for item in self.serviceItems: for item in self.serviceItems:
service_item = item[u'service_item'] service_item = item[u'service_item']
data_item = {} data_item = {}
data_item[u'title'] = unicode(service_item.title) data_item[u'title'] = unicode(service_item.get_display_title())
data_item[u'plugin'] = unicode(service_item.name) data_item[u'plugin'] = unicode(service_item.name)
data_item[u'notes'] = unicode(service_item.notes) data_item[u'notes'] = unicode(service_item.notes)
data_item[u'selected'] = (item == curitem) data_item[u'selected'] = (item == curitem)
data.append(data_item) data.append(data_item)
Receiver.send_message(u'servicemanager_list_response', data) Receiver.send_message(u'servicemanager_list_response', data)
def printServiceOrder(self):
"""
Print a Service Order Sheet.
"""
settingDialog = PrintServiceOrderForm(self.mainwindow, self)
settingDialog.exec_()

View File

@ -26,9 +26,10 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from servicenotedialog import Ui_ServiceNoteEdit from openlp.core.lib import translate
from openlp.core.lib.ui import create_accept_reject_button_box
class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit): class ServiceNoteForm(QtGui.QDialog):
""" """
This is the form that is used to edit the verses of the song. This is the form that is used to edit the verses of the song.
""" """
@ -37,8 +38,19 @@ class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit):
Constructor Constructor
""" """
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi()
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'), self.retranslateUi()
self.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'), def setupUi(self):
self.reject) self.setObjectName(u'serviceNoteEdit')
self.dialogLayout = QtGui.QVBoxLayout(self)
self.dialogLayout.setObjectName(u'verticalLayout')
self.textEdit = QtGui.QTextEdit(self)
self.textEdit.setObjectName(u'textEdit')
self.dialogLayout.addWidget(self.textEdit)
self.dialogLayout.addWidget(create_accept_reject_button_box(self))
QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self):
self.setWindowTitle(
translate('OpenLP.ServiceNoteForm', 'Service Item Notes'))

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, build_icon from openlp.core.lib import translate, build_icon
from openlp.core.lib.ui import create_accept_reject_button_box
class Ui_SettingsDialog(object): class Ui_SettingsDialog(object):
def setupUi(self, settingsDialog): def setupUi(self, settingsDialog):
@ -35,21 +36,13 @@ class Ui_SettingsDialog(object):
settingsDialog.setWindowIcon( settingsDialog.setWindowIcon(
build_icon(u':/system/system_settings.png')) build_icon(u':/system/system_settings.png'))
self.settingsLayout = QtGui.QVBoxLayout(settingsDialog) self.settingsLayout = QtGui.QVBoxLayout(settingsDialog)
margins = self.settingsLayout.contentsMargins()
self.settingsLayout.setObjectName(u'settingsLayout') self.settingsLayout.setObjectName(u'settingsLayout')
self.settingsTabWidget = QtGui.QTabWidget(settingsDialog) self.settingsTabWidget = QtGui.QTabWidget(settingsDialog)
self.settingsTabWidget.setObjectName(u'settingsTabWidget') self.settingsTabWidget.setObjectName(u'settingsTabWidget')
self.settingsLayout.addWidget(self.settingsTabWidget) self.settingsLayout.addWidget(self.settingsTabWidget)
self.buttonBox = QtGui.QDialogButtonBox(settingsDialog) self.buttonBox = create_accept_reject_button_box(settingsDialog, True)
self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(u'buttonBox')
self.settingsLayout.addWidget(self.buttonBox) self.settingsLayout.addWidget(self.buttonBox)
self.retranslateUi(settingsDialog) self.retranslateUi(settingsDialog)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'accepted()'), settingsDialog.accept)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'rejected()'), settingsDialog.reject)
QtCore.QMetaObject.connectSlotsByName(settingsDialog) QtCore.QMetaObject.connectSlotsByName(settingsDialog)
def retranslateUi(self, settingsDialog): def retranslateUi(self, settingsDialog):

View File

@ -36,7 +36,7 @@ class Ui_ShortcutListDialog(object):
self.treeWidget = QtGui.QTreeWidget(shortcutListDialog) self.treeWidget = QtGui.QTreeWidget(shortcutListDialog)
self.treeWidget.setAlternatingRowColors(True) self.treeWidget.setAlternatingRowColors(True)
self.treeWidget.setObjectName(u'treeWidget') self.treeWidget.setObjectName(u'treeWidget')
self.treeWidget.setColumnCount(2) self.treeWidget.setColumnCount(3)
self.dialogLayout.addWidget(self.treeWidget) self.dialogLayout.addWidget(self.treeWidget)
self.defaultButton = QtGui.QRadioButton(shortcutListDialog) self.defaultButton = QtGui.QRadioButton(shortcutListDialog)
self.defaultButton.setChecked(True) self.defaultButton.setChecked(True)
@ -78,7 +78,8 @@ class Ui_ShortcutListDialog(object):
translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts')) translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts'))
self.treeWidget.setHeaderLabels([ self.treeWidget.setHeaderLabels([
translate('OpenLP.ShortcutListDialog', 'Action'), translate('OpenLP.ShortcutListDialog', 'Action'),
translate('OpenLP.ShortcutListDialog', 'Shortcut')]) translate('OpenLP.ShortcutListDialog', 'Shortcut'),
translate('OpenLP.ShortcutListDialog', 'Alternate')])
self.defaultButton.setText( self.defaultButton.setText(
translate('OpenLP.ShortcutListDialog', 'Default: %s')) translate('OpenLP.ShortcutListDialog', 'Default: %s'))
self.customButton.setText( self.customButton.setText(

View File

@ -95,8 +95,13 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
item = QtGui.QTreeWidgetItem([category.name]) item = QtGui.QTreeWidgetItem([category.name])
for action in category.actions: for action in category.actions:
actionText = REMOVE_AMPERSAND.sub('', unicode(action.text())) actionText = REMOVE_AMPERSAND.sub('', unicode(action.text()))
shortcutText = action.shortcut().toString() if (len(action.shortcuts()) == 2):
actionItem = QtGui.QTreeWidgetItem([actionText, shortcutText]) shortcutText = action.shortcuts()[0].toString()
alternateText = action.shortcuts()[1].toString()
else:
shortcutText = action.shortcut().toString()
alternateText = u''
actionItem = QtGui.QTreeWidgetItem([actionText, shortcutText, alternateText])
actionItem.setIcon(0, action.icon()) actionItem.setIcon(0, action.icon())
item.addChild(actionItem) item.addChild(actionItem)
item.setExpanded(True) item.setExpanded(True)

View File

@ -30,9 +30,10 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
from openlp.core.ui import HideMode, MainDisplay
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \ from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
ItemCapabilities, translate ItemCapabilities, translate
from openlp.core.lib.ui import UiStrings, shortcut_action
from openlp.core.ui import HideMode, MainDisplay
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -77,28 +78,27 @@ class SlideController(QtGui.QWidget):
self.selectedRow = 0 self.selectedRow = 0
self.serviceItem = None self.serviceItem = None
self.alertTab = None self.alertTab = None
self.Panel = QtGui.QWidget(parent.ControlSplitter) self.panel = QtGui.QWidget(parent.controlSplitter)
self.slideList = {} self.slideList = {}
# Layout for holding panel # Layout for holding panel
self.panelLayout = QtGui.QVBoxLayout(self.Panel) self.panelLayout = QtGui.QVBoxLayout(self.panel)
self.panelLayout.setSpacing(0) self.panelLayout.setSpacing(0)
self.panelLayout.setMargin(0) self.panelLayout.setMargin(0)
# Type label for the top of the slide controller # Type label for the top of the slide controller
self.typeLabel = QtGui.QLabel(self.Panel) self.typeLabel = QtGui.QLabel(self.panel)
if self.isLive: if self.isLive:
self.typeLabel.setText(translate('OpenLP.SlideController', 'Live')) self.typeLabel.setText(UiStrings.Live)
self.split = 1 self.split = 1
self.typePrefix = u'live' self.typePrefix = u'live'
else: else:
self.typeLabel.setText(translate('OpenLP.SlideController', self.typeLabel.setText(UiStrings.Preview)
'Preview'))
self.split = 0 self.split = 0
self.typePrefix = u'preview' self.typePrefix = u'preview'
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;') self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
self.typeLabel.setAlignment(QtCore.Qt.AlignCenter) self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
self.panelLayout.addWidget(self.typeLabel) self.panelLayout.addWidget(self.typeLabel)
# Splitter # Splitter
self.splitter = QtGui.QSplitter(self.Panel) self.splitter = QtGui.QSplitter(self.panel)
self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setOrientation(QtCore.Qt.Vertical)
self.panelLayout.addWidget(self.splitter) self.panelLayout.addWidget(self.splitter)
# Actual controller section # Actual controller section
@ -119,6 +119,8 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.isLive = self.isLive self.previewListWidget.isLive = self.isLive
self.previewListWidget.setObjectName(u'PreviewListWidget') self.previewListWidget.setObjectName(u'PreviewListWidget')
self.previewListWidget.setSelectionBehavior(1) self.previewListWidget.setSelectionBehavior(1)
self.previewListWidget.setSelectionMode(
QtGui.QAbstractItemView.SingleSelection)
self.previewListWidget.setEditTriggers( self.previewListWidget.setEditTriggers(
QtGui.QAbstractItemView.NoEditTriggers) QtGui.QAbstractItemView.NoEditTriggers)
self.previewListWidget.setHorizontalScrollBarPolicy( self.previewListWidget.setHorizontalScrollBarPolicy(
@ -176,29 +178,33 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'triggered(bool)'), self.onHideDisplay) QtCore.SIGNAL(u'triggered(bool)'), self.onHideDisplay)
self.toolbar.addToolbarSeparator(u'Loop Separator') self.toolbar.addToolbarSeparator(u'Loop Separator')
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Start Loop', u':/media/media_time.png', u'Start Loop', u':/media/media_time.png',
translate('OpenLP.SlideController', 'Start continuous loop'), translate('OpenLP.SlideController', 'Start continuous loop'),
self.onStartLoop) self.onStartLoop)
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Stop Loop', u':/media/media_stop.png', u'Stop Loop', u':/media/media_stop.png',
translate('OpenLP.SlideController', 'Stop continuous loop'), translate('OpenLP.SlideController', 'Stop continuous loop'),
self.onStopLoop) self.onStopLoop)
self.DelaySpinBox = QtGui.QSpinBox() self.delaySpinBox = QtGui.QSpinBox()
self.DelaySpinBox.setMinimum(1) self.delaySpinBox.setMinimum(1)
self.DelaySpinBox.setMaximum(180) self.delaySpinBox.setMaximum(180)
self.toolbar.addToolbarWidget(u'Image SpinBox', self.DelaySpinBox) self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
self.DelaySpinBox.setSuffix(translate('OpenLP.SlideController', self.delaySpinBox.setSuffix(translate('OpenLP.SlideController',
's')) 's'))
self.DelaySpinBox.setToolTip(translate('OpenLP.SlideController', self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
'Delay between slides in seconds')) 'Delay between slides in seconds'))
else: else:
self.toolbar.addToolbarSeparator(u'Close Separator') self.toolbar.addToolbarSeparator(u'Close Separator')
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Go Live', u':/general/general_live.png', u'Go Live', u':/general/general_live.png',
translate('OpenLP.SlideController', 'Move to live'), translate('OpenLP.SlideController', 'Move to live'),
self.onGoLive) self.onGoLive)
self.toolbar.addToolbarSeparator(u'Close Separator') self.toolbar.addToolbarSeparator(u'Close Separator')
self.toolbar.addToolbarButton( self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Edit Song', u':/general/general_edit.png', u'Edit Song', u':/general/general_edit.png',
translate('OpenLP.SlideController', translate('OpenLP.SlideController',
'Edit and reload song preview'), 'Edit and reload song preview'),
@ -315,18 +321,8 @@ class SlideController(QtGui.QWidget):
self.mediabar.setVisible(False) self.mediabar.setVisible(False)
if self.isLive: if self.isLive:
self.setLiveHotkeys(self) self.setLiveHotkeys(self)
self.previewListWidget.addActions( self.__addActionsToWidget(self.previewListWidget)
[self.previousItem, self.__addActionsToWidget(self.display)
self.nextItem,
self.previousService,
self.nextService,
self.escapeItem])
self.display.addActions(
[self.previousItem,
self.nextItem,
self.previousService,
self.nextService,
self.escapeItem])
else: else:
self.setPreviewHotkeys() self.setPreviewHotkeys()
self.previewListWidget.addActions( self.previewListWidget.addActions(
@ -384,32 +380,21 @@ class SlideController(QtGui.QWidget):
self.previousItem.setShortcuts([QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp]) self.previousItem.setShortcuts([QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp])
self.previousItem.setShortcutContext( self.previousItem.setShortcutContext(
QtCore.Qt.WidgetWithChildrenShortcut) QtCore.Qt.WidgetWithChildrenShortcut)
actionList.add_action(self.nextItem, u'Live') actionList.add_action(self.previousItem, u'Live')
self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown]) self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown])
self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut) self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
actionList.add_action(self.nextItem, u'Live') actionList.add_action(self.nextItem, u'Live')
self.previousService = QtGui.QAction(translate( self.previousService = shortcut_action(parent,
'OpenLP.SlideController', 'Previous Service'), parent) translate('OpenLP.SlideController', 'Previous Service'),
self.previousService.setShortcuts([QtCore.Qt.Key_Left, 0]) [QtCore.Qt.Key_Left, 0], self.servicePrevious)
self.previousService.setShortcutContext(
QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(self.previousService,
QtCore.SIGNAL(u'triggered()'), self.servicePrevious)
actionList.add_action(self.previousService, u'Live') actionList.add_action(self.previousService, u'Live')
self.nextService = QtGui.QAction(translate( self.nextService = shortcut_action(parent,
'OpenLP.SlideController', 'Next Service'), parent) translate('OpenLP.SlideController', 'Next Service'),
self.nextService.setShortcuts([QtCore.Qt.Key_Right, 0]) [QtCore.Qt.Key_Right, 0], self.serviceNext)
self.nextService.setShortcutContext(
QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(self.nextService,
QtCore.SIGNAL(u'triggered()'), self.serviceNext)
actionList.add_action(self.nextService, u'Live') actionList.add_action(self.nextService, u'Live')
self.escapeItem = QtGui.QAction(translate( self.escapeItem = shortcut_action(parent,
'OpenLP.SlideController', 'Escape Item'), parent) translate('OpenLP.SlideController', 'Escape Item'),
self.escapeItem.setShortcuts([QtCore.Qt.Key_Escape, 0]) [QtCore.Qt.Key_Escape, 0], self.liveEscape)
self.escapeItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
QtCore.QObject.connect(self.escapeItem,
QtCore.SIGNAL(u'triggered()'), self.liveEscape)
actionList.add_action(self.escapeItem, u'Live') actionList.add_action(self.escapeItem, u'Live')
def liveEscape(self): def liveEscape(self):
@ -433,12 +418,7 @@ class SlideController(QtGui.QWidget):
self.display.alertTab = self.alertTab self.display.alertTab = self.alertTab
self.display.setup() self.display.setup()
if self.isLive: if self.isLive:
self.display.addActions( self.__addActionsToWidget(self.display)
[self.previousItem,
self.nextItem,
self.previousService,
self.nextService,
self.escapeItem])
# The SlidePreview's ratio. # The SlidePreview's ratio.
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())
@ -446,6 +426,12 @@ class SlideController(QtGui.QWidget):
if self.serviceItem: if self.serviceItem:
self.refreshServiceItem() self.refreshServiceItem()
def __addActionsToWidget(self, widget):
widget.addActions([
self.previousItem, self.nextItem,
self.previousService, self.nextService,
self.escapeItem])
def previewSizeChanged(self): def previewSizeChanged(self):
""" """
Takes care of the SlidePreview's size. Is called when one of the the Takes care of the SlidePreview's size. Is called when one of the the
@ -472,7 +458,7 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.resizeRowsToContents() self.previewListWidget.resizeRowsToContents()
else: else:
# Sort out image heights. # Sort out image heights.
width = self.parent.ControlSplitter.sizes()[self.split] width = self.parent.controlSplitter.sizes()[self.split]
for framenumber in range(len(self.serviceItem.get_frames())): for framenumber in range(len(self.serviceItem.get_frames())):
self.previewListWidget.setRowHeight( self.previewListWidget.setRowHeight(
framenumber, width / self.ratio) framenumber, width / self.ratio)
@ -480,18 +466,11 @@ class SlideController(QtGui.QWidget):
def onSongBarHandler(self): def onSongBarHandler(self):
request = unicode(self.sender().text()) request = unicode(self.sender().text())
slideno = self.slideList[request] slideno = self.slideList[request]
if slideno > self.previewListWidget.rowCount(): self.__updatePreviewSelection(slideno)
self.previewListWidget.selectRow(
self.previewListWidget.rowCount() - 1)
else:
if slideno + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(slideno + 1, 0))
self.previewListWidget.selectRow(slideno)
self.onSlideSelected() self.onSlideSelected()
def receiveSpinDelay(self, value): def receiveSpinDelay(self, value):
self.DelaySpinBox.setValue(int(value)) self.delaySpinBox.setValue(int(value))
def enableToolBar(self, item): def enableToolBar(self, item):
""" """
@ -580,10 +559,7 @@ class SlideController(QtGui.QWidget):
slideno = 0 slideno = 0
# If service item is the same as the current on only change slide # If service item is the same as the current on only change slide
if item.__eq__(self.serviceItem): if item.__eq__(self.serviceItem):
if slideno + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(slideno)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(slideno + 1, 0))
self.previewListWidget.selectRow(slideno)
self.onSlideSelected() self.onSlideSelected()
return return
self._processItem(item, slideno) self._processItem(item, slideno)
@ -611,7 +587,7 @@ class SlideController(QtGui.QWidget):
Receiver.send_message(u'%s_start' % serviceItem.name.lower(), Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
[serviceItem, self.isLive, blanked, slideno]) [serviceItem, self.isLive, blanked, slideno])
self.slideList = {} self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split] width = self.parent.controlSplitter.sizes()[self.split]
self.serviceItem = serviceItem self.serviceItem = serviceItem
self.previewListWidget.clear() self.previewListWidget.clear()
self.previewListWidget.setRowCount(0) self.previewListWidget.setRowCount(0)
@ -663,14 +639,7 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.resizeRowsToContents() self.previewListWidget.resizeRowsToContents()
self.previewListWidget.setColumnWidth(0, self.previewListWidget.setColumnWidth(0,
self.previewListWidget.viewport().size().width()) self.previewListWidget.viewport().size().width())
if slideno > self.previewListWidget.rowCount(): self.__updatePreviewSelection(slideno)
self.previewListWidget.selectRow(
self.previewListWidget.rowCount() - 1)
else:
if slideno + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(slideno + 1, 0))
self.previewListWidget.selectRow(slideno)
self.enableToolBar(serviceItem) self.enableToolBar(serviceItem)
# Pass to display for viewing # Pass to display for viewing
self.display.buildHtml(self.serviceItem) self.display.buildHtml(self.serviceItem)
@ -681,6 +650,16 @@ class SlideController(QtGui.QWidget):
Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix, Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix,
[serviceItem]) [serviceItem])
def __updatePreviewSelection(self, slideno):
"""
Utility method to update the selected slide in the list.
"""
if slideno > self.previewListWidget.rowCount():
self.previewListWidget.selectRow(
self.previewListWidget.rowCount() - 1)
else:
self.__checkUpdateSelectedSlide(slideno)
def onTextRequest(self): def onTextRequest(self):
""" """
Return the text for the current item in controller Return the text for the current item in controller
@ -728,10 +707,7 @@ class SlideController(QtGui.QWidget):
[self.serviceItem, self.isLive, index]) [self.serviceItem, self.isLive, index])
self.updatePreview() self.updatePreview()
else: else:
if index + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(index)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(index + 1, 0))
self.previewListWidget.selectRow(index)
self.onSlideSelected() self.onSlideSelected()
def mainDisplaySetBackground(self): def mainDisplaySetBackground(self):
@ -890,10 +866,7 @@ class SlideController(QtGui.QWidget):
""" """
The slide has been changed. Update the slidecontroller accordingly The slide has been changed. Update the slidecontroller accordingly
""" """
if row + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(row)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
self.updatePreview() self.updatePreview()
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix, Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row) row)
@ -904,7 +877,8 @@ class SlideController(QtGui.QWidget):
using *Blank to Theme*. using *Blank to Theme*.
""" """
log.debug(u'updatePreview %s ' % self.screens.current[u'primary']) log.debug(u'updatePreview %s ' % self.screens.current[u'primary'])
if not self.screens.current[u'primary']: if not self.screens.current[u'primary'] and self.serviceItem and \
self.serviceItem.is_capable(ItemCapabilities.ProvidesOwnDisplay):
# 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)
@ -944,10 +918,7 @@ class SlideController(QtGui.QWidget):
else: else:
Receiver.send_message('servicemanager_next_item') Receiver.send_message('servicemanager_next_item')
return return
if row + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(row)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
self.onSlideSelected() self.onSlideSelected()
def onSlideSelectedPreviousNoloop(self): def onSlideSelectedPreviousNoloop(self):
@ -970,12 +941,15 @@ class SlideController(QtGui.QWidget):
row = self.previewListWidget.rowCount() - 1 row = self.previewListWidget.rowCount() - 1
else: else:
row = 0 row = 0
if row + 1 < self.previewListWidget.rowCount(): self.__checkUpdateSelectedSlide(row)
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
self.onSlideSelected() self.onSlideSelected()
def __checkUpdateSelectedSlide(self, row):
if row + 1 < self.previewListWidget.rowCount():
self.previewListWidget.scrollToItem(
self.previewListWidget.item(row + 1, 0))
self.previewListWidget.selectRow(row)
def onSlideSelectedLast(self): def onSlideSelectedLast(self):
""" """
Go to the last slide. Go to the last slide.
@ -997,7 +971,7 @@ class SlideController(QtGui.QWidget):
""" """
if self.previewListWidget.rowCount() > 1: if self.previewListWidget.rowCount() > 1:
self.timer_id = self.startTimer( self.timer_id = self.startTimer(
int(self.DelaySpinBox.value()) * 1000) int(self.delaySpinBox.value()) * 1000)
self.toolbar.actions[u'Stop Loop'].setVisible(True) self.toolbar.actions[u'Stop Loop'].setVisible(True)
self.toolbar.actions[u'Start Loop'].setVisible(False) self.toolbar.actions[u'Start Loop'].setVisible(False)

View File

@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 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
from openlp.core.lib.ui import create_accept_reject_button_box
class Ui_StartTimeDialog(object):
def setupUi(self, StartTimeDialog):
StartTimeDialog.setObjectName(u'StartTimeDialog')
StartTimeDialog.resize(300, 10)
self.dialogLayout = QtGui.QGridLayout(StartTimeDialog)
self.dialogLayout.setObjectName(u'dialogLayout')
self.hourLabel = QtGui.QLabel(StartTimeDialog)
self.hourLabel.setObjectName("hourLabel")
self.dialogLayout.addWidget(self.hourLabel, 0, 0, 1, 1)
self.hourSpinBox = QtGui.QSpinBox(StartTimeDialog)
self.hourSpinBox.setObjectName("hourSpinBox")
self.dialogLayout.addWidget(self.hourSpinBox, 0, 1, 1, 1)
self.minuteLabel = QtGui.QLabel(StartTimeDialog)
self.minuteLabel.setObjectName("minuteLabel")
self.dialogLayout.addWidget(self.minuteLabel, 1, 0, 1, 1)
self.minuteSpinBox = QtGui.QSpinBox(StartTimeDialog)
self.minuteSpinBox.setObjectName("minuteSpinBox")
self.dialogLayout.addWidget(self.minuteSpinBox, 1, 1, 1, 1)
self.secondLabel = QtGui.QLabel(StartTimeDialog)
self.secondLabel.setObjectName("secondLabel")
self.dialogLayout.addWidget(self.secondLabel, 2, 0, 1, 1)
self.secondSpinBox = QtGui.QSpinBox(StartTimeDialog)
self.secondSpinBox.setObjectName("secondSpinBox")
self.dialogLayout.addWidget(self.secondSpinBox, 2, 1, 1, 1)
self.buttonBox = create_accept_reject_button_box(StartTimeDialog, True)
self.dialogLayout.addWidget(self.buttonBox, 4, 0, 1, 2)
self.retranslateUi(StartTimeDialog)
self.setMaximumHeight(self.sizeHint().height())
QtCore.QMetaObject.connectSlotsByName(StartTimeDialog)
def retranslateUi(self, StartTimeDialog):
self.setWindowTitle(translate('OpenLP.StartTimeForm',
'Item Start Time'))
self.hourLabel.setText(translate('OpenLP.StartTimeForm', 'Hours:'))
self.hourSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'h'))
self.minuteSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'm'))
self.secondSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 's'))
self.minuteLabel.setText(translate('OpenLP.StartTimeForm', 'Minutes:'))
self.secondLabel.setText(translate('OpenLP.StartTimeForm', 'Seconds:'))

View File

@ -24,25 +24,29 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from PyQt4 import QtCore, QtGui from PyQt4 import QtGui
from openlp.core.lib import translate
class Ui_ServiceNoteEdit(object): from starttimedialog import Ui_StartTimeDialog
def setupUi(self, serviceNoteEdit):
serviceNoteEdit.setObjectName(u'serviceNoteEdit') class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
self.dialogLayout = QtGui.QVBoxLayout(serviceNoteEdit) """
self.dialogLayout.setObjectName(u'verticalLayout') The exception dialog
self.textEdit = QtGui.QTextEdit(serviceNoteEdit) """
self.textEdit.setObjectName(u'textEdit') def __init__(self, parent):
self.dialogLayout.addWidget(self.textEdit) QtGui.QDialog.__init__(self, parent)
self.buttonBox = QtGui.QDialogButtonBox(serviceNoteEdit) self.setupUi(self)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save) def exec_(self):
self.buttonBox.setObjectName(u'buttonBox') """
self.dialogLayout.addWidget(self.buttonBox) Run the Dialog with correct heading.
self.retranslateUi(serviceNoteEdit) """
QtCore.QMetaObject.connectSlotsByName(serviceNoteEdit) seconds = self.item[u'service_item'].start_time
hours = seconds / 3600
seconds -= 3600 * hours
minutes = seconds / 60
seconds -= 60 * minutes
self.hourSpinBox.setValue(hours)
self.minuteSpinBox.setValue(minutes)
self.secondSpinBox.setValue(seconds)
return QtGui.QDialog.exec_(self)
def retranslateUi(self, serviceNoteEdit):
serviceNoteEdit.setWindowTitle(
translate('OpenLP.ServiceNoteForm', 'Service Item Notes'))

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \ from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \
Receiver Receiver
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.utils import get_images_filter from openlp.core.utils import get_images_filter
from themewizard import Ui_ThemeWizard from themewizard import Ui_ThemeWizard
@ -55,7 +55,6 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
self.thememanager = parent self.thememanager = parent
self.setupUi(self) self.setupUi(self)
self.registerFields() self.registerFields()
self.accepted = False
self.updateThemeAllowed = True self.updateThemeAllowed = True
QtCore.QObject.connect(self.backgroundComboBox, QtCore.QObject.connect(self.backgroundComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'), QtCore.SIGNAL(u'currentIndexChanged(int)'),
@ -120,14 +119,12 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
QtCore.QObject.connect(self.mainFontComboBox, QtCore.QObject.connect(self.mainFontComboBox,
QtCore.SIGNAL(u'activated(int)'), QtCore.SIGNAL(u'activated(int)'),
self.calculateLines) self.calculateLines)
QtCore.QObject.connect(self, QtCore.SIGNAL(u'accepted()'), self.accept)
def setDefaults(self): def setDefaults(self):
""" """
Set up display at start of theme edit. Set up display at start of theme edit.
""" """
self.restart() self.restart()
self.accepted = False
self.setBackgroundPageValues() self.setBackgroundPageValues()
self.setMainAreaPageValues() self.setMainAreaPageValues()
self.setFooterAreaPageValues() self.setFooterAreaPageValues()
@ -250,37 +247,43 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
""" """
Change state as Outline check box changed Change state as Outline check box changed
""" """
if state == QtCore.Qt.Checked: if self.updateThemeAllowed:
self.theme.font_main_outline = True if state == QtCore.Qt.Checked:
else: self.theme.font_main_outline = True
self.theme.font_main_outline = False else:
self.outlineColorButton.setEnabled(self.theme.font_main_outline) self.theme.font_main_outline = False
self.outlineSizeSpinBox.setEnabled(self.theme.font_main_outline) self.outlineColorButton.setEnabled(self.theme.font_main_outline)
self.calculateLines() self.outlineSizeSpinBox.setEnabled(self.theme.font_main_outline)
self.calculateLines()
def onShadowCheckCheckBoxStateChanged(self, state): def onShadowCheckCheckBoxStateChanged(self, state):
""" """
Change state as Shadow check box changed Change state as Shadow check box changed
""" """
if state == QtCore.Qt.Checked: if self.updateThemeAllowed:
self.theme.font_main_shadow = True if state == QtCore.Qt.Checked:
else: self.theme.font_main_shadow = True
self.theme.font_main_shadow = False else:
self.shadowColorButton.setEnabled(self.theme.font_main_shadow) self.theme.font_main_shadow = False
self.shadowSizeSpinBox.setEnabled(self.theme.font_main_shadow) self.shadowColorButton.setEnabled(self.theme.font_main_shadow)
self.calculateLines() self.shadowSizeSpinBox.setEnabled(self.theme.font_main_shadow)
self.calculateLines()
def onMainPositionCheckBoxStateChanged(self, value): def onMainPositionCheckBoxStateChanged(self, value):
""" """
Change state as Main Area Position check box changed Change state as Main Area Position check box changed
NOTE the font_main_override is the inverse of the check box value
""" """
self.theme.font_main_override = (value == QtCore.Qt.Checked) if self.updateThemeAllowed:
self.theme.font_main_override = not (value == QtCore.Qt.Checked)
def onFooterPositionCheckBoxStateChanged(self, value): def onFooterPositionCheckBoxStateChanged(self, value):
""" """
Change state as Footer Area Position check box changed Change state as Footer Area Position check box changed
NOTE the font_footer_override is the inverse of the check box value
""" """
self.theme.font_footer_override = (value == QtCore.Qt.Checked) if self.updateThemeAllowed:
self.theme.font_footer_override = not (value == QtCore.Qt.Checked)
def exec_(self, edit=False): def exec_(self, edit=False):
""" """
@ -446,9 +449,10 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
""" """
Background gradient Combo box has changed. Background gradient Combo box has changed.
""" """
self.theme.background_direction = \ if self.updateThemeAllowed:
BackgroundGradientType.to_string(index) self.theme.background_direction = \
self.setBackgroundPageValues() BackgroundGradientType.to_string(index)
self.setBackgroundPageValues()
def onColorButtonClicked(self): def onColorButtonClicked(self):
""" """
@ -479,8 +483,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
Background Image button pushed. Background Image button pushed.
""" """
images_filter = get_images_filter() images_filter = get_images_filter()
images_filter = '%s;;%s (*.*) (*)' % (images_filter, images_filter = u'%s;;%s (*.*) (*)' % (
translate('OpenLP.ThemeForm', 'All Files')) images_filter, UiStrings.AllFiles)
filename = QtGui.QFileDialog.getOpenFileName(self, filename = QtGui.QFileDialog.getOpenFileName(self,
translate('OpenLP.ThemeForm', 'Select Image'), u'', translate('OpenLP.ThemeForm', 'Select Image'), u'',
images_filter) images_filter)
@ -560,21 +564,16 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
""" """
Lets save the them as Finish has been pressed 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 # Save the theme name
self.theme.theme_name = \ self.theme.theme_name = unicode(self.field(u'name').toString())
unicode(self.field(u'name').toString())
if not self.theme.theme_name: if not self.theme.theme_name:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeForm', 'Theme Name Missing'), translate('OpenLP.ThemeForm', 'Theme Name Missing'),
translate('OpenLP.ThemeForm', translate('OpenLP.ThemeForm',
'There is no name for this theme. Please enter one.')) 'There is no name for this theme. Please enter one.'))
return return
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None': if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None':
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeForm', 'Theme Name Invalid'), translate('OpenLP.ThemeForm', 'Theme Name Invalid'),
translate('OpenLP.ThemeForm', translate('OpenLP.ThemeForm',
'Invalid theme name. Please enter one.')) 'Invalid theme name. Please enter one.'))
@ -590,7 +589,6 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
if not self.edit_mode and \ if not self.edit_mode and \
not self.thememanager.checkIfThemeExists(self.theme.theme_name): not self.thememanager.checkIfThemeExists(self.theme.theme_name):
return return
self.accepted = True
self.thememanager.saveTheme(self.theme, saveFrom, saveTo) self.thememanager.saveTheme(self.theme, saveFrom, saveTo)
return QtGui.QDialog.accept(self) return QtGui.QDialog.accept(self)

View File

@ -32,11 +32,13 @@ 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 criticalErrorMessageBox, FileRenameForm, ThemeForm
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, check_directory_exists BackgroundType, BackgroundGradientType, check_directory_exists, \
VerticalType
from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.theme import Theme
from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
get_filesystem_encoding get_filesystem_encoding
@ -240,7 +242,7 @@ class ThemeManager(QtGui.QWidget):
QtCore.QVariant(self.global_theme)) QtCore.QVariant(self.global_theme))
Receiver.send_message(u'theme_update_global', Receiver.send_message(u'theme_update_global',
self.global_theme) self.global_theme)
self.pushThemes() self._pushThemes()
def onAddTheme(self): def onAddTheme(self):
""" """
@ -259,7 +261,7 @@ class ThemeManager(QtGui.QWidget):
'You must select a theme to rename.')), 'You must select a theme to rename.')),
unicode(translate('OpenLP.ThemeManager', 'Rename Confirmation')), unicode(translate('OpenLP.ThemeManager', 'Rename Confirmation')),
unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')), unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')),
False): False, False):
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
self.fileRenameForm.fileNameEdit.setText(oldThemeName) self.fileRenameForm.fileNameEdit.setText(oldThemeName)
@ -267,11 +269,12 @@ class ThemeManager(QtGui.QWidget):
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text()) newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
if self.checkIfThemeExists(newThemeName): if self.checkIfThemeExists(newThemeName):
oldThemeData = self.getThemeData(oldThemeName) oldThemeData = self.getThemeData(oldThemeName)
self.deleteTheme(oldThemeName)
self.cloneThemeData(oldThemeData, newThemeName) self.cloneThemeData(oldThemeData, newThemeName)
self.deleteTheme(oldThemeName)
for plugin in self.mainwindow.pluginManager.plugins: for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(oldThemeName): if plugin.usesTheme(oldThemeName):
plugin.renameTheme(oldThemeName, newThemeName) plugin.renameTheme(oldThemeName, newThemeName)
self.loadThemes()
def onCopyTheme(self): def onCopyTheme(self):
""" """
@ -299,6 +302,7 @@ class ThemeManager(QtGui.QWidget):
os.path.split(unicode(themeData.background_filename))[1]) os.path.split(unicode(themeData.background_filename))[1])
saveFrom = themeData.background_filename saveFrom = themeData.background_filename
themeData.theme_name = newThemeName themeData.theme_name = newThemeName
themeData.extend_image_filename(self.path)
self.saveTheme(themeData, saveFrom, saveTo) self.saveTheme(themeData, saveFrom, saveTo)
def onEditTheme(self): def onEditTheme(self):
@ -310,7 +314,6 @@ class ThemeManager(QtGui.QWidget):
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
'You must select a theme to edit.')): 'You must select a theme to edit.')):
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
themeName = unicode(item.text())
theme = self.getThemeData( theme = self.getThemeData(
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':
@ -331,6 +334,9 @@ class ThemeManager(QtGui.QWidget):
row = self.themeListWidget.row(item) row = self.themeListWidget.row(item)
self.themeListWidget.takeItem(row) self.themeListWidget.takeItem(row)
self.deleteTheme(theme) self.deleteTheme(theme)
# As we do not reload the themes, push out the change. Reload the
# list as the internal lists and events need to be triggered.
self._pushThemes()
def deleteTheme(self, theme): def deleteTheme(self, theme):
""" """
@ -348,10 +354,6 @@ class ThemeManager(QtGui.QWidget):
shutil.rmtree(os.path.join(self.path, theme).encode(encoding)) shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
except OSError: except OSError:
log.exception(u'Error deleting theme %s', theme) log.exception(u'Error deleting theme %s', theme)
# As we do not reload the themes push out the change
# Reaload the list as the internal lists and events need
# to be triggered
self.pushThemes()
def onExportTheme(self): def onExportTheme(self):
""" """
@ -359,7 +361,7 @@ class ThemeManager(QtGui.QWidget):
""" """
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
if item is None: if item is None:
criticalErrorMessageBox(message=translate('OpenLP.ThemeManager', critical_error_message_box(message=translate('OpenLP.ThemeManager',
'You have not selected a theme.')) 'You have not selected a theme.'))
return return
theme = unicode(item.data(QtCore.Qt.UserRole).toString()) theme = unicode(item.data(QtCore.Qt.UserRole).toString())
@ -386,7 +388,7 @@ class ThemeManager(QtGui.QWidget):
'Your theme has been successfully exported.')) 'Your theme has been successfully exported.'))
except (IOError, OSError): except (IOError, OSError):
log.exception(u'Export Theme Failed') log.exception(u'Export Theme Failed')
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Theme Export Failed'), translate('OpenLP.ThemeManager', 'Theme Export Failed'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
'Your theme could not be exported due to an error.')) 'Your theme could not be exported due to an error.'))
@ -403,8 +405,8 @@ class ThemeManager(QtGui.QWidget):
files = QtGui.QFileDialog.getOpenFileNames(self, files = QtGui.QFileDialog.getOpenFileNames(self,
translate('OpenLP.ThemeManager', 'Select Theme Import File'), translate('OpenLP.ThemeManager', 'Select Theme Import File'),
SettingsManager.get_last_dir(self.settingsSection), SettingsManager.get_last_dir(self.settingsSection),
translate('OpenLP.ThemeManager', 'Theme v1 (*.theme);;' unicode(translate('OpenLP.ThemeManager',
'Theme v2 (*.otz);;All Files (*.*)')) 'OpenLP Themes (*.theme *.otz)')))
log.info(u'New Themes %s', unicode(files)) log.info(u'New Themes %s', unicode(files))
if files: if files:
for file in files: for file in files:
@ -448,9 +450,9 @@ class ThemeManager(QtGui.QWidget):
QtCore.QVariant(textName)) QtCore.QVariant(textName))
self.themeListWidget.addItem(item_name) self.themeListWidget.addItem(item_name)
self.themelist.append(textName) self.themelist.append(textName)
self.pushThemes() self._pushThemes()
def pushThemes(self): def _pushThemes(self):
""" """
Notify listeners that the theme list has been updated Notify listeners that the theme list has been updated
""" """
@ -496,7 +498,7 @@ class ThemeManager(QtGui.QWidget):
for file in zip.namelist(): for file in zip.namelist():
ucsfile = file_is_unicode(file) ucsfile = file_is_unicode(file)
if not ucsfile: if not ucsfile:
criticalErrorMessageBox( critical_error_message_box(
message=translate('OpenLP.ThemeManager', message=translate('OpenLP.ThemeManager',
'File is not a valid theme.\n' 'File is not a valid theme.\n'
'The content encoding is not UTF-8.')) 'The content encoding is not UTF-8.'))
@ -531,14 +533,14 @@ class ThemeManager(QtGui.QWidget):
theme = self._createThemeFromXml(filexml, self.path) theme = self._createThemeFromXml(filexml, self.path)
self.generateAndSaveImage(dir, themename, theme) self.generateAndSaveImage(dir, themename, theme)
else: else:
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
'File is not a valid theme.')) 'File is not a valid theme.'))
log.exception(u'Theme file does not contain XML data %s' % log.exception(u'Theme file does not contain XML data %s' %
filename) filename)
except (IOError, NameError): except (IOError, NameError):
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
'File is not a valid theme.')) 'File is not a valid theme.'))
@ -558,7 +560,7 @@ class ThemeManager(QtGui.QWidget):
""" """
theme_dir = os.path.join(self.path, themeName) theme_dir = os.path.join(self.path, themeName)
if os.path.exists(theme_dir): if os.path.exists(theme_dir):
criticalErrorMessageBox( critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'), translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
'A theme with this name already exists.')) 'A theme with this name already exists.'))
@ -570,6 +572,14 @@ class ThemeManager(QtGui.QWidget):
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
""" """
self._writeTheme(theme, imageFrom, imageTo)
self.loadThemes()
def _writeTheme(self, theme, imageFrom, imageTo):
"""
Writes the theme to the disk and handles the background image if
necessary
"""
name = theme.theme_name name = theme.theme_name
theme_pretty_xml = theme.extract_formatted_xml() theme_pretty_xml = theme.extract_formatted_xml()
log.debug(u'saveTheme %s %s', name, theme_pretty_xml) log.debug(u'saveTheme %s %s', name, theme_pretty_xml)
@ -597,12 +607,9 @@ class ThemeManager(QtGui.QWidget):
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) self.generateAndSaveImage(self.path, name, theme)
self.loadThemes()
self.pushThemes()
def generateAndSaveImage(self, dir, name, theme): def generateAndSaveImage(self, dir, name, theme):
log.debug(u'generateAndSaveImage %s %s', dir, name) log.debug(u'generateAndSaveImage %s %s', dir, name)
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):
@ -668,7 +675,7 @@ class ThemeManager(QtGui.QWidget):
return theme return theme
def _validate_theme_action(self, select_text, confirm_title, confirm_text, def _validate_theme_action(self, select_text, confirm_title, confirm_text,
testPlugin=True): testPlugin=True, confirm=True):
""" """
Check to see if theme has been selected and the destructive action Check to see if theme has been selected and the destructive action
is allowed. is allowed.
@ -680,15 +687,16 @@ class ThemeManager(QtGui.QWidget):
item = self.themeListWidget.currentItem() item = self.themeListWidget.currentItem()
theme = unicode(item.text()) theme = unicode(item.text())
# confirm deletion # confirm deletion
answer = QtGui.QMessageBox.question(self, confirm_title, if confirm:
confirm_text % theme, QtGui.QMessageBox.StandardButtons( answer = QtGui.QMessageBox.question(self, confirm_title,
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), confirm_text % theme, QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.No) QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
if answer == QtGui.QMessageBox.No: QtGui.QMessageBox.No)
return False if answer == QtGui.QMessageBox.No:
return False
# should be the same unless default # should be the same unless default
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()): if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
criticalErrorMessageBox( critical_error_message_box(
message=translate('OpenLP.ThemeManager', message=translate('OpenLP.ThemeManager',
'You are unable to delete the default theme.')) 'You are unable to delete the default theme.'))
return False return False
@ -696,7 +704,8 @@ class ThemeManager(QtGui.QWidget):
if testPlugin: if testPlugin:
for plugin in self.mainwindow.pluginManager.plugins: for plugin in self.mainwindow.pluginManager.plugins:
if plugin.usesTheme(theme): if plugin.usesTheme(theme):
criticalErrorMessageBox(translate('OpenLP.ThemeManager', critical_error_message_box(
translate('OpenLP.ThemeManager',
'Validation Error'), 'Validation Error'),
unicode(translate('OpenLP.ThemeManager', unicode(translate('OpenLP.ThemeManager',
'Theme %s is used in the %s plugin.')) % \ 'Theme %s is used in the %s plugin.')) % \
@ -753,11 +762,11 @@ class ThemeManager(QtGui.QWidget):
newtheme.font_main_outline = True newtheme.font_main_outline = True
newtheme.font_main_outline_color = \ newtheme.font_main_outline_color = \
unicode(theme.OutlineColor.name()) unicode(theme.OutlineColor.name())
vAlignCorrection = 0 vAlignCorrection = VerticalType.Top
if theme.VerticalAlign == 2: if theme.VerticalAlign == 2:
vAlignCorrection = 1 vAlignCorrection = VerticalType.Middle
elif theme.VerticalAlign == 1: elif theme.VerticalAlign == 1:
vAlignCorrection = 2 vAlignCorrection = VerticalType.Bottom
newtheme.display_horizontal_align = theme.HorizontalAlign newtheme.display_horizontal_align = theme.HorizontalAlign
newtheme.display_vertical_align = vAlignCorrection newtheme.display_vertical_align = vAlignCorrection
return newtheme.extract_xml() return newtheme.extract_xml()

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, Receiver, ThemeLevel, translate from openlp.core.lib import SettingsTab, Receiver, ThemeLevel, translate
from openlp.core.lib.ui import UiStrings
class ThemesTab(SettingsTab): class ThemesTab(SettingsTab):
""" """
@ -98,7 +99,7 @@ class ThemesTab(SettingsTab):
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
def retranslateUi(self): def retranslateUi(self):
self.tabTitleVisible = translate('OpenLP.ThemesTab', 'Themes') self.tabTitleVisible = UiStrings.Themes
self.GlobalGroupBox.setTitle( self.GlobalGroupBox.setTitle(
translate('OpenLP.ThemesTab', 'Global Theme')) translate('OpenLP.ThemesTab', 'Global Theme'))
self.LevelGroupBox.setTitle( self.LevelGroupBox.setTitle(
@ -165,13 +166,7 @@ class ThemesTab(SettingsTab):
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( self.__previewGlobalTheme()
self.global_theme)
preview = QtGui.QPixmap(unicode(image))
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(preview)
def updateThemeList(self, theme_list): def updateThemeList(self, theme_list):
""" """
@ -198,10 +193,16 @@ class ThemesTab(SettingsTab):
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( self.__previewGlobalTheme()
self.global_theme)
preview = QtGui.QPixmap(unicode(image)) def __previewGlobalTheme(self):
if not preview.isNull(): """
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio, Utility method to update the global theme preview image.
QtCore.Qt.SmoothTransformation) """
self.DefaultListView.setPixmap(preview) image = self.parent.ThemeManagerContents.getPreviewImage(
self.global_theme)
preview = QtGui.QPixmap(unicode(image))
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
self.DefaultListView.setPixmap(preview)

View File

@ -27,32 +27,19 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, build_icon from openlp.core.lib import translate, build_icon
from openlp.core.lib.ui import add_welcome_page, create_valign_combo
class Ui_ThemeWizard(object): class Ui_ThemeWizard(object):
def setupUi(self, ThemeWizard): def setupUi(self, themeWizard):
ThemeWizard.setObjectName(u'OpenLP.ThemeWizard') themeWizard.setObjectName(u'OpenLP.ThemeWizard')
ThemeWizard.setModal(True) themeWizard.setModal(True)
ThemeWizard.setWizardStyle(QtGui.QWizard.ModernStyle) themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
ThemeWizard.setOptions( themeWizard.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage) QtGui.QWizard.NoBackButtonOnStartPage)
self.spacer = QtGui.QSpacerItem(10, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
# Welcome Page # Welcome Page
self.welcomePage = QtGui.QWizardPage() add_welcome_page(themeWizard, u':/wizards/wizard_createtheme.bmp')
self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
QtGui.QPixmap(u':/wizards/wizard_createtheme.bmp'))
self.welcomePage.setObjectName(u'WelcomePage')
self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
self.welcomeLayout.setObjectName(u'WelcomeLayout')
self.titleLabel = QtGui.QLabel(self.welcomePage)
self.titleLabel.setObjectName(u'TitleLabel')
self.welcomeLayout.addWidget(self.titleLabel)
self.welcomeLayout.addSpacing(40)
self.informationLabel = QtGui.QLabel(self.welcomePage)
self.informationLabel.setWordWrap(True)
self.informationLabel.setObjectName(u'InformationLabel')
self.welcomeLayout.addWidget(self.informationLabel)
self.welcomeLayout.addStretch()
ThemeWizard.addPage(self.welcomePage)
# Background Page # Background Page
self.backgroundPage = QtGui.QWizardPage() self.backgroundPage = QtGui.QWizardPage()
self.backgroundPage.setObjectName(u'BackgroundPage') self.backgroundPage.setObjectName(u'BackgroundPage')
@ -67,10 +54,8 @@ class Ui_ThemeWizard(object):
self.backgroundComboBox.setObjectName(u'BackgroundComboBox') self.backgroundComboBox.setObjectName(u'BackgroundComboBox')
self.backgroundTypeLayout.addRow(self.backgroundLabel, self.backgroundTypeLayout.addRow(self.backgroundLabel,
self.backgroundComboBox) self.backgroundComboBox)
self.backgroundTypeSpacer = QtGui.QSpacerItem(10, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
self.backgroundTypeLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.backgroundTypeLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.backgroundTypeSpacer) self.spacer)
self.backgroundLayout.addLayout(self.backgroundTypeLayout) self.backgroundLayout.addLayout(self.backgroundTypeLayout)
self.backgroundStack = QtGui.QStackedLayout() self.backgroundStack = QtGui.QStackedLayout()
self.backgroundStack.setObjectName(u'BackgroundStack') self.backgroundStack.setObjectName(u'BackgroundStack')
@ -84,10 +69,7 @@ class Ui_ThemeWizard(object):
self.colorButton = QtGui.QPushButton(self.colorWidget) self.colorButton = QtGui.QPushButton(self.colorWidget)
self.colorButton.setObjectName(u'ColorButton') self.colorButton.setObjectName(u'ColorButton')
self.colorLayout.addRow(self.colorLabel, self.colorButton) self.colorLayout.addRow(self.colorLabel, self.colorButton)
self.colorSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.colorLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.colorLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.colorSpacer)
self.backgroundStack.addWidget(self.colorWidget) self.backgroundStack.addWidget(self.colorWidget)
self.gradientWidget = QtGui.QWidget(self.backgroundPage) self.gradientWidget = QtGui.QWidget(self.backgroundPage)
self.gradientWidget.setObjectName(u'GradientWidget') self.gradientWidget.setObjectName(u'GradientWidget')
@ -113,10 +95,7 @@ class Ui_ThemeWizard(object):
self.gradientComboBox.addItems([u'', u'', u'', u'', u'']) self.gradientComboBox.addItems([u'', u'', u'', u'', u''])
self.gradientLayout.addRow(self.gradientTypeLabel, self.gradientLayout.addRow(self.gradientTypeLabel,
self.gradientComboBox) self.gradientComboBox)
self.gradientSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.gradientLayout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.gradientLayout.setItem(3, QtGui.QFormLayout.LabelRole,
self.gradientSpacer)
self.backgroundStack.addWidget(self.gradientWidget) self.backgroundStack.addWidget(self.gradientWidget)
self.imageWidget = QtGui.QWidget(self.backgroundPage) self.imageWidget = QtGui.QWidget(self.backgroundPage)
self.imageWidget.setObjectName(u'ImageWidget') self.imageWidget.setObjectName(u'ImageWidget')
@ -136,13 +115,10 @@ class Ui_ThemeWizard(object):
build_icon(u':/general/general_open.png')) build_icon(u':/general/general_open.png'))
self.imageFileLayout.addWidget(self.imageBrowseButton) self.imageFileLayout.addWidget(self.imageBrowseButton)
self.imageLayout.addRow(self.imageLabel, self.imageFileLayout) self.imageLayout.addRow(self.imageLabel, self.imageFileLayout)
self.imageSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.imageSpacer)
self.backgroundStack.addWidget(self.imageWidget) self.backgroundStack.addWidget(self.imageWidget)
self.backgroundLayout.addLayout(self.backgroundStack) self.backgroundLayout.addLayout(self.backgroundStack)
ThemeWizard.addPage(self.backgroundPage) themeWizard.addPage(self.backgroundPage)
# Main Area Page # Main Area Page
self.mainAreaPage = QtGui.QWizardPage() self.mainAreaPage = QtGui.QWizardPage()
self.mainAreaPage.setObjectName(u'MainAreaPage') self.mainAreaPage.setObjectName(u'MainAreaPage')
@ -225,7 +201,7 @@ class Ui_ThemeWizard(object):
self.shadowSizeSpinBox.setObjectName(u'ShadowSizeSpinBox') self.shadowSizeSpinBox.setObjectName(u'ShadowSizeSpinBox')
self.shadowLayout.addWidget(self.shadowSizeSpinBox) self.shadowLayout.addWidget(self.shadowSizeSpinBox)
self.mainAreaLayout.addRow(self.shadowCheckBox, self.shadowLayout) self.mainAreaLayout.addRow(self.shadowCheckBox, self.shadowLayout)
ThemeWizard.addPage(self.mainAreaPage) themeWizard.addPage(self.mainAreaPage)
# Footer Area Page # Footer Area Page
self.footerAreaPage = QtGui.QWizardPage() self.footerAreaPage = QtGui.QWizardPage()
self.footerAreaPage.setObjectName(u'FooterAreaPage') self.footerAreaPage.setObjectName(u'FooterAreaPage')
@ -251,7 +227,9 @@ class Ui_ThemeWizard(object):
self.footerSizeSpinBox.setObjectName(u'FooterSizeSpinBox') self.footerSizeSpinBox.setObjectName(u'FooterSizeSpinBox')
self.footerAreaLayout.addRow(self.footerSizeLabel, self.footerAreaLayout.addRow(self.footerSizeLabel,
self.footerSizeSpinBox) self.footerSizeSpinBox)
ThemeWizard.addPage(self.footerAreaPage) self.footerAreaLayout.setItem(3, QtGui.QFormLayout.LabelRole,
self.spacer)
themeWizard.addPage(self.footerAreaPage)
# Alignment Page # Alignment Page
self.alignmentPage = QtGui.QWizardPage() self.alignmentPage = QtGui.QWizardPage()
self.alignmentPage.setObjectName(u'AlignmentPage') self.alignmentPage.setObjectName(u'AlignmentPage')
@ -264,19 +242,17 @@ class Ui_ThemeWizard(object):
self.horizontalComboBox.setObjectName(u'HorizontalComboBox') self.horizontalComboBox.setObjectName(u'HorizontalComboBox')
self.alignmentLayout.addRow(self.horizontalLabel, self.alignmentLayout.addRow(self.horizontalLabel,
self.horizontalComboBox) self.horizontalComboBox)
self.verticalLabel = QtGui.QLabel(self.alignmentPage) create_valign_combo(themeWizard, self.alignmentPage,
self.verticalLabel.setObjectName(u'VerticalLabel') self.alignmentLayout)
self.verticalComboBox = QtGui.QComboBox(self.alignmentPage)
self.verticalComboBox.addItems([u'', u'', u''])
self.verticalComboBox.setObjectName(u'VerticalComboBox')
self.alignmentLayout.addRow(self.verticalLabel, self.verticalComboBox)
self.transitionsLabel = QtGui.QLabel(self.alignmentPage) self.transitionsLabel = QtGui.QLabel(self.alignmentPage)
self.transitionsLabel.setObjectName(u'TransitionsLabel') self.transitionsLabel.setObjectName(u'TransitionsLabel')
self.transitionsCheckBox = QtGui.QCheckBox(self.alignmentPage) self.transitionsCheckBox = QtGui.QCheckBox(self.alignmentPage)
self.transitionsCheckBox.setObjectName(u'TransitionsCheckBox') self.transitionsCheckBox.setObjectName(u'TransitionsCheckBox')
self.alignmentLayout.addRow(self.transitionsLabel, self.alignmentLayout.addRow(self.transitionsLabel,
self.transitionsCheckBox) self.transitionsCheckBox)
ThemeWizard.addPage(self.alignmentPage) self.alignmentLayout.setItem(3, QtGui.QFormLayout.LabelRole,
self.spacer)
themeWizard.addPage(self.alignmentPage)
# Area Position Page # Area Position Page
self.areaPositionPage = QtGui.QWizardPage() self.areaPositionPage = QtGui.QWizardPage()
self.areaPositionPage.setObjectName(u'AreaPositionPage') self.areaPositionPage.setObjectName(u'AreaPositionPage')
@ -352,7 +328,7 @@ class Ui_ThemeWizard(object):
self.footerPositionLayout.addRow(self.footerHeightLabel, self.footerPositionLayout.addRow(self.footerHeightLabel,
self.footerHeightSpinBox) self.footerHeightSpinBox)
self.areaPositionLayout.addWidget(self.footerPositionGroupBox) self.areaPositionLayout.addWidget(self.footerPositionGroupBox)
ThemeWizard.addPage(self.areaPositionPage) themeWizard.addPage(self.areaPositionPage)
# Preview Page # Preview Page
self.previewPage = QtGui.QWizardPage() self.previewPage = QtGui.QWizardPage()
self.previewPage.setObjectName(u'PreviewPage') self.previewPage.setObjectName(u'PreviewPage')
@ -381,9 +357,8 @@ class Ui_ThemeWizard(object):
self.previewBoxLabel.setObjectName(u'PreviewBoxLabel') self.previewBoxLabel.setObjectName(u'PreviewBoxLabel')
self.previewAreaLayout.addWidget(self.previewBoxLabel) self.previewAreaLayout.addWidget(self.previewBoxLabel)
self.previewLayout.addWidget(self.previewArea) self.previewLayout.addWidget(self.previewArea)
ThemeWizard.addPage(self.previewPage) themeWizard.addPage(self.previewPage)
self.retranslateUi(themeWizard)
self.retranslateUi(ThemeWizard)
QtCore.QObject.connect(self.backgroundComboBox, QtCore.QObject.connect(self.backgroundComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'), self.backgroundStack, QtCore.SIGNAL(u'currentIndexChanged(int)'), self.backgroundStack,
QtCore.SLOT(u'setCurrentIndex(int)')) QtCore.SLOT(u'setCurrentIndex(int)'))
@ -423,10 +398,10 @@ class Ui_ThemeWizard(object):
QtCore.QObject.connect(self.footerPositionCheckBox, QtCore.QObject.connect(self.footerPositionCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.footerHeightSpinBox, QtCore.SIGNAL(u'toggled(bool)'), self.footerHeightSpinBox,
QtCore.SLOT(u'setDisabled(bool)')) QtCore.SLOT(u'setDisabled(bool)'))
QtCore.QMetaObject.connectSlotsByName(ThemeWizard) QtCore.QMetaObject.connectSlotsByName(themeWizard)
def retranslateUi(self, ThemeWizard): def retranslateUi(self, themeWizard):
ThemeWizard.setWindowTitle( themeWizard.setWindowTitle(
translate('OpenLP.ThemeWizard', 'Theme Wizard')) translate('OpenLP.ThemeWizard', 'Theme Wizard'))
self.titleLabel.setText( self.titleLabel.setText(
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \ u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
@ -471,8 +446,7 @@ class Ui_ThemeWizard(object):
self.mainAreaPage.setSubTitle( self.mainAreaPage.setSubTitle(
translate('OpenLP.ThemeWizard', 'Define the font and display ' translate('OpenLP.ThemeWizard', 'Define the font and display '
'characteristics for the Display text')) 'characteristics for the Display text'))
self.mainFontLabel.setText( self.mainFontLabel.setText(translate('OpenLP.ThemeWizard', 'Font:'))
translate('OpenLP.ThemeWizard', 'Font:'))
self.mainColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:')) self.mainColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
self.mainSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:')) self.mainSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.mainSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt')) self.mainSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
@ -486,8 +460,7 @@ class Ui_ThemeWizard(object):
self.shadowCheckBox.setText(translate('OpenLP.ThemeWizard', '&Shadow:')) self.shadowCheckBox.setText(translate('OpenLP.ThemeWizard', '&Shadow:'))
self.shadowSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:')) self.shadowSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
self.shadowSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt')) self.shadowSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
self.mainBoldCheckBox.setText( self.mainBoldCheckBox.setText(translate('OpenLP.ThemeWizard', 'Bold'))
translate('OpenLP.ThemeWizard', 'Bold'))
self.mainItalicsCheckBox.setText( self.mainItalicsCheckBox.setText(
translate('OpenLP.ThemeWizard', 'Italic')) translate('OpenLP.ThemeWizard', 'Italic'))
self.footerAreaPage.setTitle( self.footerAreaPage.setTitle(
@ -512,14 +485,6 @@ class Ui_ThemeWizard(object):
translate('OpenLP.ThemeWizard', 'Right')) translate('OpenLP.ThemeWizard', 'Right'))
self.horizontalComboBox.setItemText(2, self.horizontalComboBox.setItemText(2,
translate('OpenLP.ThemeWizard', 'Center')) 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.transitionsLabel.setText( self.transitionsLabel.setText(
translate('OpenLP.ThemeWizard', 'Transitions:')) translate('OpenLP.ThemeWizard', 'Transitions:'))
self.areaPositionPage.setTitle( self.areaPositionPage.setTitle(
@ -568,16 +533,6 @@ class Ui_ThemeWizard(object):
translate('OpenLP.ThemeWizard', 'Theme name:')) translate('OpenLP.ThemeWizard', 'Theme name:'))
# Align all QFormLayouts towards each other. # Align all QFormLayouts towards each other.
labelWidth = max(self.backgroundLabel.minimumSizeHint().width(), labelWidth = max(self.backgroundLabel.minimumSizeHint().width(),
self.colorLabel.minimumSizeHint().width(), self.horizontalLabel.minimumSizeHint().width())
self.gradientStartLabel.minimumSizeHint().width(), self.spacer.changeSize(labelWidth, 0,
self.gradientEndLabel.minimumSizeHint().width(),
self.gradientTypeLabel.minimumSizeHint().width(),
self.imageLabel.minimumSizeHint().width())
self.backgroundTypeSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.colorSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.gradientSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.imageSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)

View File

@ -27,10 +27,12 @@
The :mod:``wizard`` module provides generic wizard tools for OpenLP. The :mod:``wizard`` module provides generic wizard tools for OpenLP.
""" """
import logging import logging
import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, Receiver from openlp.core.lib import build_icon, Receiver, SettingsManager
from openlp.core.lib.ui import UiStrings, add_welcome_page
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -63,35 +65,17 @@ class OpenLPWizard(QtGui.QWizard):
self.setOptions(QtGui.QWizard.IndependentPages | self.setOptions(QtGui.QWizard.IndependentPages |
QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.NoBackButtonOnLastPage) QtGui.QWizard.NoBackButtonOnLastPage)
self.addWelcomePage(image) add_welcome_page(self, image)
self.addCustomPages() self.addCustomPages()
self.addProgressPage() self.addProgressPage()
self.retranslateUi() self.retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self) QtCore.QMetaObject.connectSlotsByName(self)
def addWelcomePage(self, image): def registerFields(self):
""" """
Add the opening welcome page to the wizard. Hook method for wizards to register any fields they need.
``image``
A splash image for the wizard
""" """
self.welcomePage = QtGui.QWizardPage() pass
self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
QtGui.QPixmap(image))
self.welcomePage.setObjectName(u'WelcomePage')
self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
self.welcomeLayout.setObjectName(u'WelcomeLayout')
self.titleLabel = QtGui.QLabel(self.welcomePage)
self.titleLabel.setObjectName(u'TitleLabel')
self.welcomeLayout.addWidget(self.titleLabel)
self.welcomeLayout.addSpacing(40)
self.informationLabel = QtGui.QLabel(self.welcomePage)
self.informationLabel.setWordWrap(True)
self.informationLabel.setObjectName(u'InformationLabel')
self.welcomeLayout.addWidget(self.informationLabel)
self.welcomeLayout.addStretch()
self.addPage(self.welcomePage)
def addProgressPage(self): def addProgressPage(self):
""" """
@ -169,3 +153,30 @@ class OpenLPWizard(QtGui.QWizard):
self.finishButton.setVisible(True) self.finishButton.setVisible(True)
self.cancelButton.setVisible(False) self.cancelButton.setVisible(False)
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
def getFileName(self, title, editbox, filters=u''):
"""
Opens a QFileDialog and saves the filename to the given editbox.
``title``
The title of the dialog (unicode).
``editbox``
A editbox (QLineEdit).
``filters``
The file extension filters. It should contain the file description
as well as the file extension. For example::
u'OpenLP 2.0 Databases (*.sqlite)'
"""
if filters:
filters += u';;'
filters += u'%s (*)' % UiStrings.AllFiles
filename = QtGui.QFileDialog.getOpenFileName(self, title,
os.path.dirname(SettingsManager.get_last_dir(
self.plugin.settingsSection, 1)), filters)
if filename:
editbox.setText(filename)
SettingsManager.set_last_dir(self.plugin.settingsSection,
filename, 1)

View File

@ -24,7 +24,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
""" """
The :mod:`utils` module provides the utility libraries for OpenLP The :mod:`openlp.core.utils` module provides the utility libraries for OpenLP.
""" """
import logging import logging
import os import os
@ -137,10 +137,7 @@ class AppLocation(object):
os.path.split(openlp.__file__)[0]) os.path.split(openlp.__file__)[0])
return os.path.join(app_path, u'i18n') return os.path.join(app_path, u'i18n')
else: else:
return _get_os_dir_path(u'openlp', return _get_os_dir_path(dir_type)
os.path.join(os.getenv(u'HOME'), u'Library',
u'Application Support', u'openlp'),
None, os.path.join(os.getenv(u'HOME'), u'.openlp'), dir_type)
@staticmethod @staticmethod
def get_data_path(): def get_data_path():
@ -163,27 +160,38 @@ class AppLocation(object):
os.makedirs(path) os.makedirs(path)
return path return path
def _get_os_dir_path(win_option, darwin_option, base_dir_option, def _get_os_dir_path(dir_type):
non_base_dir_option, dir_type=1):
""" """
Return a path based on which OS and environment we are running in. Return a path based on which OS and environment we are running in.
""" """
encoding = sys.getfilesystemencoding()
if sys.platform == u'win32': if sys.platform == u'win32':
return os.path.join(os.getenv(u'APPDATA'), win_option) if dir_type == AppLocation.DataDir:
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding),
u'openlp', u'data')
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding),
u'openlp')
elif sys.platform == u'darwin': elif sys.platform == u'darwin':
if dir_type == AppLocation.DataDir: if dir_type == AppLocation.DataDir:
return os.path.join(darwin_option, u'Data') return os.path.join(unicode(os.getenv(u'HOME'), encoding),
return darwin_option u'Library', u'Application Support', u'openlp', u'Data')
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
u'Library', u'Application Support', u'openlp')
else: else:
if XDG_BASE_AVAILABLE: if XDG_BASE_AVAILABLE:
if dir_type == AppLocation.ConfigDir: if dir_type == AppLocation.ConfigDir:
return os.path.join(BaseDirectory.xdg_config_home, u'openlp') return os.path.join(unicode(BaseDirectory.xdg_config_home,
encoding), u'openlp')
elif dir_type == AppLocation.DataDir: elif dir_type == AppLocation.DataDir:
return os.path.join(BaseDirectory.xdg_data_home, u'openlp') return os.path.join(
unicode(BaseDirectory.xdg_data_home, encoding), u'openlp')
elif dir_type == AppLocation.CacheDir: elif dir_type == AppLocation.CacheDir:
return os.path.join(BaseDirectory.xdg_cache_home, u'openlp') return os.path.join(unicode(BaseDirectory.xdg_cache_home,
else: encoding), u'openlp')
return non_base_dir_option if dir_type == AppLocation.DataDir:
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
u'.openlp', u'data')
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'.openlp')
def _get_frozen_path(frozen_option, non_frozen_option): def _get_frozen_path(frozen_option, non_frozen_option):
""" """
@ -191,8 +199,7 @@ def _get_frozen_path(frozen_option, non_frozen_option):
""" """
if hasattr(sys, u'frozen') and sys.frozen == 1: if hasattr(sys, u'frozen') and sys.frozen == 1:
return frozen_option return frozen_option
else: return non_frozen_option
return non_frozen_option
def check_latest_version(current_version): def check_latest_version(current_version):
""" """
@ -375,13 +382,13 @@ def get_uno_command():
""" """
Returns the UNO command to launch an openoffice.org instance. Returns the UNO command to launch an openoffice.org instance.
""" """
COMMAND = u'soffice'
OPTIONS = u'-nologo -norestore -minimized -invisible -nofirststartwizard'
if UNO_CONNECTION_TYPE == u'pipe': if UNO_CONNECTION_TYPE == u'pipe':
return u'openoffice.org -nologo -norestore -minimized -invisible ' \ CONNECTION = u'"-accept=pipe,name=openlp_pipe;urp;"'
+ u'-nofirststartwizard -accept=pipe,name=openlp_pipe;urp;'
else: else:
return u'openoffice.org -nologo -norestore -minimized ' \ CONNECTION = u'"-accept=socket,host=localhost,port=2002;urp;"'
+ u'-invisible -nofirststartwizard ' \ return u'%s %s %s' % (COMMAND, OPTIONS, CONNECTION)
+ u'-accept=socket,host=localhost,port=2002;urp;'
def get_uno_instance(resolver): def get_uno_instance(resolver):
""" """

View File

@ -40,21 +40,13 @@ class AlertsPlugin(Plugin):
log.info(u'Alerts Plugin loaded') log.info(u'Alerts Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Alerts', u'1.9.4', plugin_helpers) Plugin.__init__(self, u'Alerts', u'1.9.4', plugin_helpers,
settingsTabClass=AlertsTab)
self.weight = -3 self.weight = -3
self.icon = build_icon(u':/plugins/plugin_alerts.png') self.icon = build_icon(u':/plugins/plugin_alerts.png')
self.alertsmanager = AlertsManager(self) self.alertsmanager = AlertsManager(self)
self.manager = Manager(u'alerts', init_schema) self.manager = Manager(u'alerts', init_schema)
visible_name = self.getString(StringContent.VisibleName) self.alertForm = AlertForm(self)
self.alertForm = AlertForm(self, visible_name[u'title'])
def getSettingsTab(self):
"""
Return the settings tab for the Alerts plugin
"""
visible_name = self.getString(StringContent.VisibleName)
self.alertsTab = AlertsTab(self, visible_name[u'title'])
return self.alertsTab
def addToolsMenuItem(self, tools_menu): def addToolsMenuItem(self, tools_menu):
""" """
@ -82,7 +74,7 @@ class AlertsPlugin(Plugin):
log.info(u'Alerts Initialising') log.info(u'Alerts Initialising')
Plugin.initialise(self) Plugin.initialise(self)
self.toolsAlertItem.setVisible(True) self.toolsAlertItem.setVisible(True)
self.liveController.alertTab = self.alertsTab self.liveController.alertTab = self.settings_tab
def finalise(self): def finalise(self):
""" """

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate from openlp.core.lib import build_icon, translate
from openlp.core.lib.ui import create_delete_push_button
class Ui_AlertDialog(object): class Ui_AlertDialog(object):
def setupUi(self, alertDialog): def setupUi(self, alertDialog):
@ -65,9 +66,8 @@ class Ui_AlertDialog(object):
self.saveButton.setIcon(build_icon(u':/general/general_save.png')) self.saveButton.setIcon(build_icon(u':/general/general_save.png'))
self.saveButton.setObjectName(u'saveButton') self.saveButton.setObjectName(u'saveButton')
self.manageButtonLayout.addWidget(self.saveButton) self.manageButtonLayout.addWidget(self.saveButton)
self.deleteButton = QtGui.QPushButton(alertDialog) self.deleteButton = create_delete_push_button(alertDialog)
self.deleteButton.setIcon(build_icon(u':/general/general_delete.png')) self.deleteButton.setEnabled(False)
self.deleteButton.setObjectName(u'deleteButton')
self.manageButtonLayout.addWidget(self.deleteButton) self.manageButtonLayout.addWidget(self.deleteButton)
self.manageButtonLayout.addStretch() self.manageButtonLayout.addStretch()
self.alertDialogLayout.addLayout(self.manageButtonLayout, 1, 1) self.alertDialogLayout.addLayout(self.manageButtonLayout, 1, 1)
@ -75,11 +75,13 @@ class Ui_AlertDialog(object):
self.buttonBox.addButton(QtGui.QDialogButtonBox.Close) self.buttonBox.addButton(QtGui.QDialogButtonBox.Close)
displayIcon = build_icon(u':/general/general_live.png') displayIcon = build_icon(u':/general/general_live.png')
self.displayButton = QtGui.QPushButton(alertDialog) self.displayButton = QtGui.QPushButton(alertDialog)
self.displayButton.setEnabled(False)
self.displayButton.setIcon(displayIcon) self.displayButton.setIcon(displayIcon)
self.displayButton.setObjectName(u'displayButton') self.displayButton.setObjectName(u'displayButton')
self.buttonBox.addButton(self.displayButton, self.buttonBox.addButton(self.displayButton,
QtGui.QDialogButtonBox.ActionRole) QtGui.QDialogButtonBox.ActionRole)
self.displayCloseButton = QtGui.QPushButton(alertDialog) self.displayCloseButton = QtGui.QPushButton(alertDialog)
self.displayCloseButton.setEnabled(False)
self.displayCloseButton.setIcon(displayIcon) self.displayCloseButton.setIcon(displayIcon)
self.displayCloseButton.setObjectName(u'displayCloseButton') self.displayCloseButton.setObjectName(u'displayCloseButton')
self.buttonBox.addButton(self.displayCloseButton, self.buttonBox.addButton(self.displayCloseButton,
@ -101,8 +103,6 @@ class Ui_AlertDialog(object):
translate('AlertsPlugin.AlertForm', '&New')) translate('AlertsPlugin.AlertForm', '&New'))
self.saveButton.setText( self.saveButton.setText(
translate('AlertsPlugin.AlertForm', '&Save')) translate('AlertsPlugin.AlertForm', '&Save'))
self.deleteButton.setText(
translate('AlertsPlugin.AlertForm', '&Delete'))
self.displayButton.setText( self.displayButton.setText(
translate('AlertsPlugin.AlertForm', 'Displ&ay')) translate('AlertsPlugin.AlertForm', 'Displ&ay'))
self.displayCloseButton.setText( self.displayCloseButton.setText(

View File

@ -35,7 +35,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
""" """
Provide UI for the alert system Provide UI for the alert system
""" """
def __init__(self, plugin, visible_title): def __init__(self, plugin):
""" """
Initialise the alert form Initialise the alert form
""" """
@ -44,22 +44,22 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
self.item_id = None self.item_id = None
QtGui.QDialog.__init__(self, plugin.formparent) QtGui.QDialog.__init__(self, plugin.formparent)
self.setupUi(self) self.setupUi(self)
QtCore.QObject.connect(self.displayButton, QtCore.SIGNAL(u'clicked()'), QtCore.QObject.connect(self.displayButton,
self.onDisplayClicked) QtCore.SIGNAL(u'clicked()'), self.onDisplayClicked)
QtCore.QObject.connect(self.displayCloseButton, QtCore.QObject.connect(self.displayCloseButton,
QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked) QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked)
QtCore.QObject.connect(self.alertTextEdit, QtCore.QObject.connect(self.alertTextEdit,
QtCore.SIGNAL(u'textChanged(const QString&)'), self.onTextChanged) QtCore.SIGNAL(u'textChanged(const QString&)'), self.onTextChanged)
QtCore.QObject.connect(self.newButton, QtCore.SIGNAL(u'clicked()'), QtCore.QObject.connect(self.newButton,
self.onNewClick) QtCore.SIGNAL(u'clicked()'), self.onNewClick)
QtCore.QObject.connect(self.deleteButton, QtCore.SIGNAL(u'clicked()'), QtCore.QObject.connect(self.saveButton,
self.onDeleteClick) QtCore.SIGNAL(u'clicked()'), self.onSaveClick)
QtCore.QObject.connect(self.saveButton, QtCore.SIGNAL(u'clicked()'),
self.onSaveClick)
QtCore.QObject.connect(self.alertListWidget, QtCore.QObject.connect(self.alertListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onDoubleClick) QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onDoubleClick)
QtCore.QObject.connect(self.alertListWidget, QtCore.QObject.connect(self.alertListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSingleClick) QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSingleClick)
QtCore.QObject.connect(self.alertListWidget,
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
def loadList(self): def loadList(self):
""" """
@ -72,18 +72,15 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
item_name = QtGui.QListWidgetItem(alert.text) item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
self.alertListWidget.addItem(item_name) self.alertListWidget.addItem(item_name)
self.saveButton.setEnabled(False)
self.deleteButton.setEnabled(False)
def onDisplayClicked(self): def onDisplayClicked(self):
if self.triggerAlert(unicode(self.alertTextEdit.text())): self.triggerAlert(unicode(self.alertTextEdit.text()))
self.loadList()
def onDisplayCloseClicked(self): def onDisplayCloseClicked(self):
if self.triggerAlert(unicode(self.alertTextEdit.text())): if self.triggerAlert(unicode(self.alertTextEdit.text())):
self.close() self.close()
def onDeleteClick(self): def onDeleteButtonClicked(self):
""" """
Deletes the selected item. Deletes the selected item.
""" """
@ -95,8 +92,6 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
self.alertListWidget.takeItem(row) self.alertListWidget.takeItem(row)
self.item_id = None self.item_id = None
self.alertTextEdit.setText(u'') self.alertTextEdit.setText(u'')
self.saveButton.setEnabled(False)
self.deleteButton.setEnabled(False)
def onNewClick(self): def onNewClick(self):
if len(self.alertTextEdit.text()) == 0: if len(self.alertTextEdit.text()) == 0:
@ -135,30 +130,26 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
""" """
List item has been double clicked to display it List item has been double clicked to display it
""" """
items = self.alertListWidget.selectedIndexes() item = self.alertListWidget.selectedIndexes()[0]
for item in items: bitem = self.alertListWidget.item(item.row())
bitem = self.alertListWidget.item(item.row()) self.triggerAlert(unicode(bitem.text()))
self.triggerAlert(unicode(bitem.text())) self.alertTextEdit.setText(unicode(bitem.text()))
self.alertTextEdit.setText(unicode(bitem.text())) self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
self.saveButton.setEnabled(False) self.saveButton.setEnabled(False)
self.deleteButton.setEnabled(True)
def onSingleClick(self): def onSingleClick(self):
""" """
List item has been single clicked to add it to List item has been single clicked to add it to
the edit field so it can be changed. the edit field so it can be changed.
""" """
items = self.alertListWidget.selectedIndexes() item = self.alertListWidget.selectedIndexes()[0]
for item in items: bitem = self.alertListWidget.item(item.row())
bitem = self.alertListWidget.item(item.row()) self.alertTextEdit.setText(unicode(bitem.text()))
self.alertTextEdit.setText(unicode(bitem.text())) self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
# If the alert does not contain '<>' we clear the ParameterEdit field. # If the alert does not contain '<>' we clear the ParameterEdit field.
if unicode(self.alertTextEdit.text()).find(u'<>') == -1: if unicode(self.alertTextEdit.text()).find(u'<>') == -1:
self.parameterEdit.setText(u'') self.parameterEdit.setText(u'')
self.saveButton.setEnabled(False) self.saveButton.setEnabled(False)
self.deleteButton.setEnabled(True)
def triggerAlert(self, text): def triggerAlert(self, text):
""" """
@ -167,30 +158,49 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
``text`` ``text``
The alert text (unicode). The alert text (unicode).
""" """
if text: if not text:
# We found '<>' in the alert text, but the ParameterEdit field is return False
# empty. # We found '<>' in the alert text, but the ParameterEdit field is empty.
if text.find(u'<>') != -1 and not self.parameterEdit.text() and \ if text.find(u'<>') != -1 and not self.parameterEdit.text() and \
QtGui.QMessageBox.question(self, QtGui.QMessageBox.question(self,
translate('AlertPlugin.AlertForm', 'No Parameter found'), translate('AlertPlugin.AlertForm', 'No Parameter found'),
translate('AlertPlugin.AlertForm', 'You have not entered a ' translate('AlertPlugin.AlertForm', 'You have not entered a '
'parameter to be replaced.\nDo you want to continue anyway?'), 'parameter to be replaced.\nDo you want to continue anyway?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No:
self.parameterEdit.setFocus() self.parameterEdit.setFocus()
return False return False
# The ParameterEdit field is not empty, but we have not found '<>' # The ParameterEdit field is not empty, but we have not found '<>'
# in the alert text. # in the alert text.
elif text.find(u'<>') == -1 and self.parameterEdit.text() and \ elif text.find(u'<>') == -1 and self.parameterEdit.text() and \
QtGui.QMessageBox.question(self, QtGui.QMessageBox.question(self,
translate('AlertPlugin.AlertForm', 'No Placeholder found'), translate('AlertPlugin.AlertForm', 'No Placeholder found'),
translate('AlertPlugin.AlertForm', 'The alert text does not' translate('AlertPlugin.AlertForm', 'The alert text does not'
' contain \'<>\'.\nDo want to continue anyway?'), ' contain \'<>\'.\nDo want to continue anyway?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No:
self.parameterEdit.setFocus() self.parameterEdit.setFocus()
return False return False
text = text.replace(u'<>', unicode(self.parameterEdit.text())) text = text.replace(u'<>', unicode(self.parameterEdit.text()))
self.parent.alertsmanager.displayAlert(text) self.parent.alertsmanager.displayAlert(text)
return True return True
return False
def onCurrentRowChanged(self, row):
"""
Called when the *alertListWidget*'s current row has been changed. This
enables or disables buttons which require an item to act on.
``row``
The row (int). If there is no current row, the value is -1.
"""
if row == -1:
self.displayButton.setEnabled(False)
self.displayCloseButton.setEnabled(False)
self.saveButton.setEnabled(False)
self.deleteButton.setEnabled(False)
else:
self.displayButton.setEnabled(True)
self.displayCloseButton.setEnabled(True)
self.deleteButton.setEnabled(True)
# We do not need to enable the save button, as it is only enabled
# when typing text in the "alertTextEdit".

View File

@ -84,7 +84,7 @@ class AlertsManager(QtCore.QObject):
if len(self.alertList) == 0: if len(self.alertList) == 0:
return return
text = self.alertList.pop(0) text = self.alertList.pop(0)
alertTab = self.parent.alertsTab alertTab = self.parent.settings_tab
self.parent.liveController.display.alert(text) self.parent.liveController.display.alert(text)
# Check to see if we have a timer running. # Check to see if we have a timer running.
if self.timer_id == 0: if self.timer_id == 0:
@ -103,4 +103,4 @@ class AlertsManager(QtCore.QObject):
self.parent.liveController.display.alert(u'') self.parent.liveController.display.alert(u'')
self.killTimer(self.timer_id) self.killTimer(self.timer_id)
self.timer_id = 0 self.timer_id = 0
self.generateAlert() self.generateAlert()

View File

@ -27,61 +27,55 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate from openlp.core.lib import SettingsTab, translate
from openlp.core.lib.ui import UiStrings, create_valign_combo
class AlertsTab(SettingsTab): class AlertsTab(SettingsTab):
""" """
AlertsTab is the alerts settings tab in the settings dialog. AlertsTab is the alerts settings tab in the settings dialog.
""" """
def __init__(self, parent, visible_title): def __init__(self, name, visible_title):
self.parent = parent SettingsTab.__init__(self, name, visible_title)
self.manager = parent.manager
SettingsTab.__init__(self, parent.name, visible_title)
def setupUi(self): def setupUi(self):
self.setObjectName(u'AlertsTab') self.setObjectName(u'AlertsTab')
SettingsTab.setupUi(self) SettingsTab.setupUi(self)
self.FontGroupBox = QtGui.QGroupBox(self.leftColumn) self.fontGroupBox = QtGui.QGroupBox(self.leftColumn)
self.FontGroupBox.setObjectName(u'FontGroupBox') self.fontGroupBox.setObjectName(u'fontGroupBox')
self.FontLayout = QtGui.QFormLayout(self.FontGroupBox) self.fontLayout = QtGui.QFormLayout(self.fontGroupBox)
self.FontLayout.setObjectName(u'FontLayout') self.fontLayout.setObjectName(u'fontLayout')
self.FontLabel = QtGui.QLabel(self.FontGroupBox) self.FontLabel = QtGui.QLabel(self.fontGroupBox)
self.FontLabel.setObjectName(u'FontLabel') self.FontLabel.setObjectName(u'FontLabel')
self.FontComboBox = QtGui.QFontComboBox(self.FontGroupBox) self.FontComboBox = QtGui.QFontComboBox(self.fontGroupBox)
self.FontComboBox.setObjectName(u'FontComboBox') self.FontComboBox.setObjectName(u'FontComboBox')
self.FontLayout.addRow(self.FontLabel, self.FontComboBox) self.fontLayout.addRow(self.FontLabel, self.FontComboBox)
self.FontColorLabel = QtGui.QLabel(self.FontGroupBox) self.FontColorLabel = QtGui.QLabel(self.fontGroupBox)
self.FontColorLabel.setObjectName(u'FontColorLabel') self.FontColorLabel.setObjectName(u'FontColorLabel')
self.ColorLayout = QtGui.QHBoxLayout() self.ColorLayout = QtGui.QHBoxLayout()
self.ColorLayout.setObjectName(u'ColorLayout') self.ColorLayout.setObjectName(u'ColorLayout')
self.FontColorButton = QtGui.QPushButton(self.FontGroupBox) self.FontColorButton = QtGui.QPushButton(self.fontGroupBox)
self.FontColorButton.setObjectName(u'FontColorButton') self.FontColorButton.setObjectName(u'FontColorButton')
self.ColorLayout.addWidget(self.FontColorButton) self.ColorLayout.addWidget(self.FontColorButton)
self.ColorLayout.addSpacing(20) self.ColorLayout.addSpacing(20)
self.BackgroundColorLabel = QtGui.QLabel(self.FontGroupBox) self.BackgroundColorLabel = QtGui.QLabel(self.fontGroupBox)
self.BackgroundColorLabel.setObjectName(u'BackgroundColorLabel') self.BackgroundColorLabel.setObjectName(u'BackgroundColorLabel')
self.ColorLayout.addWidget(self.BackgroundColorLabel) self.ColorLayout.addWidget(self.BackgroundColorLabel)
self.BackgroundColorButton = QtGui.QPushButton(self.FontGroupBox) self.BackgroundColorButton = QtGui.QPushButton(self.fontGroupBox)
self.BackgroundColorButton.setObjectName(u'BackgroundColorButton') self.BackgroundColorButton.setObjectName(u'BackgroundColorButton')
self.ColorLayout.addWidget(self.BackgroundColorButton) self.ColorLayout.addWidget(self.BackgroundColorButton)
self.FontLayout.addRow(self.FontColorLabel, self.ColorLayout) self.fontLayout.addRow(self.FontColorLabel, self.ColorLayout)
self.FontSizeLabel = QtGui.QLabel(self.FontGroupBox) self.FontSizeLabel = QtGui.QLabel(self.fontGroupBox)
self.FontSizeLabel.setObjectName(u'FontSizeLabel') self.FontSizeLabel.setObjectName(u'FontSizeLabel')
self.FontSizeSpinBox = QtGui.QSpinBox(self.FontGroupBox) self.FontSizeSpinBox = QtGui.QSpinBox(self.fontGroupBox)
self.FontSizeSpinBox.setObjectName(u'FontSizeSpinBox') self.FontSizeSpinBox.setObjectName(u'FontSizeSpinBox')
self.FontLayout.addRow(self.FontSizeLabel, self.FontSizeSpinBox) self.fontLayout.addRow(self.FontSizeLabel, self.FontSizeSpinBox)
self.TimeoutLabel = QtGui.QLabel(self.FontGroupBox) self.TimeoutLabel = QtGui.QLabel(self.fontGroupBox)
self.TimeoutLabel.setObjectName(u'TimeoutLabel') self.TimeoutLabel.setObjectName(u'TimeoutLabel')
self.TimeoutSpinBox = QtGui.QSpinBox(self.FontGroupBox) self.TimeoutSpinBox = QtGui.QSpinBox(self.fontGroupBox)
self.TimeoutSpinBox.setMaximum(180) self.TimeoutSpinBox.setMaximum(180)
self.TimeoutSpinBox.setObjectName(u'TimeoutSpinBox') self.TimeoutSpinBox.setObjectName(u'TimeoutSpinBox')
self.FontLayout.addRow(self.TimeoutLabel, self.TimeoutSpinBox) self.fontLayout.addRow(self.TimeoutLabel, self.TimeoutSpinBox)
self.LocationLabel = QtGui.QLabel(self.FontGroupBox) create_valign_combo(self, self.fontGroupBox, self.fontLayout)
self.LocationLabel.setObjectName(u'LocationLabel') self.leftLayout.addWidget(self.fontGroupBox)
self.LocationComboBox = QtGui.QComboBox(self.FontGroupBox)
self.LocationComboBox.addItems([u'', u'', u''])
self.LocationComboBox.setObjectName(u'LocationComboBox')
self.FontLayout.addRow(self.LocationLabel, self.LocationComboBox)
self.leftLayout.addWidget(self.FontGroupBox)
self.leftLayout.addStretch() self.leftLayout.addStretch()
self.PreviewGroupBox = QtGui.QGroupBox(self.rightColumn) self.PreviewGroupBox = QtGui.QGroupBox(self.rightColumn)
self.PreviewGroupBox.setObjectName(u'PreviewGroupBox') self.PreviewGroupBox.setObjectName(u'PreviewGroupBox')
@ -99,15 +93,13 @@ class AlertsTab(SettingsTab):
QtCore.SIGNAL(u'pressed()'), self.onFontColorButtonClicked) QtCore.SIGNAL(u'pressed()'), self.onFontColorButtonClicked)
QtCore.QObject.connect(self.FontComboBox, QtCore.QObject.connect(self.FontComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onFontComboBoxClicked) QtCore.SIGNAL(u'activated(int)'), self.onFontComboBoxClicked)
QtCore.QObject.connect(self.LocationComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onLocationComboBoxClicked)
QtCore.QObject.connect(self.TimeoutSpinBox, QtCore.QObject.connect(self.TimeoutSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged) QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
QtCore.QObject.connect(self.FontSizeSpinBox, QtCore.QObject.connect(self.FontSizeSpinBox,
QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged) QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.FontGroupBox.setTitle( self.fontGroupBox.setTitle(
translate('AlertsPlugin.AlertsTab', 'Font')) translate('AlertsPlugin.AlertsTab', 'Font'))
self.FontLabel.setText( self.FontLabel.setText(
translate('AlertsPlugin.AlertsTab', 'Font name:')) translate('AlertsPlugin.AlertsTab', 'Font name:'))
@ -123,18 +115,8 @@ class AlertsTab(SettingsTab):
translate('AlertsPlugin.AlertsTab', 'Alert timeout:')) translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
self.TimeoutSpinBox.setSuffix( self.TimeoutSpinBox.setSuffix(
translate('AlertsPlugin.AlertsTab', 's')) translate('AlertsPlugin.AlertsTab', 's'))
self.LocationLabel.setText( self.PreviewGroupBox.setTitle(UiStrings.Preview)
translate('AlertsPlugin.AlertsTab', 'Location:')) self.FontPreview.setText(UiStrings.OLPV2)
self.PreviewGroupBox.setTitle(
translate('AlertsPlugin.AlertsTab', 'Preview'))
self.FontPreview.setText(
translate('AlertsPlugin.AlertsTab', 'OpenLP 2.0'))
self.LocationComboBox.setItemText(0,
translate('AlertsPlugin.AlertsTab', 'Top'))
self.LocationComboBox.setItemText(1,
translate('AlertsPlugin.AlertsTab', 'Middle'))
self.LocationComboBox.setItemText(2,
translate('AlertsPlugin.AlertsTab', 'Bottom'))
def onBackgroundColorButtonClicked(self): def onBackgroundColorButtonClicked(self):
new_color = QtGui.QColorDialog.getColor( new_color = QtGui.QColorDialog.getColor(
@ -148,9 +130,6 @@ class AlertsTab(SettingsTab):
def onFontComboBoxClicked(self): def onFontComboBoxClicked(self):
self.updateDisplay() self.updateDisplay()
def onLocationComboBoxClicked(self, location):
self.location = location
def onFontColorButtonClicked(self): def onFontColorButtonClicked(self):
new_color = QtGui.QColorDialog.getColor( new_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.font_color), self) QtGui.QColor(self.font_color), self)
@ -188,7 +167,7 @@ class AlertsTab(SettingsTab):
u'background-color: %s' % self.font_color) u'background-color: %s' % self.font_color)
self.BackgroundColorButton.setStyleSheet( self.BackgroundColorButton.setStyleSheet(
u'background-color: %s' % self.bg_color) u'background-color: %s' % self.bg_color)
self.LocationComboBox.setCurrentIndex(self.location) self.verticalComboBox.setCurrentIndex(self.location)
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(self.font_face) font.setFamily(self.font_face)
self.FontComboBox.setCurrentFont(font) self.FontComboBox.setCurrentFont(font)
@ -197,14 +176,14 @@ class AlertsTab(SettingsTab):
def save(self): def save(self):
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection) settings.beginGroup(self.settingsSection)
self.font_face = self.FontComboBox.currentFont().family()
settings.setValue(u'background color', QtCore.QVariant(self.bg_color)) settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
settings.setValue(u'font color', QtCore.QVariant(self.font_color)) settings.setValue(u'font color', QtCore.QVariant(self.font_color))
settings.setValue(u'font size', QtCore.QVariant(self.font_size)) settings.setValue(u'font size', QtCore.QVariant(self.font_size))
self.font_face = self.FontComboBox.currentFont().family()
settings.setValue(u'font face', QtCore.QVariant(self.font_face)) settings.setValue(u'font face', QtCore.QVariant(self.font_face))
settings.setValue(u'timeout', QtCore.QVariant(self.timeout)) settings.setValue(u'timeout', QtCore.QVariant(self.timeout))
settings.setValue(u'location', self.location = self.verticalComboBox.currentIndex()
QtCore.QVariant(self.LocationComboBox.currentIndex())) settings.setValue(u'location', QtCore.QVariant(self.location))
settings.endGroup() settings.endGroup()
def updateDisplay(self): def updateDisplay(self):

View File

@ -37,7 +37,8 @@ class BiblePlugin(Plugin):
log.info(u'Bible Plugin loaded') log.info(u'Bible Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Bibles', u'1.9.4', plugin_helpers) Plugin.__init__(self, u'Bibles', u'1.9.4', plugin_helpers,
BibleMediaItem, BiblesTab)
self.weight = -9 self.weight = -9
self.icon_path = u':/plugins/plugin_bibles.png' self.icon_path = u':/plugins/plugin_bibles.png'
self.icon = build_icon(self.icon_path) self.icon = build_icon(self.icon_path)
@ -61,14 +62,6 @@ class BiblePlugin(Plugin):
self.importBibleItem.setVisible(False) self.importBibleItem.setVisible(False)
self.exportBibleItem.setVisible(False) self.exportBibleItem.setVisible(False)
def getSettingsTab(self):
visible_name = self.getString(StringContent.VisibleName)
return BiblesTab(self.name, visible_name[u'title'])
def getMediaManagerItem(self):
# Create the BibleManagerItem object.
return BibleMediaItem(self, self, self.icon)
def addImportMenuItem(self, import_menu): def addImportMenuItem(self, import_menu):
self.importBibleItem = QtGui.QAction(import_menu) self.importBibleItem = QtGui.QAction(import_menu)
self.importBibleItem.setObjectName(u'importBibleItem') self.importBibleItem.setObjectName(u'importBibleItem')
@ -102,7 +95,7 @@ class BiblePlugin(Plugin):
Called to find out if the bible plugin is currently using a theme. Called to find out if the bible plugin is currently using a theme.
Returns True if the theme is being used, otherwise returns False. Returns True if the theme is being used, otherwise returns False.
""" """
if self.settings_tab.bible_theme == theme: if unicode(self.settings_tab.bible_theme) == theme:
return True return True
return False return False
@ -119,6 +112,7 @@ class BiblePlugin(Plugin):
The new name the plugin should now use. The new name the plugin should now use.
""" """
self.settings_tab.bible_theme = newTheme self.settings_tab.bible_theme = newTheme
self.settings_tab.save()
def setPluginTextStrings(self): def setPluginTextStrings(self):
""" """
@ -134,40 +128,15 @@ class BiblePlugin(Plugin):
u'title': translate('BiblesPlugin', 'Bibles', 'container title') u'title': translate('BiblesPlugin', 'Bibles', 'container title')
} }
# Middle Header Bar # Middle Header Bar
## Import Action ## tooltips = {
self.textStrings[StringContent.Import] = { u'load': u'',
u'title': translate('BiblesPlugin', '&Import'), u'import': translate('BiblesPlugin', 'Import a Bible'),
u'tooltip': translate('BiblesPlugin', 'Import a Bible') u'new': translate('BiblesPlugin', 'Add a new Bible'),
} u'edit': translate('BiblesPlugin', 'Edit the selected Bible'),
## New Action ## u'delete': translate('BiblesPlugin', 'Delete the selected Bible'),
self.textStrings[StringContent.New] = { u'preview': translate('BiblesPlugin', 'Preview the selected Bible'),
u'title': translate('BiblesPlugin', '&Add'), u'live': translate('BiblesPlugin', 'Send the selected Bible live'),
u'tooltip': translate('BiblesPlugin', 'Add a new Bible') u'service': translate('BiblesPlugin',
}
## Edit Action ##
self.textStrings[StringContent.Edit] = {
u'title': translate('BiblesPlugin', '&Edit'),
u'tooltip': translate('BiblesPlugin', 'Edit the selected Bible')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('BiblesPlugin', '&Delete'),
u'tooltip': translate('BiblesPlugin', 'Delete the selected Bible')
}
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('BiblesPlugin', 'Preview'),
u'tooltip': translate('BiblesPlugin', 'Preview the selected Bible')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('BiblesPlugin', 'Live'),
u'tooltip': translate('BiblesPlugin',
'Send the selected Bible live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('BiblesPlugin', 'Service'),
u'tooltip': translate('BiblesPlugin',
'Add the selected Bible to the service') 'Add the selected Bible to the service')
} }
self.setPluginUiTextStrings(tooltips)

View File

@ -33,9 +33,9 @@ import os.path
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsManager, translate from openlp.core.lib import Receiver, translate
from openlp.core.lib.db import delete_database from openlp.core.lib.db import delete_database
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard from openlp.core.ui.wizard import OpenLPWizard
from openlp.core.utils import AppLocation, string_is_unicode from openlp.core.utils import AppLocation, string_is_unicode
from openlp.plugins.bibles.lib.manager import BibleFormat from openlp.plugins.bibles.lib.manager import BibleFormat
@ -124,9 +124,12 @@ class BibleImportForm(OpenLPWizard):
QtCore.QObject.connect(self.osisBrowseButton, QtCore.QObject.connect(self.osisBrowseButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onOsisBrowseButtonClicked) self.onOsisBrowseButtonClicked)
QtCore.QObject.connect(self.csvTestamentsButton,
QtCore.SIGNAL(u'clicked()'),
self.onCsvTestamentsBrowseButtonClicked)
QtCore.QObject.connect(self.csvBooksButton, QtCore.QObject.connect(self.csvBooksButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onBooksBrowseButtonClicked) self.onCsvBooksBrowseButtonClicked)
QtCore.QObject.connect(self.csvVersesButton, QtCore.QObject.connect(self.csvVersesButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onCsvVersesBrowseButtonClicked) self.onCsvVersesBrowseButtonClicked)
@ -154,10 +157,9 @@ class BibleImportForm(OpenLPWizard):
self.formatComboBox.addItems([u'', u'', u'', u'', u'']) self.formatComboBox.addItems([u'', u'', u'', u'', u''])
self.formatComboBox.setObjectName(u'FormatComboBox') self.formatComboBox.setObjectName(u'FormatComboBox')
self.formatLayout.addRow(self.formatLabel, self.formatComboBox) self.formatLayout.addRow(self.formatLabel, self.formatComboBox)
self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum) QtGui.QSizePolicy.Minimum)
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
self.formatSpacer)
self.selectPageLayout.addLayout(self.formatLayout) self.selectPageLayout.addLayout(self.formatLayout)
self.selectStack = QtGui.QStackedLayout() self.selectStack = QtGui.QStackedLayout()
self.selectStack.setObjectName(u'SelectStack') self.selectStack.setObjectName(u'SelectStack')
@ -178,15 +180,25 @@ class BibleImportForm(OpenLPWizard):
self.osisBrowseButton.setObjectName(u'OsisBrowseButton') self.osisBrowseButton.setObjectName(u'OsisBrowseButton')
self.osisFileLayout.addWidget(self.osisBrowseButton) self.osisFileLayout.addWidget(self.osisBrowseButton)
self.osisLayout.addRow(self.osisFileLabel, self.osisFileLayout) self.osisLayout.addRow(self.osisFileLabel, self.osisFileLayout)
self.osisSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.osisSpacer)
self.selectStack.addWidget(self.osisWidget) self.selectStack.addWidget(self.osisWidget)
self.csvWidget = QtGui.QWidget(self.selectPage) self.csvWidget = QtGui.QWidget(self.selectPage)
self.csvWidget.setObjectName(u'CsvWidget') self.csvWidget.setObjectName(u'CsvWidget')
self.csvLayout = QtGui.QFormLayout(self.csvWidget) self.csvLayout = QtGui.QFormLayout(self.csvWidget)
self.csvLayout.setMargin(0) self.csvLayout.setMargin(0)
self.csvLayout.setObjectName(u'CsvLayout') self.csvLayout.setObjectName(u'CsvLayout')
self.csvTestamentsLabel = QtGui.QLabel(self.csvWidget)
self.csvTestamentsLabel.setObjectName(u'CsvTestamentsLabel')
self.csvTestamentsLayout = QtGui.QHBoxLayout()
self.csvTestamentsLayout.setObjectName(u'CsvTestamentsLayout')
self.csvTestamentsEdit = QtGui.QLineEdit(self.csvWidget)
self.csvTestamentsEdit.setObjectName(u'CsvTestamentsEdit')
self.csvTestamentsLayout.addWidget(self.csvTestamentsEdit)
self.csvTestamentsButton = QtGui.QToolButton(self.csvWidget)
self.csvTestamentsButton.setIcon(self.openIcon)
self.csvTestamentsButton.setObjectName(u'CsvTestamentsButton')
self.csvTestamentsLayout.addWidget(self.csvTestamentsButton)
self.csvLayout.addRow(self.csvTestamentsLabel, self.csvTestamentsLayout)
self.csvBooksLabel = QtGui.QLabel(self.csvWidget) self.csvBooksLabel = QtGui.QLabel(self.csvWidget)
self.csvBooksLabel.setObjectName(u'CsvBooksLabel') self.csvBooksLabel.setObjectName(u'CsvBooksLabel')
self.csvBooksLayout = QtGui.QHBoxLayout() self.csvBooksLayout = QtGui.QHBoxLayout()
@ -211,9 +223,7 @@ class BibleImportForm(OpenLPWizard):
self.csvVersesButton.setObjectName(u'CsvVersesButton') self.csvVersesButton.setObjectName(u'CsvVersesButton')
self.csvVersesLayout.addWidget(self.csvVersesButton) self.csvVersesLayout.addWidget(self.csvVersesButton)
self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout) self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout)
self.csvSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.csvLayout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.csvLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.csvSpacer)
self.selectStack.addWidget(self.csvWidget) self.selectStack.addWidget(self.csvWidget)
self.openSongWidget = QtGui.QWidget(self.selectPage) self.openSongWidget = QtGui.QWidget(self.selectPage)
self.openSongWidget.setObjectName(u'OpenSongWidget') self.openSongWidget.setObjectName(u'OpenSongWidget')
@ -233,10 +243,7 @@ class BibleImportForm(OpenLPWizard):
self.openSongFileLayout.addWidget(self.openSongBrowseButton) self.openSongFileLayout.addWidget(self.openSongBrowseButton)
self.openSongLayout.addRow(self.openSongFileLabel, self.openSongLayout.addRow(self.openSongFileLabel,
self.openSongFileLayout) self.openSongFileLayout)
self.openSongSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole,
self.openSongSpacer)
self.selectStack.addWidget(self.openSongWidget) self.selectStack.addWidget(self.openSongWidget)
self.webTabWidget = QtGui.QTabWidget(self.selectPage) self.webTabWidget = QtGui.QTabWidget(self.selectPage)
self.webTabWidget.setObjectName(u'WebTabWidget') self.webTabWidget.setObjectName(u'WebTabWidget')
@ -315,10 +322,7 @@ class BibleImportForm(OpenLPWizard):
self.openlp1DisabledLabel.setWordWrap(True) self.openlp1DisabledLabel.setWordWrap(True)
self.openlp1DisabledLabel.setObjectName(u'Openlp1DisabledLabel') self.openlp1DisabledLabel.setObjectName(u'Openlp1DisabledLabel')
self.openlp1Layout.addRow(self.openlp1DisabledLabel) self.openlp1Layout.addRow(self.openlp1DisabledLabel)
self.openlp1Spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
QtGui.QSizePolicy.Minimum)
self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole,
self.openlp1Spacer)
self.selectStack.addWidget(self.openlp1Widget) self.selectStack.addWidget(self.openlp1Widget)
self.selectPageLayout.addLayout(self.selectStack) self.selectPageLayout.addLayout(self.selectStack)
self.addPage(self.selectPage) self.addPage(self.selectPage)
@ -386,15 +390,17 @@ class BibleImportForm(OpenLPWizard):
self.formatComboBox.setItemText(4, self.formatComboBox.setItemText(4,
translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x')) translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x'))
self.openlp1FileLabel.setText( self.openlp1FileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'File location:')) translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
self.osisFileLabel.setText( self.osisFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'File location:')) translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
self.csvTestamentsLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Testaments file:'))
self.csvBooksLabel.setText( self.csvBooksLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Books location:')) translate('BiblesPlugin.ImportWizardForm', 'Books file:'))
self.csvVersesLabel.setText( self.csvVersesLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Verse location:')) translate('BiblesPlugin.ImportWizardForm', 'Verses file:'))
self.openSongFileLabel.setText( self.openSongFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Bible filename:')) translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
self.webSourceLabel.setText( self.webSourceLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Location:')) translate('BiblesPlugin.ImportWizardForm', 'Location:'))
self.webSourceComboBox.setItemText(0, self.webSourceComboBox.setItemText(0,
@ -445,19 +451,12 @@ class BibleImportForm(OpenLPWizard):
# Align all QFormLayouts towards each other. # Align all QFormLayouts towards each other.
labelWidth = max(self.formatLabel.minimumSizeHint().width(), labelWidth = max(self.formatLabel.minimumSizeHint().width(),
self.osisFileLabel.minimumSizeHint().width(), self.osisFileLabel.minimumSizeHint().width(),
self.csvTestamentsLabel.minimumSizeHint().width(),
self.csvBooksLabel.minimumSizeHint().width(), self.csvBooksLabel.minimumSizeHint().width(),
self.csvVersesLabel.minimumSizeHint().width(), self.csvVersesLabel.minimumSizeHint().width(),
self.openSongFileLabel.minimumSizeHint().width(), self.openSongFileLabel.minimumSizeHint().width(),
self.openlp1FileLabel.minimumSizeHint().width()) self.openlp1FileLabel.minimumSizeHint().width())
self.formatSpacer.changeSize(labelWidth, 0, self.spacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.osisSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.csvSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openSongSpacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
self.openlp1Spacer.changeSize(labelWidth, 0,
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
def validateCurrentPage(self): def validateCurrentPage(self):
@ -469,7 +468,7 @@ class BibleImportForm(OpenLPWizard):
elif self.currentPage() == self.selectPage: elif self.currentPage() == self.selectPage:
if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS: if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS:
if not self.field(u'osis_location').toString(): if not self.field(u'osis_location').toString():
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Bible Location'), 'Invalid Bible Location'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -478,8 +477,17 @@ class BibleImportForm(OpenLPWizard):
self.osisFileEdit.setFocus() self.osisFileEdit.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 not self.field(u'csv_booksfile').toString(): if not self.field(u'csv_testamentsfile').toString():
criticalErrorMessageBox( answer = critical_error_message_box(translate(
'BiblesPlugin.ImportWizardForm', 'No Testaments File'),
translate('BiblesPlugin.ImportWizardForm',
'You have not specified a testaments file. Do you '
'want to proceed with the import?'), question=True)
if answer == QtGui.QMessageBox.No:
self.csvTestamentsEdit.setFocus()
return False
elif not self.field(u'csv_booksfile').toString():
critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Books File'), 'Invalid Books File'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -488,7 +496,7 @@ class BibleImportForm(OpenLPWizard):
self.csvBooksEdit.setFocus() self.csvBooksEdit.setFocus()
return False return False
elif not self.field(u'csv_versefile').toString(): elif not self.field(u'csv_versefile').toString():
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Verse File'), 'Invalid Verse File'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -499,7 +507,7 @@ class BibleImportForm(OpenLPWizard):
elif self.field(u'source_format').toInt()[0] == \ elif self.field(u'source_format').toInt()[0] == \
BibleFormat.OpenSong: BibleFormat.OpenSong:
if not self.field(u'opensong_file').toString(): if not self.field(u'opensong_file').toString():
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid OpenSong Bible'), 'Invalid OpenSong Bible'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -509,7 +517,7 @@ class BibleImportForm(OpenLPWizard):
return False return False
elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1: elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1:
if not self.field(u'openlp1_location').toString(): if not self.field(u'openlp1_location').toString():
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Bible Location'), 'Invalid Bible Location'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -523,7 +531,7 @@ class BibleImportForm(OpenLPWizard):
license_copyright = \ license_copyright = \
unicode(self.field(u'license_copyright').toString()) unicode(self.field(u'license_copyright').toString())
if not license_version: if not license_version:
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Empty Version Name'), 'Empty Version Name'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -531,7 +539,7 @@ class BibleImportForm(OpenLPWizard):
self.versionNameEdit.setFocus() self.versionNameEdit.setFocus()
return False return False
elif not license_copyright: elif not license_copyright:
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Empty Copyright'), 'Empty Copyright'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
@ -540,7 +548,7 @@ class BibleImportForm(OpenLPWizard):
self.copyrightEdit.setFocus() self.copyrightEdit.setFocus()
return False return False
elif self.manager.exists(license_version): elif self.manager.exists(license_version):
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'), translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'),
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'This Bible already exists. Please import ' 'This Bible already exists. Please import '
@ -572,7 +580,15 @@ class BibleImportForm(OpenLPWizard):
translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'), translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'),
self.osisFileEdit) self.osisFileEdit)
def onBooksBrowseButtonClicked(self): def onCsvTestamentsBrowseButtonClicked(self):
"""
Show the file open dialog for the testaments CSV file.
"""
self.getFileName(translate('BiblesPlugin.ImportWizardForm',
'Open Testaments CSV File'), self.csvTestamentsEdit, u'%s (*.csv)'
% translate('BiblesPlugin.ImportWizardForm', 'CSV File'))
def onCsvBooksBrowseButtonClicked(self):
""" """
Show the file open dialog for the books CSV file. Show the file open dialog for the books CSV file.
""" """
@ -613,12 +629,14 @@ class BibleImportForm(OpenLPWizard):
""" """
self.selectPage.registerField(u'source_format', self.formatComboBox) self.selectPage.registerField(u'source_format', self.formatComboBox)
self.selectPage.registerField(u'osis_location', self.osisFileEdit) self.selectPage.registerField(u'osis_location', self.osisFileEdit)
self.selectPage.registerField(
u'csv_testamentsfile', self.csvTestamentsEdit)
self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit) self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit)
self.selectPage.registerField(u'csv_versefile', self.csvVersesEdit) self.selectPage.registerField(u'csv_versefile', self.csvVersesEdit)
self.selectPage.registerField(u'opensong_file', self.openSongFileEdit) self.selectPage.registerField(u'opensong_file', self.openSongFileEdit)
self.selectPage.registerField(u'web_location', self.webSourceComboBox) self.selectPage.registerField(u'web_location', self.webSourceComboBox)
self.selectPage.registerField(u'web_biblename', self.selectPage.registerField(
self.webTranslationComboBox) u'web_biblename', self.webTranslationComboBox)
self.selectPage.registerField(u'proxy_server', self.webServerEdit) self.selectPage.registerField(u'proxy_server', self.webServerEdit)
self.selectPage.registerField(u'proxy_username', self.webUserEdit) self.selectPage.registerField(u'proxy_username', self.webUserEdit)
self.selectPage.registerField(u'proxy_password', self.webPasswordEdit) self.selectPage.registerField(u'proxy_password', self.webPasswordEdit)
@ -641,6 +659,7 @@ class BibleImportForm(OpenLPWizard):
self.cancelButton.setVisible(True) self.cancelButton.setVisible(True)
self.setField(u'source_format', QtCore.QVariant(0)) self.setField(u'source_format', QtCore.QVariant(0))
self.setField(u'osis_location', QtCore.QVariant('')) self.setField(u'osis_location', QtCore.QVariant(''))
self.setField(u'csv_testamentsfile', QtCore.QVariant(''))
self.setField(u'csv_booksfile', QtCore.QVariant('')) self.setField(u'csv_booksfile', QtCore.QVariant(''))
self.setField(u'csv_versefile', QtCore.QVariant('')) self.setField(u'csv_versefile', QtCore.QVariant(''))
self.setField(u'opensong_file', QtCore.QVariant('')) self.setField(u'opensong_file', QtCore.QVariant(''))
@ -708,34 +727,6 @@ class BibleImportForm(OpenLPWizard):
if books_file: if books_file:
books_file.close() books_file.close()
def getFileName(self, title, editbox, filters=u''):
"""
Opens a QFileDialog and saves the filename to the given editbox.
``title``
The title of the dialog (unicode).
``editbox``
A editbox (QLineEdit).
``filters``
The file extension filters. It should contain the file description
as well as the file extension. For example::
u'openlp.org 1.x bible (*.bible)'
"""
if filters:
filters += u';;'
filters += u'%s (*)' % translate('BiblesPlugin.ImportWizardForm',
'All Files')
filename = QtGui.QFileDialog.getOpenFileName(self, title,
os.path.dirname(SettingsManager.get_last_dir(
self.plugin.settingsSection, 1)), filters)
if filename:
editbox.setText(filename)
SettingsManager.set_last_dir(
self.plugin.settingsSection, filename, 1)
def preWizard(self): def preWizard(self):
""" """
Prepare the UI for the import. Prepare the UI for the import.
@ -770,7 +761,8 @@ class BibleImportForm(OpenLPWizard):
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, testamentsfile=unicode(
self.field(u'csv_testamentsfile').toString()),
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())
) )
@ -795,8 +787,7 @@ class BibleImportForm(OpenLPWizard):
bible = \ bible = \
self.web_bible_list[WebDownload.Bibleserver][bible_version] self.web_bible_list[WebDownload.Bibleserver][bible_version]
importer = self.manager.import_bible( importer = self.manager.import_bible(
BibleFormat.WebDownload, BibleFormat.WebDownload, name=license_version,
name=license_version,
download_source=WebDownload.get_name(download_location), download_source=WebDownload.get_name(download_location),
download_name=bible, download_name=bible,
proxy_server=unicode(self.field(u'proxy_server').toString()), proxy_server=unicode(self.field(u'proxy_server').toString()),

View File

@ -33,6 +33,13 @@ import re
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def get_reference_match(match_type): def get_reference_match(match_type):
"""
Provides the regexes and matches to use while parsing strings for bible
references.
``match_type``
The type of reference information trying to be extracted in this call.
"""
local_separator = unicode(u':;;\s*[:vV]\s*;;-;;\s*-\s*;;,;;\s*,\s*;;end' local_separator = unicode(u':;;\s*[:vV]\s*;;-;;\s*-\s*;;,;;\s*,\s*;;end'
).split(u';;') # English ).split(u';;') # English
# local_separator = unicode(u',;;\s*,\s*;;-;;\s*-\s*;;.;;\.;;[Ee]nde' # local_separator = unicode(u',;;\s*,\s*;;-;;\s*-\s*;;.;;\.;;[Ee]nde'
@ -62,69 +69,90 @@ def get_reference_match(match_type):
def parse_reference(reference): def parse_reference(reference):
""" """
This is the next generation über-awesome function that takes a person's This is the next generation über-awesome function that takes a person's
typed in string and converts it to a reference list, a list of references to typed in string and converts it to a list of references to be queried from
be queried from the Bible database files. the Bible database files.
This is a user manual like description, how the references are working. ``reference``
A string. The Bible reference to parse.
- Each reference starts with the book name. A chapter name is manditory. Returns ``None`` or a reference list.
``John 3`` refers to Gospel of John chapter 3
- A reference range can be given after a range separator.
``John 3-5`` refers to John chapters 3 to 5
- Single verses can be addressed after a verse separator
``John 3:16`` refers to John chapter 3 verse 16
``John 3:16-4:3`` refers to John chapter 3 verse 16 to chapter 4 verse 3
- After a verse reference all further single values are treat as verse in
the last selected chapter.
``John 3:16-18`` refers to John chapter 3 verses 16 to 18
- After a list separator it is possible to refer to additional verses. They
are build analog to the first ones. This way it is possible to define
each number of verse references. It is not possible to refer to verses in
additional books.
``John 3:16,18`` refers to John chapter 3 verses 16 and 18
``John 3:16-18,20`` refers to John chapter 3 verses 16 to 18 and 20
``John 3:16-18,4:1`` refers to John chapter 3 verses 16 to 18 and
chapter 3 verse 1
- If there is a range separator without further verse declaration the last
refered chapter is addressed until the end.
``range_string`` is a regular expression which matches for verse range
declarations:
1. ``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?'
It starts with a optional chapter reference ``from_chapter`` followed by
a verse separator.
2. ``(?P<from_verse>[0-9]+)``
The verse reference ``from_verse`` is manditory
3. ``(?P<range_to>%(sep_r)s(?:`` ... ``|%(sep_e)s)?)?``
A ``range_to`` declaration is optional. It starts with a range separator
and contains optional a chapter and verse declaration or a end
separator.
4. ``(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?``
The ``to_chapter`` reference with separator is equivalent to group 1.
5. ``(?P<to_verse>[0-9]+)``
The ``to_verse`` reference is equivalent to group 2.
The full reference is matched against get_reference_match(u'full'). This
regular expression looks like this:
1. ``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*``
The ``book`` group starts with the first non-whitespace character. There
are optional leading digits followed by non-digits. The group ends
before the whitspace in front of the next digit.
2. ``(?P<ranges>(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$``
The second group contains all ``ranges``. This can be multiple
declarations of a range_string separated by a list separator.
The reference list is a list of tuples, with each tuple structured like The reference list is a list of tuples, with each tuple structured like
this:: this::
(book, chapter, from_verse, to_verse) (book, chapter, from_verse, to_verse)
For example::
[(u'John', 3, 16, 18), (u'John', 4, 1, 1)]
``reference`` **Reference string details:**
The bible reference to parse.
Each reference starts with the book name and a chapter number. These are
both mandatory.
* ``John 3`` refers to Gospel of John chapter 3
A reference range can be given after a range separator.
* ``John 3-5`` refers to John chapters 3 to 5
Single verses can be addressed after a verse separator.
* ``John 3:16`` refers to John chapter 3 verse 16
* ``John 3:16-4:3`` refers to John chapter 3 verse 16 to chapter 4 verse 3
After a verse reference all further single values are treat as verse in
the last selected chapter.
* ``John 3:16-18`` refers to John chapter 3 verses 16 to 18
After a list separator it is possible to refer to additional verses. They
are build analog to the first ones. This way it is possible to define each
number of verse references. It is not possible to refer to verses in
additional books.
* ``John 3:16,18`` refers to John chapter 3 verses 16 and 18
* ``John 3:16-18,20`` refers to John chapter 3 verses 16 to 18 and 20
* ``John 3:16-18,4:1`` refers to John chapter 3 verses 16 to 18 and
chapter 4 verse 1
If there is a range separator without further verse declaration the last
refered chapter is addressed until the end.
``range_string`` is a regular expression which matches for verse range
declarations:
``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?``
It starts with a optional chapter reference ``from_chapter`` followed by
a verse separator.
``(?P<from_verse>[0-9]+)``
The verse reference ``from_verse`` is manditory
``(?P<range_to>%(sep_r)s(?:`` ... ``|%(sep_e)s)?)?``
A ``range_to`` declaration is optional. It starts with a range separator
and contains optional a chapter and verse declaration or a end
separator.
``(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?``
The ``to_chapter`` reference with separator is equivalent to group 1.
``(?P<to_verse>[0-9]+)``
The ``to_verse`` reference is equivalent to group 2.
The full reference is matched against get_reference_match(u'full'). This
regular expression looks like this:
``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*``
The ``book`` group starts with the first non-whitespace character. There
are optional leading digits followed by non-digits. The group ends
before the whitspace in front of the next digit.
``(?P<ranges>(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$``
The second group contains all ``ranges``. This can be multiple
declarations of a range_string separated by a list separator.
Returns None or a reference list.
""" """
log.debug(u'parse_reference("%s")', reference) log.debug(u'parse_reference("%s")', reference)
match = get_reference_match(u'full').match(reference) match = get_reference_match(u'full').match(reference)
@ -194,7 +222,7 @@ def parse_reference(reference):
class SearchResults(object): class SearchResults(object):
""" """
Encapsulate a set of search results. This is Bible-type independent. Encapsulate a set of search results. This is Bible-type independent.
""" """
def __init__(self, book, chapter, verselist): def __init__(self, book, chapter, verselist):
""" """
@ -207,7 +235,8 @@ class SearchResults(object):
The chapter of the book. The chapter of the book.
``verselist`` ``verselist``
The list of verses for this reading The list of verses for this reading.
""" """
self.book = book self.book = book
self.chapter = chapter self.chapter = chapter

View File

@ -23,7 +23,48 @@
# 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 #
############################################################################### ###############################################################################
"""
The :mod:`cvsbible` modules provides a facility to import bibles from a set of
CSV files.
The module expects two mandatory files containing the books and the verses and
will accept an optional third file containing the testaments.
The format of the testament file is:
<testament_id>,<testament_name>
For example:
1,Old Testament
2,New Testament
The format of the books file is:
<book_id>,<testament_id>,<book_name>,<book_abbreviation>
For example
1,1,Genesis,Gen
2,1,Exodus,Exod
...
40,2,Matthew,Matt
There are two acceptable formats of the verses file. They are:
<book_id>,<chapter_number>,<verse_number>,<verse_text>
or
<book_name>,<chapter_number>,<verse_number>,<verse_text>
For example:
1,1,1,"In the beginning God created the heaven and the earth."
or
"Genesis",1,2,"And the earth was without form, and void; and...."
All CSV files are expected to use a comma (',') as the delimeter and double
quotes ('"') as the quote symbol.
"""
import logging import logging
import chardet import chardet
import csv import csv
@ -31,7 +72,7 @@ import csv
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from openlp.plugins.bibles.lib.db import BibleDB from openlp.plugins.bibles.lib.db import BibleDB, Testament
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -39,68 +80,120 @@ class CSVBible(BibleDB):
""" """
This class provides a specialisation for importing of CSV Bibles. This class provides a specialisation for importing of CSV Bibles.
""" """
def __init__(self, parent, **kwargs): def __init__(self, parent, **kwargs):
""" """
Loads a Bible from a pair of CVS files passed in Loads a Bible from a set of CVS files.
This class assumes the files contain all the information and This class assumes the files contain all the information and
a clean bible is being loaded. a clean bible is being loaded.
""" """
log.info(self.__class__.__name__) log.info(self.__class__.__name__)
BibleDB.__init__(self, parent, **kwargs) BibleDB.__init__(self, parent, **kwargs)
try:
self.testamentsfile = kwargs[u'testamentsfile']
except KeyError:
self.testamentsfile = None
self.booksfile = kwargs[u'booksfile'] self.booksfile = kwargs[u'booksfile']
self.versesfile = kwargs[u'versefile'] self.versesfile = kwargs[u'versefile']
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
def setup_testaments(self):
"""
Overrides parent method so we can handle importing a testament file.
"""
if self.testamentsfile:
self.wizard.progressBar.setMinimum(0)
self.wizard.progressBar.setMaximum(2)
self.wizard.progressBar.setValue(0)
testaments_file = None
try:
details = get_file_encoding(self.testamentsfile)
testaments_file = open(self.testamentsfile, 'rb')
testaments_reader = csv.reader(testaments_file, delimiter=',',
quotechar='"')
for line in testaments_reader:
if self.stop_import_flag:
break
self.wizard.incrementProgressBar(unicode(
translate('BibleDB.Wizard',
'Importing testaments... %s')) %
unicode(line[1], details['encoding']), 0)
self.save_object(Testament.populate(
name=unicode(line[1], details['encoding'])))
Receiver.send_message(u'openlp_process_events')
except (IOError, IndexError):
log.exception(u'Loading testaments from file failed')
finally:
if testaments_file:
testaments_file.close()
self.wizard.incrementProgressBar(unicode(translate(
'BibleDB.Wizard', 'Importing testaments... done.')), 2)
else:
BibleDB.setup_testaments(self)
def do_import(self): def do_import(self):
"""
Import the bible books and verses.
"""
self.wizard.progressBar.setValue(0)
self.wizard.progressBar.setMinimum(0)
self.wizard.progressBar.setMaximum(66)
success = True success = True
books_file = None books_file = None
book_ptr = None book_list = {}
verse_file = None
# Populate the Tables # Populate the Tables
try: try:
details = get_file_encoding(self.booksfile)
books_file = open(self.booksfile, 'r') books_file = open(self.booksfile, 'r')
dialect = csv.Sniffer().sniff(books_file.read(1024)) books_reader = csv.reader(books_file, delimiter=',', quotechar='"')
books_file.seek(0)
books_reader = csv.reader(books_file, dialect)
for line in books_reader: for line in books_reader:
# cancel pressed
if self.stop_import_flag: if self.stop_import_flag:
break break
details = chardet.detect(line[1]) self.wizard.incrementProgressBar(unicode(
self.create_book(unicode(line[1], details['encoding']), translate('BibleDB.Wizard', 'Importing books... %s')) %
line[2], int(line[0])) unicode(line[2], details['encoding']))
Receiver.send_message(u'openlp_process_events') self.create_book(unicode(line[2], details['encoding']),
unicode(line[3], details['encoding']), int(line[1]))
book_list[int(line[0])] = unicode(line[2], details['encoding'])
Receiver.send_message(u'openlp_process_events')
except (IOError, IndexError): except (IOError, IndexError):
log.exception(u'Loading books from file failed') log.exception(u'Loading books from file failed')
success = False success = False
finally: finally:
if books_file: if books_file:
books_file.close() books_file.close()
if not success: if self.stop_import_flag or not success:
return False return False
self.wizard.progressBar.setValue(0)
self.wizard.progressBar.setMaximum(67)
verse_file = None
try: try:
verse_file = open(self.versesfile, 'r') book_ptr = None
dialect = csv.Sniffer().sniff(verse_file.read(1024)) details = get_file_encoding(self.versesfile)
verse_file.seek(0) verse_file = open(self.versesfile, 'rb')
verse_reader = csv.reader(verse_file, dialect) verse_reader = csv.reader(verse_file, delimiter=',', quotechar='"')
for line in verse_reader: for line in verse_reader:
if self.stop_import_flag: if self.stop_import_flag:
# cancel pressed
break break
details = chardet.detect(line[3]) try:
if book_ptr != line[0]: line_book = book_list[int(line[0])]
book = self.get_book(line[0]) except ValueError:
line_book = unicode(line[0], details['encoding'])
if book_ptr != line_book:
book = self.get_book(line_book)
book_ptr = book.name book_ptr = book.name
self.wizard.incrementProgressBar(unicode(translate( self.wizard.incrementProgressBar(unicode(translate(
'BiblesPlugin.CSVImport', 'Importing %s %s...', 'BibleDB.Wizard', 'Importing verses from %s...',
'Importing <book name> <chapter>...')) % 'Importing verses from <book name>...')) % book.name)
(book.name, int(line[1])))
self.session.commit() self.session.commit()
self.create_verse(book.id, line[1], line[2], try:
unicode(line[3], details['encoding'])) verse_text = unicode(line[3], details['encoding'])
Receiver.send_message(u'openlp_process_events') except UnicodeError:
verse_text = unicode(line[3], u'cp1252')
self.create_verse(book.id, line[1], line[2], verse_text)
self.wizard.incrementProgressBar(translate('BibleDB.Wizard',
'Importing verses... done.'))
Receiver.send_message(u'openlp_process_events')
self.session.commit() self.session.commit()
except IOError: except IOError:
log.exception(u'Loading verses from file failed') log.exception(u'Loading verses from file failed')
@ -112,3 +205,18 @@ class CSVBible(BibleDB):
return False return False
else: else:
return success return success
def get_file_encoding(filename):
"""
Utility function to get the file encoding.
"""
detect_file = None
try:
detect_file = open(filename, 'r')
details = chardet.detect(detect_file.read(1024))
except IOError:
log.exception(u'Error detecting file encoding')
finally:
if detect_file:
detect_file.close()
return details

View File

@ -35,7 +35,7 @@ from sqlalchemy.orm.exc import UnmappedClassError
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.lib.db import BaseModel, init_db, Manager from openlp.core.lib.db import BaseModel, init_db, Manager
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import critical_error_message_box
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -206,10 +206,16 @@ class BibleDB(QtCore.QObject, Manager):
""" """
self.wizard = wizard self.wizard = wizard
self.create_meta(u'dbversion', u'2') self.create_meta(u'dbversion', u'2')
self.setup_testaments()
return self.name
def setup_testaments(self):
"""
Initialise the testaments section of a bible with suitable defaults.
"""
self.save_object(Testament.populate(name=u'Old Testament')) self.save_object(Testament.populate(name=u'Old Testament'))
self.save_object(Testament.populate(name=u'New Testament')) self.save_object(Testament.populate(name=u'New Testament'))
self.save_object(Testament.populate(name=u'Apocrypha')) self.save_object(Testament.populate(name=u'Apocrypha'))
return self.name
def create_book(self, name, abbrev, testament=1): def create_book(self, name, abbrev, testament=1):
""" """
@ -355,7 +361,7 @@ class BibleDB(QtCore.QObject, Manager):
verse_list.extend(verses) verse_list.extend(verses)
else: else:
log.debug(u'OpenLP failed to find book %s', book) log.debug(u'OpenLP failed to find book %s', book)
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'), translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching book ' translate('BiblesPlugin', 'No matching book '
'could be found in this Bible. Check that you have ' 'could be found in this Bible. Check that you have '

View File

@ -38,7 +38,7 @@ from HTMLParser import HTMLParseError
from BeautifulSoup import BeautifulSoup, NavigableString from BeautifulSoup import BeautifulSoup, NavigableString
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import critical_error_message_box
from openlp.core.utils import AppLocation, get_web_page from openlp.core.utils import AppLocation, get_web_page
from openlp.plugins.bibles.lib import SearchResults from openlp.plugins.bibles.lib import SearchResults
from openlp.plugins.bibles.lib.db import BibleDB, Book from openlp.plugins.bibles.lib.db import BibleDB, Book
@ -210,7 +210,8 @@ class BGExtract(object):
cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')] cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')]
soup = get_soup_for_bible_ref( soup = get_soup_for_bible_ref(
u'http://www.biblegateway.com/passage/?%s' % url_params, u'http://www.biblegateway.com/passage/?%s' % url_params,
cleaner=cleaner) pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='',
cleaner=cleaner)
if not soup: if not soup:
return None return None
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
@ -430,7 +431,7 @@ class HTTPBible(BibleDB):
if not db_book: if not db_book:
book_details = HTTPBooks.get_book(book) book_details = HTTPBooks.get_book(book)
if not book_details: if not book_details:
criticalErrorMessageBox( critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'), translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching ' translate('BiblesPlugin', 'No matching '
'book could be found in this Bible. Check that you ' 'book could be found in this Bible. Check that you '
@ -442,7 +443,6 @@ class HTTPBible(BibleDB):
book = db_book.name book = db_book.name
if BibleDB.get_verse_count(self, book, reference[1]) == 0: if BibleDB.get_verse_count(self, book, reference[1]) == 0:
Receiver.send_message(u'cursor_busy') Receiver.send_message(u'cursor_busy')
Receiver.send_message(u'openlp_process_events')
search_results = self.get_chapter(book, reference[1]) search_results = self.get_chapter(book, reference[1])
if search_results and search_results.has_verselist(): if search_results and search_results.has_verselist():
## We have found a book of the bible lets check to see ## We have found a book of the bible lets check to see
@ -499,7 +499,8 @@ class HTTPBible(BibleDB):
""" """
return HTTPBooks.get_verse_count(book, chapter) return HTTPBooks.get_verse_count(book, chapter)
def get_soup_for_bible_ref(reference_url, header=None, cleaner=None): def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None,
pre_parse_substitute=None, cleaner=None):
""" """
Gets a webpage and returns a parsed and optionally cleaned soup or None. Gets a webpage and returns a parsed and optionally cleaned soup or None.
@ -509,6 +510,13 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None):
``header`` ``header``
An optional HTTP header to pass to the bible web server. An optional HTTP header to pass to the bible web server.
``pre_parse_regex``
A regular expression to run on the webpage. Allows manipulation of the
webpage before passing to BeautifulSoup for parsing.
``pre_parse_substitute``
The text to replace any matches to the regular expression with.
``cleaner`` ``cleaner``
An optional regex to use during webpage parsing. An optional regex to use during webpage parsing.
""" """
@ -518,12 +526,15 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None):
if not page: if not page:
send_error_message(u'download') send_error_message(u'download')
return None return None
page_source = page.read()
if pre_parse_regex and pre_parse_substitute is not None:
page_source = re.sub(pre_parse_regex, pre_parse_substitute, page_source)
soup = None soup = None
try: try:
if cleaner: if cleaner:
soup = BeautifulSoup(page, markupMassage=cleaner) soup = BeautifulSoup(page_source, markupMassage=cleaner)
else: else:
soup = BeautifulSoup(page) soup = BeautifulSoup(page_source)
except HTMLParseError: except HTMLParseError:
log.exception(u'BeautifulSoup could not parse the bible page.') log.exception(u'BeautifulSoup could not parse the bible page.')
if not soup: if not soup:
@ -540,14 +551,14 @@ def send_error_message(error_type):
The type of error that occured for the issue. The type of error that occured for the issue.
""" """
if error_type == u'download': if error_type == u'download':
criticalErrorMessageBox( critical_error_message_box(
translate('BiblePlugin.HTTPBible', 'Download Error'), translate('BiblePlugin.HTTPBible', 'Download Error'),
translate('BiblePlugin.HTTPBible', 'There was a ' translate('BiblePlugin.HTTPBible', 'There was a '
'problem downloading your verse selection. Please check your ' 'problem downloading your verse selection. Please check your '
'Internet connection, and if this error continues to occur ' 'Internet connection, and if this error continues to occur '
'please consider reporting a bug.')) 'please consider reporting a bug.'))
elif error_type == u'parse': elif error_type == u'parse':
criticalErrorMessageBox( critical_error_message_box(
translate('BiblePlugin.HTTPBible', 'Parse Error'), translate('BiblePlugin.HTTPBible', 'Parse Error'),
translate('BiblePlugin.HTTPBible', 'There was a ' translate('BiblePlugin.HTTPBible', 'There was a '
'problem extracting your verse selection. If this error continues ' 'problem extracting your verse selection. If this error continues '

View File

@ -92,7 +92,7 @@ class BibleFormat(object):
return None return None
@staticmethod @staticmethod
def list(): def get_formats_list():
""" """
Return a list of the supported Bible formats. Return a list of the supported Bible formats.
""" """

View File

@ -28,21 +28,22 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
ItemCapabilities, translate translate
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import UiStrings, add_widget_completer, \
media_item_combo_box, critical_error_message_box
from openlp.plugins.bibles.forms import BibleImportForm from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib import get_reference_match from openlp.plugins.bibles.lib import get_reference_match
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class BibleListView(BaseListWithDnD): class BibleSearch(object):
""" """
Custom list view descendant, required for drag and drop. Enumeration class for the different search methods for the "quick search".
""" """
def __init__(self, parent=None): Reference = 1
self.PluginName = u'Bibles' Text = 2
BaseListWithDnD.__init__(self, parent)
class BibleMediaItem(MediaManagerItem): class BibleMediaItem(MediaManagerItem):
@ -53,7 +54,6 @@ class BibleMediaItem(MediaManagerItem):
def __init__(self, parent, plugin, icon): def __init__(self, parent, plugin, icon):
self.IconPath = u'songs/song' self.IconPath = u'songs/song'
self.ListViewWithDnD_class = BibleListView
MediaManagerItem.__init__(self, parent, plugin, icon) 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 = {}
@ -81,50 +81,33 @@ class BibleMediaItem(MediaManagerItem):
self.quickLayout.setObjectName(u'quickLayout') self.quickLayout.setObjectName(u'quickLayout')
self.quickVersionLabel = QtGui.QLabel(self.quickTab) self.quickVersionLabel = QtGui.QLabel(self.quickTab)
self.quickVersionLabel.setObjectName(u'quickVersionLabel') self.quickVersionLabel.setObjectName(u'quickVersionLabel')
self.quickVersionComboBox = QtGui.QComboBox(self.quickTab) self.quickVersionComboBox = media_item_combo_box(self.quickTab,
self.quickVersionComboBox.setSizeAdjustPolicy( u'quickVersionComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickVersionComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickVersionComboBox.setObjectName(u'quickVersionComboBox')
self.quickVersionLabel.setBuddy(self.quickVersionComboBox) self.quickVersionLabel.setBuddy(self.quickVersionComboBox)
self.quickLayout.addRow(self.quickVersionLabel, self.quickLayout.addRow(self.quickVersionLabel,
self.quickVersionComboBox) self.quickVersionComboBox)
self.quickSecondLabel = QtGui.QLabel(self.quickTab) self.quickSecondLabel = QtGui.QLabel(self.quickTab)
self.quickSecondLabel.setObjectName(u'quickSecondLabel') self.quickSecondLabel.setObjectName(u'quickSecondLabel')
self.quickSecondComboBox = QtGui.QComboBox(self.quickTab) self.quickSecondComboBox = media_item_combo_box(self.quickTab,
self.quickSecondComboBox.setSizeAdjustPolicy( u'quickSecondComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickSecondComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickSecondComboBox.setObjectName(u'quickSecondComboBox')
self.quickSecondLabel.setBuddy(self.quickSecondComboBox) self.quickSecondLabel.setBuddy(self.quickSecondComboBox)
self.quickLayout.addRow(self.quickSecondLabel, self.quickSecondComboBox) self.quickLayout.addRow(self.quickSecondLabel, self.quickSecondComboBox)
self.quickSearchTypeLabel = QtGui.QLabel(self.quickTab)
self.quickSearchTypeLabel.setObjectName(u'quickSearchTypeLabel')
self.quickSearchComboBox = QtGui.QComboBox(self.quickTab)
self.quickSearchComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickSearchComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickSearchComboBox.setObjectName(u'quickSearchComboBox')
self.quickSearchTypeLabel.setBuddy(self.quickSearchComboBox)
self.quickLayout.addRow(self.quickSearchTypeLabel,
self.quickSearchComboBox)
self.quickSearchLabel = QtGui.QLabel(self.quickTab) self.quickSearchLabel = QtGui.QLabel(self.quickTab)
self.quickSearchLabel.setObjectName(u'quickSearchLabel') self.quickSearchLabel.setObjectName(u'quickSearchLabel')
self.quickSearchEdit = QtGui.QLineEdit(self.quickTab) self.quickSearchEdit = SearchEdit(self.quickTab)
self.quickSearchEdit.setObjectName(u'quickSearchEdit') self.quickSearchEdit.setObjectName(u'quickSearchEdit')
self.quickSearchLabel.setBuddy(self.quickSearchEdit) self.quickSearchLabel.setBuddy(self.quickSearchEdit)
self.quickSearchEdit.setSearchTypes([
(BibleSearch.Reference, u':/bibles/bibles_search_reference.png',
translate('BiblesPlugin.MediaItem', 'Scripture Reference')),
(BibleSearch.Text, u':/bibles/bibles_search_text.png',
translate('BiblesPlugin.MediaItem', 'Text Search'))
])
self.quickLayout.addRow(self.quickSearchLabel, self.quickSearchEdit) self.quickLayout.addRow(self.quickSearchLabel, self.quickSearchEdit)
self.quickClearLabel = QtGui.QLabel(self.quickTab) self.quickClearLabel = QtGui.QLabel(self.quickTab)
self.quickClearLabel.setObjectName(u'quickClearLabel') self.quickClearLabel.setObjectName(u'quickClearLabel')
self.quickClearComboBox = QtGui.QComboBox(self.quickTab) self.quickClearComboBox = media_item_combo_box(self.quickTab,
self.quickClearComboBox.setSizeAdjustPolicy( u'quickClearComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.quickClearComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.quickClearComboBox.setObjectName(u'quickClearComboBox')
self.quickLayout.addRow(self.quickClearLabel, self.quickClearComboBox) self.quickLayout.addRow(self.quickClearLabel, self.quickClearComboBox)
self.quickSearchButtonLayout = QtGui.QHBoxLayout() self.quickSearchButtonLayout = QtGui.QHBoxLayout()
self.quickSearchButtonLayout.setObjectName(u'quickSearchButtonLayout') self.quickSearchButtonLayout.setObjectName(u'quickSearchButtonLayout')
@ -144,36 +127,24 @@ class BibleMediaItem(MediaManagerItem):
self.advancedVersionLabel.setObjectName(u'advancedVersionLabel') self.advancedVersionLabel.setObjectName(u'advancedVersionLabel')
self.advancedLayout.addWidget(self.advancedVersionLabel, 0, 0, self.advancedLayout.addWidget(self.advancedVersionLabel, 0, 0,
QtCore.Qt.AlignRight) QtCore.Qt.AlignRight)
self.advancedVersionComboBox = QtGui.QComboBox(self.advancedTab) self.advancedVersionComboBox = media_item_combo_box(self.advancedTab,
self.advancedVersionComboBox.setSizeAdjustPolicy( u'advancedVersionComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedVersionComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedVersionComboBox.setObjectName(u'advancedVersionComboBox')
self.advancedVersionLabel.setBuddy(self.advancedVersionComboBox) self.advancedVersionLabel.setBuddy(self.advancedVersionComboBox)
self.advancedLayout.addWidget(self.advancedVersionComboBox, 0, 1, 1, 2) self.advancedLayout.addWidget(self.advancedVersionComboBox, 0, 1, 1, 2)
self.advancedSecondLabel = QtGui.QLabel(self.advancedTab) self.advancedSecondLabel = QtGui.QLabel(self.advancedTab)
self.advancedSecondLabel.setObjectName(u'advancedSecondLabel') self.advancedSecondLabel.setObjectName(u'advancedSecondLabel')
self.advancedLayout.addWidget(self.advancedSecondLabel, 1, 0, self.advancedLayout.addWidget(self.advancedSecondLabel, 1, 0,
QtCore.Qt.AlignRight) QtCore.Qt.AlignRight)
self.advancedSecondComboBox = QtGui.QComboBox(self.advancedTab) self.advancedSecondComboBox = media_item_combo_box(self.advancedTab,
self.advancedSecondComboBox.setSizeAdjustPolicy( u'advancedSecondComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedSecondComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedSecondComboBox.setObjectName(u'advancedSecondComboBox')
self.advancedSecondLabel.setBuddy(self.advancedSecondComboBox) self.advancedSecondLabel.setBuddy(self.advancedSecondComboBox)
self.advancedLayout.addWidget(self.advancedSecondComboBox, 1, 1, 1, 2) self.advancedLayout.addWidget(self.advancedSecondComboBox, 1, 1, 1, 2)
self.advancedBookLabel = QtGui.QLabel(self.advancedTab) self.advancedBookLabel = QtGui.QLabel(self.advancedTab)
self.advancedBookLabel.setObjectName(u'advancedBookLabel') self.advancedBookLabel.setObjectName(u'advancedBookLabel')
self.advancedLayout.addWidget(self.advancedBookLabel, 2, 0, self.advancedLayout.addWidget(self.advancedBookLabel, 2, 0,
QtCore.Qt.AlignRight) QtCore.Qt.AlignRight)
self.advancedBookComboBox = QtGui.QComboBox(self.advancedTab) self.advancedBookComboBox = media_item_combo_box(self.advancedTab,
self.advancedBookComboBox.setSizeAdjustPolicy( u'advancedBookComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedBookComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedBookComboBox.setObjectName(u'advancedBookComboBox')
self.advancedBookLabel.setBuddy(self.advancedBookComboBox) self.advancedBookLabel.setBuddy(self.advancedBookComboBox)
self.advancedLayout.addWidget(self.advancedBookComboBox, 2, 1, 1, 2) self.advancedLayout.addWidget(self.advancedBookComboBox, 2, 1, 1, 2)
self.advancedChapterLabel = QtGui.QLabel(self.advancedTab) self.advancedChapterLabel = QtGui.QLabel(self.advancedTab)
@ -202,17 +173,12 @@ class BibleMediaItem(MediaManagerItem):
self.advancedToVerse = QtGui.QComboBox(self.advancedTab) self.advancedToVerse = QtGui.QComboBox(self.advancedTab)
self.advancedToVerse.setObjectName(u'advancedToVerse') self.advancedToVerse.setObjectName(u'advancedToVerse')
self.advancedLayout.addWidget(self.advancedToVerse, 5, 2) self.advancedLayout.addWidget(self.advancedToVerse, 5, 2)
self.advancedClearLabel = QtGui.QLabel(self.quickTab) self.advancedClearLabel = QtGui.QLabel(self.quickTab)
self.advancedClearLabel.setObjectName(u'advancedClearLabel') self.advancedClearLabel.setObjectName(u'advancedClearLabel')
self.advancedLayout.addWidget(self.advancedClearLabel, 6, 0, self.advancedLayout.addWidget(self.advancedClearLabel, 6, 0,
QtCore.Qt.AlignRight) QtCore.Qt.AlignRight)
self.advancedClearComboBox = QtGui.QComboBox(self.quickTab) self.advancedClearComboBox = media_item_combo_box(self.quickTab,
self.advancedClearComboBox.setSizeAdjustPolicy( u'advancedClearComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.advancedClearComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.advancedClearComboBox.setObjectName(u'advancedClearComboBox')
self.advancedClearLabel.setBuddy(self.advancedClearComboBox) self.advancedClearLabel.setBuddy(self.advancedClearComboBox)
self.advancedLayout.addWidget(self.advancedClearComboBox, 6, 1, 1, 2) self.advancedLayout.addWidget(self.advancedClearComboBox, 6, 1, 1, 2)
self.advancedSearchButtonLayout = QtGui.QHBoxLayout() self.advancedSearchButtonLayout = QtGui.QHBoxLayout()
@ -224,8 +190,7 @@ class BibleMediaItem(MediaManagerItem):
self.advancedSearchButtonLayout.addWidget(self.advancedSearchButton) self.advancedSearchButtonLayout.addWidget(self.advancedSearchButton)
self.advancedLayout.addLayout( self.advancedLayout.addLayout(
self.advancedSearchButtonLayout, 7, 0, 1, 3) self.advancedSearchButtonLayout, 7, 0, 1, 3)
self.searchTabWidget.addTab(self.advancedTab, self.searchTabWidget.addTab(self.advancedTab, UiStrings.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
@ -239,8 +204,8 @@ 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.QObject.connect(self.quickSearchEdit,
QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter) QtCore.SIGNAL(u'searchTypeChanged(int)'), self.updateAutoCompleter)
QtCore.QObject.connect(self.quickVersionComboBox, QtCore.QObject.connect(self.quickVersionComboBox,
QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter) QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter)
# Buttons # Buttons
@ -254,9 +219,6 @@ class BibleMediaItem(MediaManagerItem):
QtCore.QObject.connect(self.quickSearchEdit, QtCore.QObject.connect(self.quickSearchEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton) QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton)
def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self)
def configUpdated(self): def configUpdated(self):
log.debug(u'configUpdated') log.debug(u'configUpdated')
if QtCore.QSettings().value(self.settingsSection + u'/second bibles', if QtCore.QSettings().value(self.settingsSection + u'/second bibles',
@ -277,8 +239,6 @@ class BibleMediaItem(MediaManagerItem):
translate('BiblesPlugin.MediaItem', 'Version:')) translate('BiblesPlugin.MediaItem', 'Version:'))
self.quickSecondLabel.setText( self.quickSecondLabel.setText(
translate('BiblesPlugin.MediaItem', 'Second:')) translate('BiblesPlugin.MediaItem', 'Second:'))
self.quickSearchTypeLabel.setText(
translate('BiblesPlugin.MediaItem', 'Search type:'))
self.quickSearchLabel.setText( self.quickSearchLabel.setText(
translate('BiblesPlugin.MediaItem', 'Find:')) translate('BiblesPlugin.MediaItem', 'Find:'))
self.quickSearchButton.setText( self.quickSearchButton.setText(
@ -303,10 +263,6 @@ class BibleMediaItem(MediaManagerItem):
translate('BiblesPlugin.MediaItem', 'Results:')) translate('BiblesPlugin.MediaItem', 'Results:'))
self.advancedSearchButton.setText( self.advancedSearchButton.setText(
translate('BiblesPlugin.MediaItem', 'Search')) translate('BiblesPlugin.MediaItem', 'Search'))
self.quickSearchComboBox.addItem(
translate('BiblesPlugin.MediaItem', 'Verse Search'))
self.quickSearchComboBox.addItem(
translate('BiblesPlugin.MediaItem', 'Text Search'))
self.quickClearComboBox.addItem( self.quickClearComboBox.addItem(
translate('BiblesPlugin.MediaItem', 'Clear')) translate('BiblesPlugin.MediaItem', 'Clear'))
self.quickClearComboBox.addItem( self.quickClearComboBox.addItem(
@ -390,7 +346,8 @@ class BibleMediaItem(MediaManagerItem):
verse_count = self.parent.manager.get_verse_count(bible, book, 1) verse_count = self.parent.manager.get_verse_count(bible, book, 1)
if verse_count == 0: if verse_count == 0:
self.advancedSearchButton.setEnabled(False) self.advancedSearchButton.setEnabled(False)
criticalErrorMessageBox(message=translate('BiblePlugin.MediaItem', critical_error_message_box(
message=translate('BiblePlugin.MediaItem',
'Bible not fully loaded')) 'Bible not fully loaded'))
else: else:
self.advancedSearchButton.setEnabled(True) self.advancedSearchButton.setEnabled(True)
@ -403,20 +360,18 @@ class BibleMediaItem(MediaManagerItem):
""" """
This updates the bible book completion list for the search field. The 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 completion depends on the bible. It is only updated when we are doing a
verse search, otherwise the auto completion list is removed. reference search, otherwise the auto completion list is removed.
""" """
books = [] books = []
# We have to do a 'Verse Search'. # We have to do a 'Reference Search'.
if self.quickSearchComboBox.currentIndex() == 0: if self.quickSearchEdit.currentSearchType() == BibleSearch.Reference:
bibles = self.parent.manager.get_bibles() bibles = self.parent.manager.get_bibles()
bible = unicode(self.quickVersionComboBox.currentText()) bible = unicode(self.quickVersionComboBox.currentText())
if bible: if bible:
book_data = bibles[bible].get_books() book_data = bibles[bible].get_books()
books = [book.name for book in book_data] books = [book.name for book in book_data]
books.sort() books.sort()
completer = QtGui.QCompleter(books) add_widget_completer(books, self.quickSearchEdit)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.quickSearchEdit.setCompleter(completer)
def onAdvancedVersionComboBox(self): def onAdvancedVersionComboBox(self):
self.initialiseBible( self.initialiseBible(
@ -528,19 +483,7 @@ class BibleMediaItem(MediaManagerItem):
if self.advancedClearComboBox.currentIndex() == 0: if self.advancedClearComboBox.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. self.__checkSecondBible(bible, second_bible)
bitem = self.listView.item(0)
item_second_bible = self._decodeQtObject(bitem, 'second_bible')
if item_second_bible and second_bible or not item_second_bible and \
not second_bible:
self.displayResults(bible, second_bible)
elif criticalErrorMessageBox(
message=translate('BiblePlugin.MediaItem',
'You cannot combine single and second bible verses. Do you '
'want to delete your search results and start a new search?'),
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.listView.clear()
self.displayResults(bible, second_bible)
else: else:
self.displayResults(bible, second_bible) self.displayResults(bible, second_bible)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
@ -550,7 +493,7 @@ class BibleMediaItem(MediaManagerItem):
def onQuickSearchButton(self): def onQuickSearchButton(self):
""" """
Does a quick search and saves the search results. Quick search can Does a quick search and saves the search results. Quick search can
either be "Verse Search" or "Text Search". either be "Reference 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)
@ -558,8 +501,8 @@ class BibleMediaItem(MediaManagerItem):
bible = unicode(self.quickVersionComboBox.currentText()) bible = unicode(self.quickVersionComboBox.currentText())
second_bible = unicode(self.quickSecondComboBox.currentText()) second_bible = unicode(self.quickSecondComboBox.currentText())
text = unicode(self.quickSearchEdit.text()) text = unicode(self.quickSearchEdit.text())
if self.quickSearchComboBox.currentIndex() == 0: if self.quickSearchEdit.currentSearchType() == BibleSearch.Reference:
# We are doing a 'Verse Search'. # We are doing a 'Reference Search'.
self.search_results = self.parent.manager.get_verses(bible, text) self.search_results = self.parent.manager.get_verses(bible, text)
if second_bible and self.search_results: if second_bible and self.search_results:
self.second_search_results = self.parent.manager.get_verses( self.second_search_results = self.parent.manager.get_verses(
@ -580,24 +523,30 @@ class BibleMediaItem(MediaManagerItem):
if self.quickClearComboBox.currentIndex() == 0: if self.quickClearComboBox.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) self.__checkSecondBible(bible, second_bible)
item_second_bible = self._decodeQtObject(bitem, 'second_bible')
if item_second_bible and second_bible or not item_second_bible and \
not second_bible:
self.displayResults(bible, second_bible)
elif criticalErrorMessageBox(
message=translate('BiblePlugin.MediaItem',
'You cannot combine single and second bible verses. Do you '
'want to delete your search results and start a new search?'),
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.listView.clear()
self.displayResults(bible, second_bible)
elif self.search_results: elif self.search_results:
self.displayResults(bible, second_bible) self.displayResults(bible, second_bible)
self.quickSearchButton.setEnabled(True) self.quickSearchButton.setEnabled(True)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
def __checkSecondBible(self, bible, second_bible):
"""
Check if the first item is a second bible item or not.
"""
bitem = self.listView.item(0)
item_second_bible = self._decodeQtObject(bitem, 'second_bible')
if item_second_bible and second_bible or not item_second_bible and \
not second_bible:
self.displayResults(bible, second_bible)
elif critical_error_message_box(
message=translate('BiblePlugin.MediaItem',
'You cannot combine single and second bible verses. Do you '
'want to delete your search results and start a new search?'),
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.listView.clear()
self.displayResults(bible, second_bible)
def displayResults(self, bible, second_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

View File

@ -38,7 +38,6 @@ class OpenSongBible(BibleDB):
""" """
OpenSong Bible format importer class. OpenSong Bible format importer class.
""" """
def __init__(self, parent, **kwargs): def __init__(self, parent, **kwargs):
""" """
Constructor to create and set up an instance of the OpenSongBible Constructor to create and set up an instance of the OpenSongBible
@ -81,14 +80,13 @@ class OpenSongBible(BibleDB):
db_book.id, db_book.id,
int(chapter.attrib[u'n'].split()[-1]), int(chapter.attrib[u'n'].split()[-1]),
int(verse.attrib[u'n']), int(verse.attrib[u'n']),
unicode(verse.text) unicode(verse.text))
)
Receiver.send_message(u'openlp_process_events')
self.wizard.incrementProgressBar(unicode(translate( self.wizard.incrementProgressBar(unicode(translate(
'BiblesPlugin.Opensong', 'Importing %s %s...', 'BiblesPlugin.Opensong', 'Importing %s %s...',
'Importing <book name> <chapter>...')) % 'Importing <book name> <chapter>...')) %
(db_book.name, int(chapter.attrib[u'n'].split()[-1]))) (db_book.name, int(chapter.attrib[u'n'].split()[-1])))
self.session.commit() self.session.commit()
Receiver.send_message(u'openlp_process_events')
except (IOError, AttributeError): except (IOError, AttributeError):
log.exception(u'Loading bible from OpenSong file failed') log.exception(u'Loading bible from OpenSong file failed')
success = False success = False

View File

@ -19,7 +19,7 @@ IBS-fordítás (Új Károli), KAR
King James Version, KJV King James Version, KJV
Luther 1984, LUT Luther 1984, LUT
Septuaginta, LXX Septuaginta, LXX
Neue Genfer Übersetzung, NGÜ Neue Genfer Übersetzung, NGU
New International Readers Version, NIRV New International Readers Version, NIRV
New International Version, NIV New International Version, NIV
Neues Leben, NL Neues Leben, NL

1 عربي ARA
19 King James Version KJV
20 Luther 1984 LUT
21 Septuaginta LXX
22 Neue Genfer Übersetzung NGÜ NGU
23 New International Readers Version NIRV
24 New International Version NIV
25 Neues Leben NL

View File

@ -47,21 +47,14 @@ class CustomPlugin(Plugin):
log.info(u'Custom Plugin loaded') log.info(u'Custom Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Custom', u'1.9.4', plugin_helpers) Plugin.__init__(self, u'Custom', u'1.9.4', plugin_helpers,
CustomMediaItem, CustomTab)
self.weight = -5 self.weight = -5
self.manager = Manager(u'custom', init_schema) self.manager = Manager(u'custom', init_schema)
self.edit_custom_form = EditCustomForm(self.manager) self.edit_custom_form = EditCustomForm(self.manager)
self.icon_path = u':/plugins/plugin_custom.png' self.icon_path = u':/plugins/plugin_custom.png'
self.icon = build_icon(self.icon_path) self.icon = build_icon(self.icon_path)
def getSettingsTab(self):
visible_name = self.getString(StringContent.VisibleName)
return CustomTab(self.name, visible_name[u'title'])
def getMediaManagerItem(self):
# Create the ManagerItem object
return CustomMediaItem(self, self, self.icon)
def about(self): def about(self):
about_text = translate('CustomPlugin', '<strong>Custom Plugin</strong>' about_text = translate('CustomPlugin', '<strong>Custom Plugin</strong>'
'<br />The custom plugin provides the ability to set up custom ' '<br />The custom plugin provides the ability to set up custom '
@ -112,54 +105,20 @@ class CustomPlugin(Plugin):
u'title': translate('CustomsPlugin', 'Custom', 'container title') u'title': translate('CustomsPlugin', 'Custom', 'container title')
} }
# Middle Header Bar # Middle Header Bar
## Import Action ## tooltips = {
self.textStrings[StringContent.Import] = { u'load': translate('CustomsPlugin', 'Load a new Custom'),
u'title': translate('CustomsPlugin', 'Import'), u'import': translate('CustomsPlugin', 'Import a Custom'),
u'tooltip': translate('CustomsPlugin', u'new': translate('CustomsPlugin', 'Add a new Custom'),
'Import a Custom') u'edit': translate('CustomsPlugin', 'Edit the selected Custom'),
} u'delete': translate('CustomsPlugin', 'Delete the selected Custom'),
## Load Action ## u'preview': translate('CustomsPlugin',
self.textStrings[StringContent.Load] = { 'Preview the selected Custom'),
u'title': translate('CustomsPlugin', 'Load'), u'live': translate('CustomsPlugin',
u'tooltip': translate('CustomsPlugin', 'Send the selected Custom live'),
'Load a new Custom') u'service': translate('CustomsPlugin',
}
## New Action ##
self.textStrings[StringContent.New] = {
u'title': translate('CustomsPlugin', 'Add'),
u'tooltip': translate('CustomsPlugin',
'Add a new Custom')
}
## Edit Action ##
self.textStrings[StringContent.Edit] = {
u'title': translate('CustomsPlugin', 'Edit'),
u'tooltip': translate('CustomsPlugin',
'Edit the selected Custom')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('CustomsPlugin', 'Delete'),
u'tooltip': translate('CustomsPlugin',
'Delete the selected Custom')
}
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('CustomsPlugin', 'Preview'),
u'tooltip': translate('CustomsPlugin',
'Preview the selected Custom')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('CustomsPlugin', 'Live'),
u'tooltip': translate('CustomsPlugin',
'Send the selected Custom live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('CustomsPlugin', 'Service'),
u'tooltip': translate('CustomsPlugin',
'Add the selected Custom to the service') 'Add the selected Custom to the service')
} }
self.setPluginUiTextStrings(tooltips)
def finalise(self): def finalise(self):
""" """

View File

@ -27,6 +27,8 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate from openlp.core.lib import build_icon, translate
from openlp.core.lib.ui import UiStrings, create_accept_reject_button_box, \
create_delete_push_button, create_up_down_push_button_set
class Ui_CustomEditDialog(object): class Ui_CustomEditDialog(object):
def setupUi(self, customEditDialog): def setupUi(self, customEditDialog):
@ -58,22 +60,21 @@ class Ui_CustomEditDialog(object):
self.addButton.setObjectName(u'addButton') self.addButton.setObjectName(u'addButton')
self.buttonLayout.addWidget(self.addButton) self.buttonLayout.addWidget(self.addButton)
self.editButton = QtGui.QPushButton(customEditDialog) self.editButton = QtGui.QPushButton(customEditDialog)
self.editButton.setEnabled(False)
self.editButton.setObjectName(u'editButton') self.editButton.setObjectName(u'editButton')
self.buttonLayout.addWidget(self.editButton) self.buttonLayout.addWidget(self.editButton)
self.editAllButton = QtGui.QPushButton(customEditDialog) self.editAllButton = QtGui.QPushButton(customEditDialog)
self.editAllButton.setObjectName(u'editAllButton') self.editAllButton.setObjectName(u'editAllButton')
self.buttonLayout.addWidget(self.editAllButton) self.buttonLayout.addWidget(self.editAllButton)
self.deleteButton = QtGui.QPushButton(customEditDialog) self.deleteButton = create_delete_push_button(customEditDialog)
self.deleteButton.setObjectName(u'deleteButton') self.deleteButton.setEnabled(False)
self.buttonLayout.addWidget(self.deleteButton) self.buttonLayout.addWidget(self.deleteButton)
self.buttonLayout.addStretch() self.buttonLayout.addStretch()
self.upButton = QtGui.QPushButton(customEditDialog) self.upButton, self.downButton = create_up_down_push_button_set(
self.upButton.setIcon(build_icon(u':/services/service_up.png')) customEditDialog)
self.upButton.setObjectName(u'upButton') self.upButton.setEnabled(False)
self.downButton.setEnabled(False)
self.buttonLayout.addWidget(self.upButton) self.buttonLayout.addWidget(self.upButton)
self.downButton = QtGui.QPushButton(customEditDialog)
self.downButton.setIcon(build_icon(u':/services/service_down.png'))
self.downButton.setObjectName(u'downButton')
self.buttonLayout.addWidget(self.downButton) self.buttonLayout.addWidget(self.downButton)
self.centralLayout.addLayout(self.buttonLayout) self.centralLayout.addLayout(self.buttonLayout)
self.dialogLayout.addLayout(self.centralLayout) self.dialogLayout.addLayout(self.centralLayout)
@ -93,36 +94,24 @@ class Ui_CustomEditDialog(object):
self.creditLabel.setBuddy(self.creditEdit) self.creditLabel.setBuddy(self.creditEdit)
self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit) self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit)
self.dialogLayout.addLayout(self.bottomFormLayout) self.dialogLayout.addLayout(self.bottomFormLayout)
self.buttonBox = QtGui.QDialogButtonBox(customEditDialog) self.buttonBox = create_accept_reject_button_box(customEditDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | self.previewButton = QtGui.QPushButton()
QtGui.QDialogButtonBox.Save) self.buttonBox.addButton(
self.buttonBox.setObjectName(u'buttonBox') self.previewButton, QtGui.QDialogButtonBox.ActionRole)
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(customEditDialog) self.retranslateUi(customEditDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
customEditDialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
customEditDialog.closePressed)
QtCore.QMetaObject.connectSlotsByName(customEditDialog) QtCore.QMetaObject.connectSlotsByName(customEditDialog)
def retranslateUi(self, customEditDialog): def retranslateUi(self, customEditDialog):
customEditDialog.setWindowTitle( customEditDialog.setWindowTitle(
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides')) translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
self.upButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide up one '
'position.'))
self.downButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide down one '
'position.'))
self.titleLabel.setText( self.titleLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Title:')) translate('CustomPlugin.EditCustomForm', '&Title:'))
self.addButton.setText( self.addButton.setText(UiStrings.Add)
translate('CustomPlugin.EditCustomForm', '&Add'))
self.addButton.setToolTip( self.addButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Add a new slide at ' translate('CustomPlugin.EditCustomForm', 'Add a new slide at '
'bottom.')) 'bottom.'))
self.editButton.setText( self.editButton.setText(UiStrings.Edit)
translate('CustomPlugin.EditCustomForm', '&Edit'))
self.editButton.setToolTip( self.editButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit the selected ' translate('CustomPlugin.EditCustomForm', 'Edit the selected '
'slide.')) 'slide.'))
@ -131,12 +120,9 @@ class Ui_CustomEditDialog(object):
self.editAllButton.setToolTip( self.editAllButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit all the slides at ' translate('CustomPlugin.EditCustomForm', 'Edit all the slides at '
'once.')) 'once.'))
self.deleteButton.setText(
translate('CustomPlugin.EditCustomForm', '&Delete'))
self.deleteButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Delete the selected '
'slide.'))
self.themeLabel.setText( self.themeLabel.setText(
translate('CustomPlugin.EditCustomForm', 'The&me:')) translate('CustomPlugin.EditCustomForm', 'The&me:'))
self.creditLabel.setText( self.creditLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Credits:')) translate('CustomPlugin.EditCustomForm', '&Credits:'))
self.previewButton.setText(
translate('CustomPlugin.EditCustomForm', 'Save && Preview'))

View File

@ -29,7 +29,7 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide from openlp.plugins.custom.lib.db import CustomSlide
from editcustomdialog import Ui_CustomEditDialog from editcustomdialog import Ui_CustomEditDialog
@ -48,52 +48,22 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
""" """
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.setupUi(self) self.setupUi(self)
# Create other objects and forms.
self.manager = manager
self.editSlideForm = EditCustomSlideForm(self)
# Connecting signals and slots # Connecting signals and slots
self.previewButton = QtGui.QPushButton() QtCore.QObject.connect(self.previewButton,
self.previewButton.setText( QtCore.SIGNAL(u'pressed()'), self.onPreviewButtonPressed)
translate('CustomPlugin.EditCustomForm', 'Save && Preview'))
self.buttonBox.addButton(
self.previewButton, QtGui.QDialogButtonBox.ActionRole)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview)
QtCore.QObject.connect(self.addButton, QtCore.QObject.connect(self.addButton,
QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed)
QtCore.QObject.connect(self.editButton, QtCore.QObject.connect(self.editButton,
QtCore.SIGNAL(u'pressed()'), self.onEditButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onEditButtonPressed)
QtCore.QObject.connect(self.editAllButton, QtCore.QObject.connect(self.editAllButton,
QtCore.SIGNAL(u'pressed()'), self.onEditAllButtonPressed) QtCore.SIGNAL(u'pressed()'), self.onEditAllButtonPressed)
QtCore.QObject.connect(self.deleteButton,
QtCore.SIGNAL(u'pressed()'), self.onDeleteButtonPressed)
QtCore.QObject.connect(self.upButton,
QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed)
QtCore.QObject.connect(self.downButton,
QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed)
QtCore.QObject.connect(self.slideListView,
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
self.onSlideListViewPressed)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.loadThemes) QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
# Create other objects and forms. QtCore.QObject.connect(self.slideListView,
self.manager = manager QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
self.editSlideForm = EditCustomSlideForm(self)
self.initialise()
def onPreview(self, button):
log.debug(u'onPreview')
if button.text() == unicode(translate('CustomPlugin.EditCustomForm',
'Save && Preview')) and self.saveCustom():
Receiver.send_message(u'custom_preview')
def initialise(self):
self.addButton.setEnabled(True)
self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(True)
self.titleEdit.setText(u'')
self.creditEdit.setText(u'')
self.slideListView.clear()
# Make sure we have a new item.
self.customSlide = CustomSlide()
def loadThemes(self, themelist): def loadThemes(self, themelist):
self.themeComboBox.clear() self.themeComboBox.clear()
@ -112,9 +82,13 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
States whether the custom is edited while being previewed in the States whether the custom is edited while being previewed in the
preview panel. preview panel.
""" """
self.customSlide = CustomSlide() self.slideListView.clear()
self.initialise() if id == 0:
if id != 0: self.customSlide = CustomSlide()
self.titleEdit.setText(u'')
self.creditEdit.setText(u'')
self.themeComboBox.setCurrentIndex(0)
else:
self.customSlide = self.manager.get_object(CustomSlide, id) self.customSlide = self.manager.get_object(CustomSlide, id)
self.titleEdit.setText(self.customSlide.title) self.titleEdit.setText(self.customSlide.title)
self.creditEdit.setText(self.customSlide.credits) self.creditEdit.setText(self.customSlide.credits)
@ -128,31 +102,26 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
if id == -1: if id == -1:
id = 0 id = 0
self.themeComboBox.setCurrentIndex(id) self.themeComboBox.setCurrentIndex(id)
else:
self.themeComboBox.setCurrentIndex(0)
self.editAllButton.setEnabled(False)
# If not preview hide the preview button. # If not preview hide the preview button.
self.previewButton.setVisible(False) self.previewButton.setVisible(False)
if preview: if preview:
self.previewButton.setVisible(True) self.previewButton.setVisible(True)
def closePressed(self): def reject(self):
Receiver.send_message(u'custom_edit_clear') Receiver.send_message(u'custom_edit_clear')
self.close() QtGui.QDialog.reject(self)
def accept(self): def accept(self):
log.debug(u'accept') log.debug(u'accept')
if self.saveCustom(): if self.saveCustom():
Receiver.send_message(u'custom_load_list') Receiver.send_message(u'custom_load_list')
self.close() QtGui.QDialog.accept(self)
def saveCustom(self): def saveCustom(self):
""" """
Saves the custom. Saves the custom.
""" """
valid, message = self._validate() if not self._validate():
if not valid:
criticalErrorMessageBox(message=message)
return False return False
sxml = CustomXMLBuilder() sxml = CustomXMLBuilder()
sxml.new_document() sxml.new_document()
@ -168,14 +137,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.customSlide.theme_name = unicode(self.themeComboBox.currentText()) self.customSlide.theme_name = unicode(self.themeComboBox.currentText())
return self.manager.save_object(self.customSlide) return self.manager.save_object(self.customSlide)
def onUpButtonPressed(self): def onUpButtonClicked(self):
selectedRow = self.slideListView.currentRow() selectedRow = self.slideListView.currentRow()
if selectedRow != 0: if selectedRow != 0:
qw = self.slideListView.takeItem(selectedRow) qw = self.slideListView.takeItem(selectedRow)
self.slideListView.insertItem(selectedRow - 1, qw) self.slideListView.insertItem(selectedRow - 1, qw)
self.slideListView.setCurrentRow(selectedRow - 1) self.slideListView.setCurrentRow(selectedRow - 1)
def onDownButtonPressed(self): def onDownButtonClicked(self):
selectedRow = self.slideListView.currentRow() selectedRow = self.slideListView.currentRow()
# zero base arrays # zero base arrays
if selectedRow != self.slideListView.count() - 1: if selectedRow != self.slideListView.count() - 1:
@ -183,16 +152,11 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.slideListView.insertItem(selectedRow + 1, qw) self.slideListView.insertItem(selectedRow + 1, qw)
self.slideListView.setCurrentRow(selectedRow + 1) self.slideListView.setCurrentRow(selectedRow + 1)
def onSlideListViewPressed(self, item):
self.deleteButton.setEnabled(True)
self.editButton.setEnabled(True)
def onAddButtonPressed(self): def onAddButtonPressed(self):
self.editSlideForm.setText(u'') self.editSlideForm.setText(u'')
if self.editSlideForm.exec_(): if self.editSlideForm.exec_():
for slide in self.editSlideForm.getText(): for slide in self.editSlideForm.getText():
self.slideListView.addItem(slide) self.slideListView.addItem(slide)
self.editAllButton.setEnabled(True)
def onEditButtonPressed(self): def onEditButtonPressed(self):
self.editSlideForm.setText(self.slideListView.currentItem().text()) self.editSlideForm.setText(self.slideListView.currentItem().text())
@ -203,16 +167,23 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
""" """
Edits all slides. Edits all slides.
""" """
if self.slideListView.count() > 0: slide_list = u''
slide_list = u'' for row in range(0, self.slideListView.count()):
for row in range(0, self.slideListView.count()): item = self.slideListView.item(row)
item = self.slideListView.item(row) slide_list += item.text()
slide_list += item.text() if row != self.slideListView.count() - 1:
if row != self.slideListView.count() - 1: slide_list += u'\n[---]\n'
slide_list += u'\n[---]\n' self.editSlideForm.setText(slide_list)
self.editSlideForm.setText(slide_list) if self.editSlideForm.exec_():
if self.editSlideForm.exec_(): self.updateSlideList(self.editSlideForm.getText(), True)
self.updateSlideList(self.editSlideForm.getText(), True)
def onPreviewButtonPressed(self):
"""
Save the custom item and preview it.
"""
log.debug(u'onPreview')
if self.saveCustom():
Receiver.send_message(u'custom_preview')
def updateSlideList(self, slides, edit_all=False): def updateSlideList(self, slides, edit_all=False):
""" """
@ -243,14 +214,41 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.slideListView.addItem(slide) self.slideListView.addItem(slide)
self.slideListView.repaint() self.slideListView.repaint()
def onDeleteButtonPressed(self): def onDeleteButtonClicked(self):
"""
Removes the current row from the list.
"""
self.slideListView.takeItem(self.slideListView.currentRow()) self.slideListView.takeItem(self.slideListView.currentRow())
self.editButton.setEnabled(True) if self.slideListView.currentRow() == 0:
self.editAllButton.setEnabled(True) self.upButton.setEnabled(False)
if self.slideListView.count() == 0: if self.slideListView.currentRow() == self.slideListView.count():
self.downButton.setEnabled(False)
def onCurrentRowChanged(self, row):
"""
Called when the *slideListView*'s current row has been changed. This
enables or disables buttons which require an slide to act on.
``row``
The row (int). If there is no current row, the value is -1.
"""
if row == -1:
self.deleteButton.setEnabled(False) self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False) self.editButton.setEnabled(False)
self.editAllButton.setEnabled(False) self.upButton.setEnabled(False)
self.downButton.setEnabled(False)
else:
self.deleteButton.setEnabled(True)
self.editButton.setEnabled(True)
# Decide if the up/down buttons should be enabled or not.
if self.slideListView.count() - 1 == row:
self.downButton.setEnabled(False)
else:
self.downButton.setEnabled(True)
if row == 0:
self.upButton.setEnabled(False)
else:
self.upButton.setEnabled(True)
def _validate(self): def _validate(self):
""" """
@ -259,10 +257,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
# We must have a title. # We must have a title.
if len(self.titleEdit.displayText()) == 0: if len(self.titleEdit.displayText()) == 0:
self.titleEdit.setFocus() self.titleEdit.setFocus()
return False, translate('CustomPlugin.EditCustomForm', critical_error_message_box(
'You need to type in a title.') message=translate('CustomPlugin.EditCustomForm',
'You need to type in a title.'))
return False
# We must have at least one slide. # We must have at least one slide.
if self.slideListView.count() == 0: if self.slideListView.count() == 0:
return False, translate('CustomPlugin.EditCustomForm', critical_error_message_box(
'You need to add at least one slide') message=translate('CustomPlugin.EditCustomForm',
return True, u'' 'You need to add at least one slide'))
return False
return True

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, SpellTextEdit from openlp.core.lib import translate, SpellTextEdit
from openlp.core.lib.ui import create_accept_reject_button_box
class Ui_CustomSlideEditDialog(object): class Ui_CustomSlideEditDialog(object):
def setupUi(self, customSlideEditDialog): def setupUi(self, customSlideEditDialog):
@ -36,20 +37,13 @@ class Ui_CustomSlideEditDialog(object):
self.slideTextEdit = SpellTextEdit(self) self.slideTextEdit = SpellTextEdit(self)
self.slideTextEdit.setObjectName(u'slideTextEdit') self.slideTextEdit.setObjectName(u'slideTextEdit')
self.dialogLayout.addWidget(self.slideTextEdit) self.dialogLayout.addWidget(self.slideTextEdit)
self.buttonBox = QtGui.QDialogButtonBox(customSlideEditDialog) self.buttonBox = create_accept_reject_button_box(customSlideEditDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.splitButton = QtGui.QPushButton(customSlideEditDialog) self.splitButton = QtGui.QPushButton(customSlideEditDialog)
self.splitButton.setObjectName(u'splitButton') self.splitButton.setObjectName(u'splitButton')
self.buttonBox.addButton(self.splitButton, self.buttonBox.addButton(self.splitButton,
QtGui.QDialogButtonBox.ActionRole) QtGui.QDialogButtonBox.ActionRole)
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(customSlideEditDialog) self.retranslateUi(customSlideEditDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
customSlideEditDialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
customSlideEditDialog.reject)
QtCore.QMetaObject.connectSlotsByName(customSlideEditDialog) QtCore.QMetaObject.connectSlotsByName(customSlideEditDialog)
def retranslateUi(self, customSlideEditDialog): def retranslateUi(self, customSlideEditDialog):

View File

@ -28,18 +28,13 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, \ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
Receiver, ItemCapabilities, translate, check_item_selected translate, check_item_selected
from openlp.plugins.custom.lib import CustomXMLParser from openlp.plugins.custom.lib import CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide from openlp.plugins.custom.lib.db import CustomSlide
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class CustomListView(BaseListWithDnD):
def __init__(self, parent=None):
self.PluginName = u'Custom'
BaseListWithDnD.__init__(self, parent)
class CustomMediaItem(MediaManagerItem): class CustomMediaItem(MediaManagerItem):
""" """
This is the custom media manager item for Custom Slides. This is the custom media manager item for Custom Slides.
@ -48,9 +43,6 @@ class CustomMediaItem(MediaManagerItem):
def __init__(self, parent, plugin, icon): def __init__(self, parent, plugin, icon):
self.IconPath = u'custom/custom' self.IconPath = u'custom/custom'
# this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = CustomListView
MediaManagerItem.__init__(self, parent, self, icon) MediaManagerItem.__init__(self, parent, self, icon)
self.singleServiceItem = False self.singleServiceItem = False
# Holds information about whether the edit is remotly triggered and # Holds information about whether the edit is remotly triggered and
@ -68,11 +60,8 @@ class CustomMediaItem(MediaManagerItem):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick) QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
def requiredIcons(self):
MediaManagerItem.requiredIcons(self)
def initialise(self): def initialise(self):
self.loadCustomListView(self.manager.get_all_objects( self.loadList(self.manager.get_all_objects(
CustomSlide, order_by_ref=CustomSlide.title)) CustomSlide, order_by_ref=CustomSlide.title))
# Called to redisplay the custom list screen edith from a search # Called to redisplay the custom list screen edith from a search
# or from the exit of the Custom edit dialog. If remote editing is # or from the exit of the Custom edit dialog. If remote editing is
@ -83,7 +72,7 @@ class CustomMediaItem(MediaManagerItem):
self.onPreviewClick() self.onPreviewClick()
self.onRemoteEditClear() self.onRemoteEditClear()
def loadCustomListView(self, list): def loadList(self, list):
self.listView.clear() self.listView.clear()
for customSlide in list: for customSlide in list:
custom_name = QtGui.QListWidgetItem(customSlide.title) custom_name = QtGui.QListWidgetItem(customSlide.title)
@ -149,16 +138,7 @@ class CustomMediaItem(MediaManagerItem):
raw_footer = [] raw_footer = []
slide = None slide = None
theme = None theme = None
if item is None: item_id = self._getIdOfItemToGenerate(item, self.remoteCustom)
if self.remoteTriggered is None:
item = self.listView.currentItem()
if item is None:
return False
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
else:
item_id = self.remoteCustom
else:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)
@ -182,4 +162,4 @@ class CustomMediaItem(MediaManagerItem):
else: else:
raw_footer.append(u'') raw_footer.append(u'')
service_item.raw_footer = raw_footer service_item.raw_footer = raw_footer
return True return True

View File

@ -35,15 +35,12 @@ class ImagePlugin(Plugin):
log.info(u'Image Plugin loaded') log.info(u'Image Plugin loaded')
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Images', u'1.9.4', plugin_helpers) Plugin.__init__(self, u'Images', u'1.9.4', plugin_helpers,
ImageMediaItem)
self.weight = -7 self.weight = -7
self.icon_path = u':/plugins/plugin_images.png' self.icon_path = u':/plugins/plugin_images.png'
self.icon = build_icon(self.icon_path) self.icon = build_icon(self.icon_path)
def getMediaManagerItem(self):
# Create the MediaManagerItem object.
return ImageMediaItem(self, self, self.icon)
def about(self): def about(self):
about_text = translate('ImagePlugin', '<strong>Image Plugin</strong>' about_text = translate('ImagePlugin', '<strong>Image Plugin</strong>'
'<br />The image plugin provides displaying of images.<br />One ' '<br />The image plugin provides displaying of images.<br />One '
@ -72,45 +69,15 @@ class ImagePlugin(Plugin):
u'title': translate('ImagePlugin', 'Images', 'container title') u'title': translate('ImagePlugin', 'Images', 'container title')
} }
# Middle Header Bar # Middle Header Bar
## Load Button ## tooltips = {
self.textStrings[StringContent.Load] = { u'load': translate('ImagePlugin', 'Load a new Image'),
u'title': translate('ImagePlugin', 'Load'), u'import': u'',
u'tooltip': translate('ImagePlugin', u'new': translate('ImagePlugin', 'Add a new Image'),
'Load a new Image') u'edit': translate('ImagePlugin', 'Edit the selected Image'),
} u'delete': translate('ImagePlugin', 'Delete the selected Image'),
## New Button ## u'preview': translate('ImagePlugin', 'Preview the selected Image'),
self.textStrings[StringContent.New] = { u'live': translate('ImagePlugin', 'Send the selected Image live'),
u'title': translate('ImagePlugin', 'Add'), u'service': translate('ImagePlugin',
u'tooltip': translate('ImagePlugin',
'Add a new Image')
}
## Edit Button ##
self.textStrings[StringContent.Edit] = {
u'title': translate('ImagePlugin', 'Edit'),
u'tooltip': translate('ImagePlugin',
'Edit the selected Image')
}
## Delete Button ##
self.textStrings[StringContent.Delete] = {
u'title': translate('ImagePlugin', 'Delete'),
u'tooltip': translate('ImagePlugin',
'Delete the selected Image')
}
## Preview ##
self.textStrings[StringContent.Preview] = {
u'title': translate('ImagePlugin', 'Preview'),
u'tooltip': translate('ImagePlugin',
'Preview the selected Image')
}
## Live Button ##
self.textStrings[StringContent.Live] = {
u'title': translate('ImagePlugin', 'Live'),
u'tooltip': translate('ImagePlugin',
'Send the selected Image live')
}
## Add to service Button ##
self.textStrings[StringContent.Service] = {
u'title': translate('ImagePlugin', 'Service'),
u'tooltip': translate('ImagePlugin',
'Add the selected Image to the service') 'Add the selected Image to the service')
} }
self.setPluginUiTextStrings(tooltips)

View File

@ -29,22 +29,14 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \
ItemCapabilities, SettingsManager, translate, check_item_selected, \ SettingsManager, translate, check_item_selected, check_directory_exists, \
check_directory_exists Receiver
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.utils import AppLocation, delete_file, get_images_filter from openlp.core.utils import AppLocation, delete_file, get_images_filter
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# We have to explicitly create separate classes for each plugin
# in order for DnD to the Service manager to work correctly.
class ImageListView(BaseListWithDnD):
def __init__(self, parent=None):
self.PluginName = u'Images'
BaseListWithDnD.__init__(self, parent)
class ImageMediaItem(MediaManagerItem): class ImageMediaItem(MediaManagerItem):
""" """
This is the custom media manager item for images. This is the custom media manager item for images.
@ -53,25 +45,20 @@ class ImageMediaItem(MediaManagerItem):
def __init__(self, parent, plugin, icon): def __init__(self, parent, plugin, icon):
self.IconPath = u'images/image' self.IconPath = u'images/image'
# This next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem.
self.ListViewWithDnD_class = ImageListView
MediaManagerItem.__init__(self, parent, self, icon) MediaManagerItem.__init__(self, parent, self, icon)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged)
def retranslateUi(self): def retranslateUi(self):
self.OnNewPrompt = translate('ImagePlugin.MediaItem', self.OnNewPrompt = translate('ImagePlugin.MediaItem',
'Select Image(s)') 'Select Image(s)')
file_formats = get_images_filter() file_formats = get_images_filter()
self.OnNewFileMasks = u'%s;;%s (*.*) (*)' % (file_formats, self.OnNewFileMasks = u'%s;;%s (*.*) (*)' % (file_formats,
unicode(translate('ImagePlugin.MediaItem', 'All Files'))) UiStrings.AllFiles)
self.replaceAction.setText( self.replaceAction.setText(UiStrings.ReplaceBG)
translate('ImagePlugin.MediaItem', 'Replace Background')) self.replaceAction.setToolTip(UiStrings.ReplaceLiveBG)
self.replaceAction.setToolTip( self.resetAction.setText(UiStrings.ResetBG)
translate('ImagePlugin.MediaItem', 'Replace Live Background')) self.resetAction.setToolTip(UiStrings.ResetLiveBG)
self.resetAction.setText(
translate('ImagePlugin.MediaItem', 'Reset Background'))
self.resetAction.setToolTip(
translate('ImagePlugin.MediaItem', 'Reset Live Background'))
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
@ -83,8 +70,6 @@ class ImageMediaItem(MediaManagerItem):
def initialise(self): def initialise(self):
log.debug(u'initialise') log.debug(u'initialise')
self.listView.clear() self.listView.clear()
self.listView.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
self.listView.setIconSize(QtCore.QSize(88, 50)) self.listView.setIconSize(QtCore.QSize(88, 50))
self.servicePath = os.path.join( self.servicePath = os.path.join(
AppLocation.get_section_data_path(self.settingsSection), AppLocation.get_section_data_path(self.settingsSection),
@ -95,7 +80,6 @@ class ImageMediaItem(MediaManagerItem):
def addListViewToToolBar(self): def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self) MediaManagerItem.addListViewToToolBar(self)
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
self.listView.addAction(self.replaceAction) self.listView.addAction(self.replaceAction)
def addEndHeaderBar(self): def addEndHeaderBar(self):
@ -123,26 +107,26 @@ class ImageMediaItem(MediaManagerItem):
self.settingsSection, self.getFileList()) self.settingsSection, self.getFileList())
def loadList(self, list): def loadList(self, list):
for file in list: for imageFile in list:
filename = os.path.split(unicode(file))[1] filename = os.path.split(unicode(imageFile))[1]
thumb = os.path.join(self.servicePath, filename) thumb = os.path.join(self.servicePath, filename)
if os.path.exists(thumb): if os.path.exists(thumb):
if self.validate(file, thumb): if self.validate(imageFile, thumb):
icon = build_icon(thumb) icon = build_icon(thumb)
else: else:
icon = build_icon(u':/general/general_delete.png') icon = build_icon(u':/general/general_delete.png')
else: else:
icon = self.iconFromFile(file, thumb) icon = self.iconFromFile(imageFile, thumb)
item_name = QtGui.QListWidgetItem(filename) item_name = QtGui.QListWidgetItem(filename)
item_name.setIcon(icon) item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
self.listView.addItem(item_name) self.listView.addItem(item_name)
def generateSlideData(self, service_item, item=None, xmlVersion=False): 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(
translate('ImagePlugin.MediaItem', 'Image(s)')) translate('ImagePlugin.MediaItem', 'Images'))
service_item.add_capability(ItemCapabilities.AllowsMaintain) service_item.add_capability(ItemCapabilities.AllowsMaintain)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)
@ -161,7 +145,7 @@ class ImageMediaItem(MediaManagerItem):
items.remove(item) items.remove(item)
# We cannot continue, as all images do not exist. # We cannot continue, as all images do not exist.
if not items: if not items:
criticalErrorMessageBox( critical_error_message_box(
translate('ImagePlugin.MediaItem', 'Missing Image(s)'), translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
unicode(translate('ImagePlugin.MediaItem', unicode(translate('ImagePlugin.MediaItem',
'The following image(s) no longer exist: %s')) % 'The following image(s) no longer exist: %s')) %
@ -193,6 +177,12 @@ class ImageMediaItem(MediaManagerItem):
self.resetAction.setVisible(False) self.resetAction.setVisible(False)
self.parent.liveController.display.resetImage() self.parent.liveController.display.resetImage()
def liveThemeChanged(self):
"""
Triggered by the change of theme in the slide controller
"""
self.resetAction.setVisible(False)
def onReplaceClick(self): def onReplaceClick(self):
""" """
Called to replace Live backgound with the image selected. Called to replace Live backgound with the image selected.
@ -208,11 +198,8 @@ class ImageMediaItem(MediaManagerItem):
self.parent.liveController.display.directImage(name, filename) self.parent.liveController.display.directImage(name, filename)
self.resetAction.setVisible(True) self.resetAction.setVisible(True)
else: else:
criticalErrorMessageBox( critical_error_message_box(
translate('ImagePlugin.MediaItem', 'Live Background Error'), translate('ImagePlugin.MediaItem', 'Live Background Error'),
unicode(translate('ImagePlugin.MediaItem', unicode(translate('ImagePlugin.MediaItem',
'There was a problem replacing your background, ' 'There was a problem replacing your background, '
'the image file "%s" no longer exists.')) % filename) 'the image file "%s" no longer exists.')) % filename)
def onPreviewClick(self):
MediaManagerItem.onPreviewClick(self)

View File

@ -29,18 +29,13 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \
ItemCapabilities, SettingsManager, translate, check_item_selected SettingsManager, translate, check_item_selected, Receiver
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import UiStrings, critical_error_message_box
from PyQt4.phonon import Phonon
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class MediaListView(BaseListWithDnD):
def __init__(self, parent=None):
self.PluginName = u'Media'
BaseListWithDnD.__init__(self, parent)
class MediaMediaItem(MediaManagerItem): class MediaMediaItem(MediaManagerItem):
""" """
This is the custom media manager item for Media Slides. This is the custom media manager item for Media Slides.
@ -50,28 +45,27 @@ class MediaMediaItem(MediaManagerItem):
def __init__(self, parent, plugin, icon): def __init__(self, parent, plugin, icon):
self.IconPath = u'images/image' self.IconPath = u'images/image'
self.background = False self.background = False
# this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = MediaListView
self.PreviewFunction = QtGui.QPixmap( self.PreviewFunction = QtGui.QPixmap(
u':/media/media_video.png').toImage() u':/media/media_video.png').toImage()
MediaManagerItem.__init__(self, parent, self, icon) MediaManagerItem.__init__(self, parent, self, icon)
self.singleServiceItem = False self.singleServiceItem = False
self.serviceItemIconName = u':/media/image_clapperboard.png' self.mediaObject = Phonon.MediaObject(self)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'video_background_replaced'),
self.videobackgroundReplaced)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
self.videoStart)
def retranslateUi(self): def retranslateUi(self):
self.OnNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media') self.OnNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
self.OnNewFileMasks = unicode(translate('MediaPlugin.MediaItem', self.OnNewFileMasks = unicode(translate('MediaPlugin.MediaItem',
'Videos (%s);;Audio (%s);;All files (*)')) % \ 'Videos (%s);;Audio (%s);;%s (*)')) % (self.parent.video_list,
(self.parent.video_list, self.parent.audio_list) self.parent.audio_list, UiStrings.AllFiles)
self.replaceAction.setText( self.replaceAction.setText(UiStrings.ReplaceBG)
translate('MediaPlugin.MediaItem', 'Replace Background')) self.replaceAction.setToolTip(UiStrings.ReplaceLiveBG)
self.replaceAction.setToolTip( self.resetAction.setText(UiStrings.ResetBG)
translate('MediaPlugin.MediaItem', 'Replace Live Background')) self.resetAction.setToolTip(UiStrings.ResetLiveBG)
self.resetAction.setText(
translate('MediaPlugin.MediaItem', 'Reset Background'))
self.resetAction.setToolTip(
translate('ImagePlugin.MediaItem', 'Reset Live Background'))
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
@ -81,7 +75,6 @@ class MediaMediaItem(MediaManagerItem):
def addListViewToToolBar(self): def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self) MediaManagerItem.addListViewToToolBar(self)
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
self.listView.addAction(self.replaceAction) self.listView.addAction(self.replaceAction)
def addEndHeaderBar(self): def addEndHeaderBar(self):
@ -99,6 +92,12 @@ class MediaMediaItem(MediaManagerItem):
self.resetAction.setVisible(False) self.resetAction.setVisible(False)
self.parent.liveController.display.resetVideo() self.parent.liveController.display.resetVideo()
def videobackgroundReplaced(self):
"""
Triggered by main display on change of serviceitem
"""
self.resetAction.setVisible(False)
def onReplaceClick(self): def onReplaceClick(self):
""" """
Called to replace Live backgound with the media selected. Called to replace Live backgound with the media selected.
@ -113,7 +112,7 @@ class MediaMediaItem(MediaManagerItem):
self.parent.liveController.display.video(filename, 0, True) self.parent.liveController.display.video(filename, 0, True)
self.resetAction.setVisible(True) self.resetAction.setVisible(True)
else: else:
criticalErrorMessageBox(translate('MediaPlugin.MediaItem', critical_error_message_box(translate('MediaPlugin.MediaItem',
'Live Background Error'), 'Live Background Error'),
unicode(translate('MediaPlugin.MediaItem', unicode(translate('MediaPlugin.MediaItem',
'There was a problem replacing your background, ' 'There was a problem replacing your background, '
@ -126,26 +125,34 @@ class MediaMediaItem(MediaManagerItem):
return False return False
filename = unicode(item.data(QtCore.Qt.UserRole).toString()) filename = unicode(item.data(QtCore.Qt.UserRole).toString())
if os.path.exists(filename): if os.path.exists(filename):
self.MediaState = None
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.mediaObject.setCurrentSource(Phonon.MediaSource(filename))
self.mediaObject.play()
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)
service_item.add_capability(ItemCapabilities.AllowsVarableStartTime)
# force a nonexistent theme # force a nonexistent theme
service_item.theme = -1 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)
while not self.MediaState:
Receiver.send_message(u'openlp_process_events')
service_item.media_length = self.mediaLength
service_item.add_from_command(path, name, frame) service_item.add_from_command(path, name, frame)
return True return True
else: else:
# File is no longer present # File is no longer present
criticalErrorMessageBox( critical_error_message_box(
translate('MediaPlugin.MediaItem', 'Missing Media File'), translate('MediaPlugin.MediaItem', 'Missing Media File'),
unicode(translate('MediaPlugin.MediaItem', unicode(translate('MediaPlugin.MediaItem',
'The file %s no longer exists.')) % filename) 'The file %s no longer exists.')) % filename)
return False return False
def initialise(self): def initialise(self):
self.listView.setSelectionMode( self.listView.clear()
QtGui.QAbstractItemView.ExtendedSelection)
self.listView.setIconSize(QtCore.QSize(88, 50)) self.listView.setIconSize(QtCore.QSize(88, 50))
self.loadList(SettingsManager.load_list(self.settingsSection, self.loadList(SettingsManager.load_list(self.settingsSection,
self.settingsSection)) self.settingsSection))
@ -171,3 +178,12 @@ class MediaMediaItem(MediaManagerItem):
item_name.setIcon(build_icon(img)) item_name.setIcon(build_icon(img))
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 videoStart(self, newState, oldState):
"""
Start the video at a predetermined point.
"""
if newState == Phonon.PlayingState:
self.MediaState = newState
self.mediaLength = self.mediaObject.totalTime()/1000
self.mediaObject.stop()

View File

@ -32,8 +32,8 @@ class MediaTab(SettingsTab):
""" """
MediaTab is the Media settings tab in the settings dialog. MediaTab is the Media settings tab in the settings dialog.
""" """
def __init__(self, title): def __init__(self, title, visible_title):
SettingsTab.__init__(self, title) SettingsTab.__init__(self, title, visible_title)
def setupUi(self): def setupUi(self):
self.setObjectName(u'MediaTab') self.setObjectName(u'MediaTab')
@ -53,9 +53,8 @@ class MediaTab(SettingsTab):
self.onUsePhononCheckBoxChanged) self.onUsePhononCheckBoxChanged)
def retranslateUi(self): def retranslateUi(self):
self.tabTitleVisible = translate('MediaPlugin.MediaTab', 'Media') self.mediaModeGroupBox.setTitle(
self.mediaModeGroupBox.setTitle(translate('MediaPlugin.MediaTab', translate('MediaPlugin.MediaTab', 'Media Display'))
'Media Display'))
self.usePhononCheckBox.setText( self.usePhononCheckBox.setText(
translate('MediaPlugin.MediaTab', 'Use Phonon for video playback')) translate('MediaPlugin.MediaTab', 'Use Phonon for video playback'))

View File

@ -38,7 +38,8 @@ class MediaPlugin(Plugin):
log.info(u'%s MediaPlugin loaded', __name__) log.info(u'%s MediaPlugin loaded', __name__)
def __init__(self, plugin_helpers): def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Media', u'1.9.4', plugin_helpers) Plugin.__init__(self, u'Media', u'1.9.4', plugin_helpers,
MediaMediaItem, MediaTab)
self.weight = -6 self.weight = -6
self.icon_path = u':/plugins/plugin_media.png' self.icon_path = u':/plugins/plugin_media.png'
self.icon = build_icon(self.icon_path) self.icon = build_icon(self.icon_path)
@ -75,13 +76,6 @@ class MediaPlugin(Plugin):
mimetype = u'' mimetype = u''
return list, mimetype return list, mimetype
def getSettingsTab(self):
return MediaTab(self.name)
def getMediaManagerItem(self):
# Create the MediaManagerItem object.
return MediaMediaItem(self, self, self.icon)
def about(self): def about(self):
about_text = translate('MediaPlugin', '<strong>Media Plugin</strong>' about_text = translate('MediaPlugin', '<strong>Media Plugin</strong>'
'<br />The media plugin provides playback of audio and video.') '<br />The media plugin provides playback of audio and video.')
@ -101,45 +95,15 @@ class MediaPlugin(Plugin):
u'title': translate('MediaPlugin', 'Media', 'container title') u'title': translate('MediaPlugin', 'Media', 'container title')
} }
# Middle Header Bar # Middle Header Bar
## Load Action ## tooltips = {
self.textStrings[StringContent.Load] = { u'load': translate('MediaPlugin', 'Load a new Media'),
u'title': translate('MediaPlugin', 'Load'), u'import': u'',
u'tooltip': translate('MediaPlugin', u'new': translate('MediaPlugin', 'Add a new Media'),
'Load a new Media') u'edit': translate('MediaPlugin', 'Edit the selected Media'),
} u'delete': translate('MediaPlugin', 'Delete the selected Media'),
## New Action ## u'preview': translate('MediaPlugin', 'Preview the selected Media'),
self.textStrings[StringContent.New] = { u'live': translate('MediaPlugin', 'Send the selected Media live'),
u'title': translate('MediaPlugin', 'Add'), u'service': translate('MediaPlugin',
u'tooltip': translate('MediaPlugin',
'Add a new Media')
}
## Edit Action ##
self.textStrings[StringContent.Edit] = {
u'title': translate('MediaPlugin', 'Edit'),
u'tooltip': translate('MediaPlugin',
'Edit the selected Media')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('MediaPlugin', 'Delete'),
u'tooltip': translate('MediaPlugin',
'Delete the selected Media')
}
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('MediaPlugin', 'Preview'),
u'tooltip': translate('MediaPlugin',
'Preview the selected Media')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('MediaPlugin', 'Live'),
u'tooltip': translate('MediaPlugin',
'Send the selected Media live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('MediaPlugin', 'Service'),
u'tooltip': translate('MediaPlugin',
'Add the selected Media to the service') 'Add the selected Media to the service')
} }
self.setPluginUiTextStrings(tooltips)

View File

@ -69,7 +69,8 @@ class ImpressController(PresentationController):
Initialise the class Initialise the class
""" """
log.debug(u'Initialising') log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Impress') PresentationController.__init__(self, plugin, u'Impress',
ImpressDocument)
self.supports = [u'odp'] self.supports = [u'odp']
self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx'] self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx']
self.process = None self.process = None
@ -144,7 +145,12 @@ class ImpressController(PresentationController):
log.debug(u'get COM Desktop OpenOffice') log.debug(u'get COM Desktop OpenOffice')
if not self.manager: if not self.manager:
return None return None
return self.manager.createInstance(u'com.sun.star.frame.Desktop') desktop = None
try:
desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
except AttributeError:
log.exception(u'Failure to find desktop - Impress may have closed')
return desktop if desktop else None
def get_com_servicemanager(self): def get_com_servicemanager(self):
""" """
@ -165,17 +171,19 @@ class ImpressController(PresentationController):
log.debug(u'Kill OpenOffice') log.debug(u'Kill OpenOffice')
while self.docs: while self.docs:
self.docs[0].close_presentation() self.docs[0].close_presentation()
if os.name != u'nt': desktop = None
desktop = self.get_uno_desktop() try:
else: if os.name != u'nt':
desktop = self.get_com_desktop() desktop = self.get_uno_desktop()
#Sometimes we get a failure and desktop is None else:
desktop = self.get_com_desktop()
except:
log.exception(u'Failed to find an OpenOffice desktop to terminate')
if not desktop: if not desktop:
log.exception(u'Failed to terminate OpenOffice')
return return
docs = desktop.getComponents() docs = desktop.getComponents()
if docs.hasElements(): if docs.hasElements():
log.debug(u'OpenOffice not terminated') log.debug(u'OpenOffice not terminated as docs are still open')
else: else:
try: try:
desktop.terminate() desktop.terminate()
@ -183,14 +191,6 @@ class ImpressController(PresentationController):
except: except:
log.exception(u'Failed to terminate OpenOffice') log.exception(u'Failed to terminate OpenOffice')
def add_doc(self, name):
"""
Called when a new Impress document is opened
"""
log.debug(u'Add Doc OpenOffice')
doc = ImpressDocument(self, name)
self.docs.append(doc)
return doc
class ImpressDocument(PresentationDocument): class ImpressDocument(PresentationDocument):
""" """
@ -431,35 +431,36 @@ class ImpressDocument(PresentationDocument):
def get_slide_text(self, slide_no): def get_slide_text(self, slide_no):
""" """
Returns the text on the slide Returns the text on the slide.
``slide_no`` ``slide_no``
The slide the text is required for, starting at 1 The slide the text is required for, starting at 1
"""
return self.__get_text_from_page(slide_no)
def get_slide_notes(self, slide_no):
"""
Returns the text in the slide notes.
``slide_no``
The slide the notes are required for, starting at 1
"""
return self.__get_text_from_page(slide_no, True)
def __get_text_from_page(self, slide_no, notes=False):
"""
Return any text extracted from the presentation page.
``notes``
A boolean. If set the method searches the notes of the slide.
""" """
doc = self.document
pages = doc.getDrawPages()
text = '' text = ''
pages = self.document.getDrawPages()
page = pages.getByIndex(slide_no - 1) page = pages.getByIndex(slide_no - 1)
if notes:
page = page.getNotesPage()
for idx in range(page.getCount()): for idx in range(page.getCount()):
shape = page.getByIndex(idx) shape = page.getByIndex(idx)
if shape.supportsService("com.sun.star.drawing.Text"): if shape.supportsService("com.sun.star.drawing.Text"):
text += shape.getString() + '\n' text += shape.getString() + '\n'
return text return text
def get_slide_notes(self, slide_no):
"""
Returns the text on the slide
``slide_no``
The slide the notes are required for, starting at 1
"""
doc = self.document
pages = doc.getDrawPages()
text = ''
page = pages.getByIndex(slide_no - 1)
notes = page.getNotesPage()
for idx in range(notes.getCount()):
shape = notes.getByIndex(idx)
if shape.supportsService("com.sun.star.drawing.Text"):
text += shape.getString() + '\n'
return text

View File

@ -29,24 +29,13 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, build_icon, SettingsManager, \
SettingsManager, translate, check_item_selected, Receiver, ItemCapabilities translate, check_item_selected, Receiver, ItemCapabilities
from openlp.core.ui import criticalErrorMessageBox from openlp.core.lib.ui import critical_error_message_box, media_item_combo_box
from openlp.plugins.presentations.lib import MessageListener from openlp.plugins.presentations.lib import MessageListener
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class PresentationListView(BaseListWithDnD):
"""
Class for the list of Presentations
We have to explicitly create separate classes for each plugin
in order for DnD to the Service manager to work correctly.
"""
def __init__(self, parent=None):
self.PluginName = u'Presentations'
BaseListWithDnD.__init__(self, parent)
class PresentationMediaItem(MediaManagerItem): class PresentationMediaItem(MediaManagerItem):
""" """
This is the Presentation media manager item for Presentation Items. This is the Presentation media manager item for Presentation Items.
@ -61,9 +50,6 @@ class PresentationMediaItem(MediaManagerItem):
self.controllers = controllers self.controllers = controllers
self.IconPath = u'presentations/presentation' self.IconPath = u'presentations/presentation'
self.Automatic = u'' self.Automatic = u''
# this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = PresentationListView
MediaManagerItem.__init__(self, parent, self, icon) MediaManagerItem.__init__(self, parent, self, icon)
self.message_listener = MessageListener(self) self.message_listener = MessageListener(self)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -116,12 +102,8 @@ class PresentationMediaItem(MediaManagerItem):
self.displayLayout.setObjectName(u'displayLayout') self.displayLayout.setObjectName(u'displayLayout')
self.displayTypeLabel = QtGui.QLabel(self.presentationWidget) self.displayTypeLabel = QtGui.QLabel(self.presentationWidget)
self.displayTypeLabel.setObjectName(u'displayTypeLabel') self.displayTypeLabel.setObjectName(u'displayTypeLabel')
self.displayTypeComboBox = QtGui.QComboBox(self.presentationWidget) self.displayTypeComboBox = media_item_combo_box(
self.displayTypeComboBox.setSizeAdjustPolicy( self.presentationWidget, u'displayTypeComboBox')
QtGui.QComboBox.AdjustToMinimumContentsLength)
self.displayTypeComboBox.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
self.displayTypeComboBox.setObjectName(u'displayTypeComboBox')
self.displayTypeLabel.setBuddy(self.displayTypeComboBox) self.displayTypeLabel.setBuddy(self.displayTypeComboBox)
self.displayLayout.addRow(self.displayTypeLabel, self.displayLayout.addRow(self.displayTypeLabel,
self.displayTypeComboBox) self.displayTypeComboBox)
@ -181,7 +163,7 @@ class PresentationMediaItem(MediaManagerItem):
filename = os.path.split(unicode(file))[1] filename = os.path.split(unicode(file))[1]
if titles.count(filename) > 0: if titles.count(filename) > 0:
if not initialLoad: if not initialLoad:
criticalErrorMessageBox( critical_error_message_box(
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'File Exists'), 'File Exists'),
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
@ -190,7 +172,7 @@ class PresentationMediaItem(MediaManagerItem):
controller_name = self.findControllerByType(filename) controller_name = self.findControllerByType(filename)
if controller_name: if controller_name:
controller = self.controllers[controller_name] controller = self.controllers[controller_name]
doc = controller.add_doc(unicode(file)) doc = controller.add_document(unicode(file))
thumb = os.path.join(doc.get_thumbnail_folder(), u'icon.png') thumb = os.path.join(doc.get_thumbnail_folder(), u'icon.png')
preview = doc.get_thumbnail_path(1, True) preview = doc.get_thumbnail_path(1, True)
if not preview and not initialLoad: if not preview and not initialLoad:
@ -205,7 +187,7 @@ class PresentationMediaItem(MediaManagerItem):
if initialLoad: if initialLoad:
icon = build_icon(u':/general/general_delete.png') icon = build_icon(u':/general/general_delete.png')
else: else:
criticalErrorMessageBox( critical_error_message_box(
self, translate('PresentationPlugin.MediaItem', self, translate('PresentationPlugin.MediaItem',
'Unsupported File'), 'Unsupported File'),
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
@ -230,7 +212,7 @@ class PresentationMediaItem(MediaManagerItem):
filepath = unicode(item.data( filepath = unicode(item.data(
QtCore.Qt.UserRole).toString()) QtCore.Qt.UserRole).toString())
for cidx in self.controllers: for cidx in self.controllers:
doc = self.controllers[cidx].add_doc(filepath) doc = self.controllers[cidx].add_document(filepath)
doc.presentation_deleted() doc.presentation_deleted()
doc.close_presentation() doc.close_presentation()
for row in row_list: for row in row_list:
@ -250,6 +232,7 @@ class PresentationMediaItem(MediaManagerItem):
service_item.title = unicode(self.displayTypeComboBox.currentText()) service_item.title = unicode(self.displayTypeComboBox.currentText())
service_item.shortname = unicode(self.displayTypeComboBox.currentText()) service_item.shortname = unicode(self.displayTypeComboBox.currentText())
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay) service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
service_item.add_capability(ItemCapabilities.AllowsDetailedTitleDisplay)
shortname = service_item.shortname shortname = service_item.shortname
if shortname: if shortname:
for item in items: for item in items:
@ -263,7 +246,7 @@ class PresentationMediaItem(MediaManagerItem):
return False return False
controller = self.controllers[service_item.shortname] controller = self.controllers[service_item.shortname]
(path, name) = os.path.split(filename) (path, name) = os.path.split(filename)
doc = controller.add_doc(filename) doc = controller.add_document(filename)
if doc.get_thumbnail_path(1, True) is None: if doc.get_thumbnail_path(1, True) is None:
doc.load_presentation() doc.load_presentation()
i = 1 i = 1
@ -277,7 +260,7 @@ class PresentationMediaItem(MediaManagerItem):
return True return True
else: else:
# File is no longer present # File is no longer present
criticalErrorMessageBox( critical_error_message_box(
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'Missing Presentation'), 'Missing Presentation'),
unicode(translate('PresentationPlugin.MediaItem', unicode(translate('PresentationPlugin.MediaItem',
@ -286,7 +269,7 @@ class PresentationMediaItem(MediaManagerItem):
return False return False
else: else:
# File is no longer present # File is no longer present
criticalErrorMessageBox( critical_error_message_box(
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'Missing Presentation'), 'Missing Presentation'),
unicode(translate('PresentationPlugin.MediaItem', unicode(translate('PresentationPlugin.MediaItem',

View File

@ -59,7 +59,7 @@ class Controller(object):
self.controller = controller self.controller = controller
if self.doc is not None: if self.doc is not None:
self.shutdown() self.shutdown()
self.doc = self.controller.add_doc(file) self.doc = self.controller.add_document(file)
if not self.doc.load_presentation(): if not self.doc.load_presentation():
# Display error message to user # Display error message to user
# Inform slidecontroller that the action failed? # Inform slidecontroller that the action failed?
@ -116,7 +116,7 @@ class Controller(object):
def last(self): def last(self):
""" """
Based on the handler passed at startup triggers the first slide Based on the handler passed at startup triggers the last slide
""" """
log.debug(u'Live = %s, last' % self.is_live) log.debug(u'Live = %s, last' % self.is_live)
if not self.is_live: if not self.is_live:

View File

@ -53,7 +53,8 @@ class PowerpointController(PresentationController):
Initialise the class Initialise the class
""" """
log.debug(u'Initialising') log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Powerpoint') PresentationController.__init__(self, plugin, u'Powerpoint',
PowerpointDocument)
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx'] self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
self.process = None self.process = None
@ -97,14 +98,6 @@ class PowerpointController(PresentationController):
pass pass
self.process = None self.process = None
def add_doc(self, name):
"""
Called when a new powerpoint document is opened
"""
log.debug(u'Add Doc PowerPoint')
doc = PowerpointDocument(self, name)
self.docs.append(doc)
return doc
class PowerpointDocument(PresentationDocument): class PowerpointDocument(PresentationDocument):
""" """
@ -154,8 +147,10 @@ class PowerpointDocument(PresentationDocument):
""" """
if self.check_thumbnails(): if self.check_thumbnails():
return return
self.presentation.Export(os.path.join(self.get_thumbnail_folder(), ''), for num in range(0, self.presentation.Slides.Count):
'png', 320, 240) self.presentation.Slides(num + 1).Export(os.path.join(
self.get_thumbnail_folder(), 'slide%d.png' % (num + 1)),
'png', 320, 240)
def close_presentation(self): def close_presentation(self):
""" """
@ -291,13 +286,7 @@ class PowerpointDocument(PresentationDocument):
``slide_no`` ``slide_no``
The slide the text is required for, starting at 1. The slide the text is required for, starting at 1.
""" """
text = '' return _get_text_from_shapes(self.presentation.Slides(slide_no).Shapes)
shapes = self.presentation.Slides(slide_no).Shapes
for idx in range(shapes.Count):
shape = shapes(idx + 1)
if shape.HasTextFrame:
text += shape.TextFrame.TextRange.Text + '\n'
return text
def get_slide_notes(self, slide_no): def get_slide_notes(self, slide_no):
""" """
@ -306,10 +295,19 @@ class PowerpointDocument(PresentationDocument):
``slide_no`` ``slide_no``
The slide the notes are required for, starting at 1. The slide the notes are required for, starting at 1.
""" """
text = '' return _get_text_from_shapes(
shapes = self.presentation.Slides(slide_no).NotesPage.Shapes self.presentation.Slides(slide_no).NotesPage.Shapes)
for idx in range(shapes.Count):
shape = shapes(idx + 1) def _get_text_from_shapes(shapes):
if shape.HasTextFrame: """
text += shape.TextFrame.TextRange.Text + '\n' Returns any text extracted from the shapes on a presentation slide.
return text
``shapes``
A set of shapes to search for text.
"""
text = ''
for idx in range(shapes.Count):
shape = shapes(idx + 1)
if shape.HasTextFrame:
text += shape.TextFrame.TextRange.Text + '\n'
return text

View File

@ -49,7 +49,8 @@ class PptviewController(PresentationController):
""" """
log.debug(u'Initialising') log.debug(u'Initialising')
self.process = None self.process = None
PresentationController.__init__(self, plugin, u'Powerpoint Viewer') PresentationController.__init__(self, plugin, u'Powerpoint Viewer',
PptviewDocument)
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx'] self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
def check_available(self): def check_available(self):
@ -93,14 +94,6 @@ class PptviewController(PresentationController):
while self.docs: while self.docs:
self.docs[0].close_presentation() self.docs[0].close_presentation()
def add_doc(self, name):
"""
Called when a new powerpoint document is opened
"""
log.debug(u'Add Doc PPTView')
doc = PptviewDocument(self, name)
self.docs.append(doc)
return doc
class PptviewDocument(PresentationDocument): class PptviewDocument(PresentationDocument):
""" """
@ -161,8 +154,9 @@ class PptviewDocument(PresentationDocument):
being shut down being shut down
""" """
log.debug(u'ClosePresentation') log.debug(u'ClosePresentation')
self.controller.process.ClosePPT(self.pptid) if self.controller.process:
self.pptid = -1 self.controller.process.ClosePPT(self.pptid)
self.pptid = -1
self.controller.remove_doc(self) self.controller.remove_doc(self)
def is_loaded(self): def is_loaded(self):
@ -247,4 +241,4 @@ class PptviewDocument(PresentationDocument):
""" """
Triggers the previous slide on the running presentation Triggers the previous slide on the running presentation
""" """
self.controller.process.PrevStep(self.pptid) self.controller.process.PrevStep(self.pptid)

View File

@ -35,151 +35,6 @@ from openlp.core.utils import AppLocation
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class PresentationController(object):
"""
This class is used to control interactions with presentation applications
by creating a runtime environment. This is a base class for presentation
controllers to inherit from.
To create a new controller, take a copy of this file and name it so it ends
with ``controller.py``, i.e. ``foobarcontroller.py``. Make sure it inherits
:class:`~openlp.plugins.presentations.lib.presentationcontroller.PresentationController`,
and then fill in the blanks. If possible try to make sure it loads on all
platforms, usually by using :mod:``os.name`` checks, although
``__init__``, ``check_available`` and ``presentation_deleted`` should
always be implemented.
See :class:`~openlp.plugins.presentations.lib.impresscontroller.ImpressController`,
:class:`~openlp.plugins.presentations.lib.powerpointcontroller.PowerpointController` or
:class:`~openlp.plugins.presentations.lib.pptviewcontroller.PptviewController`
for examples.
**Basic Attributes**
``name``
The name that appears in the options and the media manager
``enabled``
The controller is enabled
``available``
The controller is available on this machine. Set by init via
call to check_available
``plugin``
The presentationplugin object
``supports``
The primary native file types this application supports
``alsosupports``
Other file types the application can import, although not necessarily
the first choice due to potential incompatibilities
**Hook Functions**
``kill()``
Called at system exit to clean up any running presentations
``check_available()``
Returns True if presentation application is installed/can run on this
machine
``presentation_deleted()``
Deletes presentation specific files, e.g. thumbnails
"""
log.info(u'PresentationController loaded')
def __init__(self, plugin=None, name=u'PresentationController'):
"""
This is the constructor for the presentationcontroller object. This
provides an easy way for descendent plugins to populate common data.
This method *must* be overridden, like so::
class MyPresentationController(PresentationController):
def __init__(self, plugin):
PresentationController.__init(
self, plugin, u'My Presenter App')
``plugin``
Defaults to *None*. The presentationplugin object
``name``
Name of the application, to appear in the application
"""
self.supports = []
self.alsosupports = []
self.docs = []
self.plugin = plugin
self.name = name
self.settings_section = self.plugin.settingsSection
self.available = self.check_available()
self.temp_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section), name)
self.thumbnail_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section),
u'thumbnails')
self.thumbnail_prefix = u'slide'
if not os.path.isdir(self.thumbnail_folder):
os.makedirs(self.thumbnail_folder)
if not os.path.isdir(self.temp_folder):
os.makedirs(self.temp_folder)
def enabled(self):
"""
Return whether the controller is currently enabled
"""
if self.available:
return QtCore.QSettings().value(
self.settings_section + u'/' + self.name,
QtCore.QVariant(QtCore.Qt.Checked)).toInt()[0] == \
QtCore.Qt.Checked
else:
return False
def check_available(self):
"""
Presentation app is able to run on this machine
"""
return False
def start_process(self):
"""
Loads a running version of the presentation application in the
background.
"""
pass
def kill(self):
"""
Called at system exit to clean up any running presentations and
close the application
"""
log.debug(u'Kill')
self.close_presentation()
def add_doc(self, name):
"""
Called when a new presentation document is opened
"""
doc = PresentationDocument(self, name)
self.docs.append(doc)
return doc
def remove_doc(self, doc=None):
"""
Called to remove an open document from the collection
"""
log.debug(u'remove_doc Presentation')
if doc is None:
return
if doc in self.docs:
self.docs.remove(doc)
def close_presentation(self):
pass
class PresentationDocument(object): class PresentationDocument(object):
""" """
Base class for presentation documents to inherit from. Base class for presentation documents to inherit from.
@ -440,4 +295,152 @@ class PresentationDocument(object):
``slide_no`` ``slide_no``
The slide the notes are required for, starting at 1 The slide the notes are required for, starting at 1
""" """
return '' return ''
class PresentationController(object):
"""
This class is used to control interactions with presentation applications
by creating a runtime environment. This is a base class for presentation
controllers to inherit from.
To create a new controller, take a copy of this file and name it so it ends
with ``controller.py``, i.e. ``foobarcontroller.py``. Make sure it inherits
:class:`~openlp.plugins.presentations.lib.presentationcontroller.PresentationController`,
and then fill in the blanks. If possible try to make sure it loads on all
platforms, usually by using :mod:``os.name`` checks, although
``__init__``, ``check_available`` and ``presentation_deleted`` should
always be implemented.
See :class:`~openlp.plugins.presentations.lib.impresscontroller.ImpressController`,
:class:`~openlp.plugins.presentations.lib.powerpointcontroller.PowerpointController` or
:class:`~openlp.plugins.presentations.lib.pptviewcontroller.PptviewController`
for examples.
**Basic Attributes**
``name``
The name that appears in the options and the media manager
``enabled``
The controller is enabled
``available``
The controller is available on this machine. Set by init via
call to check_available
``plugin``
The presentationplugin object
``supports``
The primary native file types this application supports
``alsosupports``
Other file types the application can import, although not necessarily
the first choice due to potential incompatibilities
**Hook Functions**
``kill()``
Called at system exit to clean up any running presentations
``check_available()``
Returns True if presentation application is installed/can run on this
machine
``presentation_deleted()``
Deletes presentation specific files, e.g. thumbnails
"""
log.info(u'PresentationController loaded')
def __init__(self, plugin=None, name=u'PresentationController',
document_class=PresentationDocument):
"""
This is the constructor for the presentationcontroller object. This
provides an easy way for descendent plugins to populate common data.
This method *must* be overridden, like so::
class MyPresentationController(PresentationController):
def __init__(self, plugin):
PresentationController.__init(
self, plugin, u'My Presenter App')
``plugin``
Defaults to *None*. The presentationplugin object
``name``
Name of the application, to appear in the application
"""
self.supports = []
self.alsosupports = []
self.docs = []
self.plugin = plugin
self.name = name
self.document_class = document_class
self.settings_section = self.plugin.settingsSection
self.available = self.check_available()
self.temp_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section), name)
self.thumbnail_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section),
u'thumbnails')
self.thumbnail_prefix = u'slide'
if not os.path.isdir(self.thumbnail_folder):
os.makedirs(self.thumbnail_folder)
if not os.path.isdir(self.temp_folder):
os.makedirs(self.temp_folder)
def enabled(self):
"""
Return whether the controller is currently enabled
"""
if self.available:
return QtCore.QSettings().value(
self.settings_section + u'/' + self.name,
QtCore.QVariant(QtCore.Qt.Checked)).toInt()[0] == \
QtCore.Qt.Checked
else:
return False
def check_available(self):
"""
Presentation app is able to run on this machine
"""
return False
def start_process(self):
"""
Loads a running version of the presentation application in the
background.
"""
pass
def kill(self):
"""
Called at system exit to clean up any running presentations and
close the application
"""
log.debug(u'Kill')
self.close_presentation()
def add_document(self, name):
"""
Called when a new presentation document is opened
"""
document = self.document_class(self, name)
self.docs.append(document)
return document
def remove_doc(self, doc=None):
"""
Called to remove an open document from the collection
"""
log.debug(u'remove_doc Presentation')
if doc is None:
return
if doc in self.docs:
self.docs.remove(doc)
def close_presentation(self):
pass

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsTab, translate from openlp.core.lib import Receiver, SettingsTab, translate
from openlp.core.lib.ui import UiStrings
class PresentationTab(SettingsTab): class PresentationTab(SettingsTab):
""" """
@ -85,9 +86,7 @@ class PresentationTab(SettingsTab):
checkbox.setText( checkbox.setText(
unicode(translate('PresentationPlugin.PresentationTab', unicode(translate('PresentationPlugin.PresentationTab',
'%s (unvailable)')) % controller.name) '%s (unvailable)')) % controller.name)
self.AdvancedGroupBox.setTitle( self.AdvancedGroupBox.setTitle(UiStrings.Advanced)
translate('PresentationPlugin.PresentationTab',
'Advanced'))
self.OverrideAppCheckBox.setText( self.OverrideAppCheckBox.setText(
translate('PresentationPlugin.PresentationTab', translate('PresentationPlugin.PresentationTab',
'Allow presentation application to be overriden')) 'Allow presentation application to be overriden'))

View File

@ -74,7 +74,11 @@ class PresentationPlugin(Plugin):
self.insertToolboxItem() self.insertToolboxItem()
for controller in self.controllers: for controller in self.controllers:
if self.controllers[controller].enabled(): if self.controllers[controller].enabled():
self.controllers[controller].start_process() try:
self.controllers[controller].start_process()
except:
log.exception(u'Failed to start controller process')
self.controllers[controller].available = False
self.mediaItem.buildFileMaskString() self.mediaItem.buildFileMaskString()
def finalise(self): def finalise(self):
@ -163,33 +167,18 @@ class PresentationPlugin(Plugin):
'container title') 'container title')
} }
# Middle Header Bar # Middle Header Bar
## Load Action ## tooltips = {
self.textStrings[StringContent.Load] = { u'load': translate('PresentationPlugin', 'Load a new Presentation'),
u'title': translate('PresentationPlugin', 'Load'), u'import': u'',
u'tooltip': translate('PresentationPlugin', u'new': u'',
'Load a new Presentation') u'edit': u'',
} u'delete': translate('PresentationPlugin',
## Delete Action ## 'Delete the selected Presentation'),
self.textStrings[StringContent.Delete] = { u'preview': translate('PresentationPlugin',
u'title': translate('PresentationPlugin', 'Delete'), 'Preview the selected Presentation'),
u'tooltip': translate('PresentationPlugin', u'live': translate('PresentationPlugin',
'Delete the selected Presentation') 'Send the selected Presentation live'),
} u'service': translate('PresentationPlugin',
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('PresentationPlugin', 'Preview'),
u'tooltip': translate('PresentationPlugin',
'Preview the selected Presentation')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('PresentationPlugin', 'Live'),
u'tooltip': translate('PresentationPlugin',
'Send the selected Presentation live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('PresentationPlugin', 'Service'),
u'tooltip': translate('PresentationPlugin',
'Add the selected Presentation to the service') 'Add the selected Presentation to the service')
} }
self.setPluginUiTextStrings(tooltips)

View File

@ -38,7 +38,8 @@ class RemotesPlugin(Plugin):
""" """
remotes constructor remotes constructor
""" """
Plugin.__init__(self, u'Remotes', u'1.9.4', plugin_helpers) Plugin.__init__(self, u'Remotes', u'1.9.4', plugin_helpers,
settingsTabClass=RemoteTab)
self.icon = build_icon(u':/plugins/plugin_remote.png') self.icon = build_icon(u':/plugins/plugin_remote.png')
self.weight = -1 self.weight = -1
self.server = None self.server = None
@ -61,13 +62,6 @@ class RemotesPlugin(Plugin):
if self.server: if self.server:
self.server.close() self.server.close()
def getSettingsTab(self):
"""
Create the settings Tab
"""
visible_name = self.getString(StringContent.VisibleName)
return RemoteTab(self.name, visible_name[u'title'])
def about(self): def about(self):
""" """
Information about this plugin Information about this plugin

View File

@ -57,4 +57,6 @@ from songbookform import SongBookForm
from editverseform import EditVerseForm from editverseform import EditVerseForm
from editsongform import EditSongForm from editsongform import EditSongForm
from songmaintenanceform import SongMaintenanceForm from songmaintenanceform import SongMaintenanceForm
from songimportform import SongImportForm from songimportform import SongImportForm
from songexportform import SongExportForm

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.lib.ui import create_accept_reject_button_box
class Ui_AuthorsDialog(object): class Ui_AuthorsDialog(object):
def setupUi(self, authorsDialog): def setupUi(self, authorsDialog):
@ -55,17 +56,10 @@ class Ui_AuthorsDialog(object):
self.displayLabel.setBuddy(self.displayEdit) self.displayLabel.setBuddy(self.displayEdit)
self.authorLayout.addRow(self.displayLabel, self.displayEdit) self.authorLayout.addRow(self.displayLabel, self.displayEdit)
self.dialogLayout.addLayout(self.authorLayout) self.dialogLayout.addLayout(self.authorLayout)
self.buttonBox = QtGui.QDialogButtonBox(authorsDialog) self.dialogLayout.addWidget(
self.buttonBox.setStandardButtons( create_accept_reject_button_box(authorsDialog))
QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel)
self.buttonBox.setObjectName(u'buttonBox')
self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(authorsDialog) self.retranslateUi(authorsDialog)
authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height()) authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height())
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'accepted()'), authorsDialog.accept)
QtCore.QObject.connect(self.buttonBox,
QtCore.SIGNAL(u'rejected()'), authorsDialog.reject)
QtCore.QMetaObject.connectSlotsByName(authorsDialog) QtCore.QMetaObject.connectSlotsByName(authorsDialog)
def retranslateUi(self, authorsDialog): def retranslateUi(self, authorsDialog):

Some files were not shown because too many files have changed in this diff Show More