This commit is contained in:
Andreas Preikschat 2011-02-17 20:19:24 +01:00
commit 1db68d99b5
116 changed files with 3089 additions and 1670 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

@ -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':
html_theme_options = {
'sidebarbgcolor': '#3a60a9', 'sidebarbgcolor': '#3a60a9',
'relbarbgcolor': '#203b6f', 'relbarbgcolor': '#203b6f',
'footerbgcolor': '#26437c', 'footerbgcolor': '#26437c',
'headtextcolor': '#203b6f', 'headtextcolor': '#203b6f',
'linkcolor': '#26437c', 'linkcolor': '#26437c',
'sidebarlinkcolor': '#ceceff' '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

@ -239,7 +239,8 @@ def resize_image(image, width, height, background=QtCore.Qt.black):
Resize an image to fit on the current screen. Resize an image to fit on the current screen.
``image`` ``image``
The image to resize. The image to resize. It has to be either a ``QImage`` instance or the
path to the image.
``width`` ``width``
The new image width. The new image width.
@ -319,6 +320,7 @@ def check_directory_exists(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 +341,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

@ -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__)
@ -536,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:
@ -634,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')
@ -85,8 +85,7 @@ class ImageManager(QtCore.QObject):
for key in self._cache.keys(): for key in self._cache.keys():
image = self._cache[key] image = self._cache[key]
image.dirty = True image.dirty = True
image.image = resize_image(image.path, image.image = resize_image(image.path, self.width, self.height)
self.width, self.height)
self._cache_dirty = True self._cache_dirty = True
# only one thread please # only one thread please
if not self._thread_running: if not self._thread_running:
@ -128,8 +127,7 @@ class ImageManager(QtCore.QObject):
image = Image() image = Image()
image.name = name image.name = name
image.path = path image.path = path
image.image = resize_image(path, image.image = resize_image(path, self.width, self.height)
self.width, self.height)
self._cache[name] = image self._cache[name] = image
else: else:
log.debug(u'Image in cache %s:%s' % (name, path)) log.debug(u'Image in cache %s:%s' % (name, path))

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
@ -202,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'],
preview_string[u'tooltip'],
u':/general/general_preview.png', self.onPreviewClick)
## Live Button ## ## Live Button ##
live_string = self.plugin.getString(StringContent.Live) toolbar_actions.append([StringContent.Live,
self.addToolbarButton( u':/general/general_live.png', self.onLiveClick])
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,
u':/general/general_add.png', self.onAddClick])
for action in toolbar_actions:
self.addToolbarButton( self.addToolbarButton(
service_string[u'title'], self.plugin.getString(action[0])[u'title'],
service_string[u'tooltip'], self.plugin.getString(action[0])[u'tooltip'],
u':/general/general_add.png', self.onAddClick) 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(
@ -275,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(
@ -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:

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__)
@ -44,6 +45,9 @@ class PluginStatus(object):
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'
@ -110,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*
@ -128,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
@ -137,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
@ -195,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):
""" """
@ -226,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):
""" """
@ -316,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):

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__)
@ -60,6 +62,7 @@ class ItemCapabilities(object):
AddIfNewItem = 9 AddIfNewItem = 9
ProvidesOwnDisplay = 10 ProvidesOwnDisplay = 10
AllowsDetailedTitleDisplay = 11 AllowsDetailedTitleDisplay = 11
AllowsVarableStartTime = 12
class ServiceItem(object): class ServiceItem(object):
@ -105,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):
@ -257,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:
@ -301,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)
@ -420,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

@ -164,13 +164,27 @@ 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. 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):
""" """
@ -180,6 +194,19 @@ class VerticalType(object):
Middle = 1 Middle = 1
Bottom = 2 Bottom = 2
@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', BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow',
u'slide_transition'] u'slide_transition']
@ -583,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

@ -34,6 +34,39 @@ from openlp.core.lib import build_icon, Receiver, translate
log = logging.getLogger(__name__) 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): def add_welcome_page(parent, image):
""" """
Generate an opening welcome page for a wizard using a provided image. Generate an opening welcome page for a wizard using a provided image.
@ -61,18 +94,25 @@ def add_welcome_page(parent, image):
parent.welcomeLayout.addStretch() parent.welcomeLayout.addStretch()
parent.addPage(parent.welcomePage) parent.addPage(parent.welcomePage)
def create_save_cancel_button_box(parent): def create_accept_reject_button_box(parent, okay=False):
""" """
Creates a standard dialog button box with save and cancel buttons. The Creates a standard dialog button box with two buttons. The buttons default
button box is connected to the parent's ``accept()`` and ``reject()`` 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. methods to handle the default ``accepted()`` and ``rejected()`` signals.
``parent`` ``parent``
The parent object. This should be a ``QWidget`` descendant. 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) button_box = QtGui.QDialogButtonBox(parent)
button_box.setStandardButtons( accept_button = QtGui.QDialogButtonBox.Save
QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel) if okay:
accept_button = QtGui.QDialogButtonBox.Ok
button_box.setStandardButtons(accept_button | QtGui.QDialogButtonBox.Cancel)
button_box.setObjectName(u'%sButtonBox' % parent) button_box.setObjectName(u'%sButtonBox' % parent)
QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'accepted()'), QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'accepted()'),
parent.accept) parent.accept)
@ -98,13 +138,12 @@ def critical_error_message_box(title=None, message=None, parent=None,
``question`` ``question``
Should this message box question the user. Should this message box question the user.
""" """
error = translate('OpenLP.Ui', 'Error')
if question: if question:
return QtGui.QMessageBox.critical(parent, error, message, return QtGui.QMessageBox.critical(parent, UiStrings.Error, message,
QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
data = {u'message': message} data = {u'message': message}
data[u'title'] = title if title else error data[u'title'] = title if title else UiStrings.Error
return Receiver.send_message(u'openlp_error_message', data) return Receiver.send_message(u'openlp_error_message', data)
def media_item_combo_box(parent, name): def media_item_combo_box(parent, name):
@ -134,7 +173,7 @@ def create_delete_push_button(parent, icon=None):
delete_button.setObjectName(u'deleteButton') delete_button.setObjectName(u'deleteButton')
delete_icon = icon if icon else u':/general/general_delete.png' delete_icon = icon if icon else u':/general/general_delete.png'
delete_button.setIcon(build_icon(delete_icon)) delete_button.setIcon(build_icon(delete_icon))
delete_button.setText(translate('OpenLP.Ui', '&Delete')) delete_button.setText(UiStrings.Delete)
delete_button.setToolTip( delete_button.setToolTip(
translate('OpenLP.Ui', 'Delete the selected item.')) translate('OpenLP.Ui', 'Delete the selected item.'))
QtCore.QObject.connect(delete_button, QtCore.QObject.connect(delete_button,
@ -219,3 +258,28 @@ def add_widget_completer(cache, widget):
completer = QtGui.QCompleter(cache) completer = QtGui.QCompleter(cache)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive) completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
widget.setCompleter(completer) 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"?>
@ -69,37 +72,44 @@ class Theme(object):
``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):
""" """
@ -53,6 +53,7 @@ class HideMode(object):
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

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):
""" """
@ -80,16 +81,6 @@ class AdvancedTab(SettingsTab):
self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox') self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
self.hideMouseLayout.addWidget(self.hideMouseCheckBox) self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
self.leftLayout.addWidget(self.hideMouseGroupBox) self.leftLayout.addWidget(self.hideMouseGroupBox)
self.serviceOrderGroupBox = QtGui.QGroupBox(self.leftColumn)
self.serviceOrderGroupBox.setObjectName(u'serviceOrderGroupBox')
self.serviceOrderLayout = QtGui.QVBoxLayout(self.serviceOrderGroupBox)
self.serviceOrderLayout.setObjectName(u'serviceOrderLayout')
self.detailedServicePrintCheckBox = QtGui.QCheckBox(
self.serviceOrderGroupBox)
self.detailedServicePrintCheckBox.setObjectName(
u'detailedServicePrintCheckBox')
self.serviceOrderLayout.addWidget(self.detailedServicePrintCheckBox)
self.leftLayout.addWidget(self.serviceOrderGroupBox)
# self.sharedDirGroupBox = QtGui.QGroupBox(self.leftColumn) # self.sharedDirGroupBox = QtGui.QGroupBox(self.leftColumn)
# self.sharedDirGroupBox.setObjectName(u'sharedDirGroupBox') # self.sharedDirGroupBox.setObjectName(u'sharedDirGroupBox')
# self.sharedDirLayout = QtGui.QFormLayout(self.sharedDirGroupBox) # self.sharedDirLayout = QtGui.QFormLayout(self.sharedDirGroupBox)
@ -122,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',
@ -139,11 +130,6 @@ class AdvancedTab(SettingsTab):
'Mouse Cursor')) 'Mouse Cursor'))
self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab', self.hideMouseCheckBox.setText(translate('OpenLP.AdvancedTab',
'Hide the mouse cursor when moved over the display window')) 'Hide the mouse cursor when moved over the display window'))
self.serviceOrderGroupBox.setTitle(translate('OpenLP.AdvancedTab',
'Service Order Print'))
self.detailedServicePrintCheckBox.setText(
translate('OpenLP.AdvancedTab',
'Print slide texts and service item notes as well'))
# self.sharedDirGroupBox.setTitle( # self.sharedDirGroupBox.setTitle(
# translate('AdvancedTab', 'Central Data Store')) # translate('AdvancedTab', 'Central Data Store'))
# self.sharedCheckBox.setText( # self.sharedCheckBox.setText(
@ -179,8 +165,6 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(True)).toBool()) QtCore.QVariant(True)).toBool())
self.hideMouseCheckBox.setChecked( self.hideMouseCheckBox.setChecked(
settings.value(u'hide mouse', QtCore.QVariant(False)).toBool()) settings.value(u'hide mouse', QtCore.QVariant(False)).toBool())
self.detailedServicePrintCheckBox.setChecked(settings.value(
u'detailed service print', QtCore.QVariant(False)).toBool())
settings.endGroup() settings.endGroup()
def save(self): def save(self):
@ -201,8 +185,6 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(self.enableAutoCloseCheckBox.isChecked())) QtCore.QVariant(self.enableAutoCloseCheckBox.isChecked()))
settings.setValue(u'hide mouse', settings.setValue(u'hide mouse',
QtCore.QVariant(self.hideMouseCheckBox.isChecked())) QtCore.QVariant(self.hideMouseCheckBox.isChecked()))
settings.setValue(u'detailed service print',
QtCore.QVariant(self.detailedServicePrintCheckBox.isChecked()))
settings.endGroup() settings.endGroup()
# def onSharedCheckBoxChanged(self, checked): # def onSharedCheckBoxChanged(self, checked):

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.lib.ui import critical_error_message_box 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'))

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
@ -176,8 +177,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
self,translate('ImagePlugin.ExceptionDialog', self,translate('ImagePlugin.ExceptionDialog',
'Select Attachment'), 'Select Attachment'),
SettingsManager.get_last_dir(u'exceptions'), SettingsManager.get_last_dir(u'exceptions'),
u'%s (*.*) (*)' % u'%s (*.*) (*)' % UiStrings.AllFiles)
unicode(translate('ImagePlugin.MediaItem', 'All Files')))
log.info(u'New files(s) %s', unicode(files)) log.info(u'New files(s) %s', unicode(files))
if files: if files:
self.fileAttachment = unicode(files) self.fileAttachment = unicode(files)

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):
""" """

View File

@ -72,7 +72,7 @@ class MainDisplay(DisplayWidget):
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(),
@ -106,6 +106,9 @@ 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())
@ -145,7 +148,7 @@ class MainDisplay(DisplayWidget):
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, None)) 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']:
@ -326,8 +329,7 @@ class MainDisplay(DisplayWidget):
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
@ -342,6 +344,13 @@ class MainDisplay(DisplayWidget):
Receiver.send_message(u'maindisplay_active') Receiver.send_message(u'maindisplay_active')
return self.preview() return self.preview()
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): def isWebLoaded(self):
""" """
Called by webView event to show display is fully loaded Called by webView event to show display is fully loaded
@ -398,8 +407,7 @@ class MainDisplay(DisplayWidget):
if u'video' in self.override: if u'video' in self.override:
Receiver.send_message(u'video_background_replaced') Receiver.send_message(u'video_background_replaced')
self.override = {} self.override = {}
elif self.override[u'theme'] != \ elif self.override[u'theme'] != serviceItem.themedata.theme_name:
serviceItem.themedata.theme_name:
Receiver.send_message(u'live_theme_changed') Receiver.send_message(u'live_theme_changed')
self.override = {} self.override = {}
else: else:
@ -408,7 +416,7 @@ class MainDisplay(DisplayWidget):
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, background) self.isLive, background)
log.debug(u'buildHtml - pre setHtml') log.debug(u'buildHtml - pre setHtml')
self.webView.setHtml(html) self.webView.setHtml(html)

View File

@ -30,7 +30,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \ from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
SettingsManager, PluginManager, Receiver, translate SettingsManager, PluginManager, Receiver, translate
from openlp.core.lib.ui import base_action, checkable_action, icon_action 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
@ -77,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)
@ -102,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)
@ -125,38 +126,38 @@ 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(mainWindow, self.mediaManagerDock = OpenLPDockWidget(mainWindow,
u'MediaManagerDock', u':/system/system_mediamanager.png') u'mediaManagerDock', 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(mainWindow, self.serviceManagerDock = OpenLPDockWidget(mainWindow,
u'ServiceManagerDock', u':/system/system_servicemanager.png') u'serviceManagerDock', 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(mainWindow, self.themeManagerDock = OpenLPDockWidget(mainWindow,
u'ThemeManagerDock', u':/system/system_thememanager.png') u'themeManagerDock', 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 = icon_action(mainWindow, u'FileNewItem', self.FileNewItem = icon_action(mainWindow, u'FileNewItem',
u':/general/general_new.png') u':/general/general_new.png')
@ -186,14 +187,14 @@ class Ui_MainWindow(object):
mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export') mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export')
self.ViewMediaManagerItem = icon_action(mainWindow, self.ViewMediaManagerItem = icon_action(mainWindow,
u'ViewMediaManagerItem', u':/system/system_mediamanager.png', u'ViewMediaManagerItem', u':/system/system_mediamanager.png',
self.MediaManagerDock.isVisible()) self.mediaManagerDock.isVisible())
self.ViewThemeManagerItem = icon_action(mainWindow, self.ViewThemeManagerItem = icon_action(mainWindow,
u'ViewThemeManagerItem', u':/system/system_thememanager.png', u'ViewThemeManagerItem', u':/system/system_thememanager.png',
self.ThemeManagerDock.isVisible()) self.themeManagerDock.isVisible())
mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View') mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View')
self.ViewServiceManagerItem = icon_action(mainWindow, self.ViewServiceManagerItem = icon_action(mainWindow,
u'ViewServiceManagerItem', u':/system/system_servicemanager.png', u'ViewServiceManagerItem', u':/system/system_servicemanager.png',
self.ServiceManagerDock.isVisible()) self.serviceManagerDock.isVisible())
mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View') mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View')
self.ViewPreviewPanel = checkable_action(mainWindow, self.ViewPreviewPanel = checkable_action(mainWindow,
u'ViewPreviewPanel', previewVisible) u'ViewPreviewPanel', previewVisible)
@ -215,9 +216,12 @@ class Ui_MainWindow(object):
self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem', self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
u':/tools/tools_add.png') u':/tools/tools_add.png')
mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools') mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools')
self.SettingsPluginListItem = icon_action(mainWindow, self.ToolsOpenDataFolder = icon_action(mainWindow,
u'SettingsPluginListItem', u':/system/settings_plugin_list.png') u'ToolsOpenDataFolder', u':/general/general_open.png')
mainWindow.actionList.add_action(self.SettingsPluginListItem, mainWindow.actionList.add_action(self.ToolsOpenDataFolder, u'Tools')
self.settingsPluginListItem = icon_action(mainWindow,
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 = checkable_action(mainWindow, self.AutoLanguageItem = checkable_action(mainWindow,
@ -264,22 +268,23 @@ class Ui_MainWindow(object):
self.FileExportMenu.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)
@ -295,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'))
@ -403,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'))
@ -432,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',
@ -501,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)
@ -702,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
@ -748,9 +762,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.setValue(u'%s/view mode' % self.generalSettingsSection, settings.setValue(u'%s/view mode' % self.generalSettingsSection,
mode) mode)
self.MediaManagerDock.setVisible(media) self.mediaManagerDock.setVisible(media)
self.ServiceManagerDock.setVisible(service) self.serviceManagerDock.setVisible(service)
self.ThemeManagerDock.setVisible(theme) self.themeManagerDock.setVisible(theme)
self.setPreviewPanelVisibility(preview) self.setPreviewPanelVisibility(preview)
self.setLivePanelVisibility(live) self.setLivePanelVisibility(live)
@ -867,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):
""" """

View File

@ -34,7 +34,9 @@ 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

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

@ -27,7 +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_save_cancel_button_box, \ from openlp.core.lib.ui import create_accept_reject_button_box, \
create_delete_push_button, create_up_down_push_button_set create_delete_push_button, create_up_down_push_button_set
class Ui_ServiceItemEditDialog(object): class Ui_ServiceItemEditDialog(object):
@ -50,7 +50,7 @@ class Ui_ServiceItemEditDialog(object):
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.dialogLayout.addWidget( self.dialogLayout.addWidget(
create_save_cancel_button_box(serviceItemEditDialog), 1, 0, 1, 2) create_accept_reject_button_box(serviceItemEditDialog), 1, 0, 1, 2)
self.retranslateUi(serviceItemEditDialog) self.retranslateUi(serviceItemEditDialog)
QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog) QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog)

View File

@ -110,11 +110,12 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
temp = self.itemList[row] temp = self.itemList[row]
self.itemList.remove(self.itemList[row]) self.itemList.remove(self.itemList[row])
if direction == u'up': if direction == u'up':
self.itemList.insert(row - 1, temp) row -= 1
else: else:
self.itemList.insert(row + 1, temp) 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.lib.ui import critical_error_message_box from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.ui import ServiceNoteForm, 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
@ -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,18 +96,14 @@ 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.saveFile) self.saveFile)
self.toolbar.addSeparator() self.toolbar.addSeparator()
@ -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)
@ -461,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)')))
@ -563,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)
@ -571,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)
@ -583,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:
@ -597,6 +603,16 @@ class ServiceManager(QtGui.QWidget):
self.serviceNoteForm.textEdit.toPlainText() self.serviceNoteForm.textEdit.toPlainText()
self.repaintServiceList(item, -1) 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]
self.serviceItemEditForm.setServiceItem( self.serviceItemEditForm.setServiceItem(
@ -843,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)
@ -1187,41 +1208,5 @@ class ServiceManager(QtGui.QWidget):
""" """
Print a Service Order Sheet. Print a Service Order Sheet.
""" """
if not self.serviceItems: settingDialog = PrintServiceOrderForm(self.mainwindow, self)
critical_error_message_box( settingDialog.exec_()
message=translate('OpenLP.ServiceManager',
'There is no service item in this service.'))
return
printDialog = QtGui.QPrintDialog()
if not printDialog.exec_():
return
text = u'<h2>%s</h2>' % translate('OpenLP.ServiceManager',
'Service Order Sheet')
for item in self.serviceItems:
item = item[u'service_item']
# add the title
text += u'<h4><img src="%s" /> %s</h4>' % (item.icon,
item.get_display_title())
if not QtCore.QSettings().value(u'advanced' +
u'/detailed service print', QtCore.QVariant(True)).toBool():
continue
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
if item.notes:
# add notes
text += u'<p><b>%s</b> %s</p>' % (translate(
'OpenLP.ServiceManager', 'Notes:'), item.notes)
serviceDocument = QtGui.QTextDocument()
serviceDocument.setHtml(text)
serviceDocument.print_(printDialog.printer())

View File

@ -27,7 +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_save_cancel_button_box from openlp.core.lib.ui import create_accept_reject_button_box
class ServiceNoteForm(QtGui.QDialog): class ServiceNoteForm(QtGui.QDialog):
""" """
@ -48,7 +48,7 @@ class ServiceNoteForm(QtGui.QDialog):
self.textEdit = QtGui.QTextEdit(self) self.textEdit = QtGui.QTextEdit(self)
self.textEdit.setObjectName(u'textEdit') self.textEdit.setObjectName(u'textEdit')
self.dialogLayout.addWidget(self.textEdit) self.dialogLayout.addWidget(self.textEdit)
self.dialogLayout.addWidget(create_save_cancel_button_box(self)) self.dialogLayout.addWidget(create_accept_reject_button_box(self))
QtCore.QMetaObject.connectSlotsByName(self) QtCore.QMetaObject.connectSlotsByName(self)
def retranslateUi(self): def retranslateUi(self):

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()))
if (len(action.shortcuts()) == 2):
shortcutText = action.shortcuts()[0].toString()
alternateText = action.shortcuts()[1].toString()
else:
shortcutText = action.shortcut().toString() shortcutText = action.shortcut().toString()
actionItem = QtGui.QTreeWidgetItem([actionText, shortcutText]) 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

@ -32,7 +32,7 @@ from PyQt4.phonon import Phonon
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 shortcut_action from openlp.core.lib.ui import UiStrings, shortcut_action
from openlp.core.ui import HideMode, MainDisplay from openlp.core.ui import HideMode, MainDisplay
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -78,7 +78,7 @@ 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)
@ -87,12 +87,11 @@ class SlideController(QtGui.QWidget):
# 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;')
@ -179,10 +178,12 @@ 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)
@ -197,11 +198,13 @@ class SlideController(QtGui.QWidget):
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'),
@ -377,7 +380,7 @@ 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')
@ -455,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)
@ -584,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)
@ -874,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)

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

@ -0,0 +1,52 @@
# -*- 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 QtGui
from starttimedialog import Ui_StartTimeDialog
class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
"""
The exception dialog
"""
def __init__(self, parent):
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
def exec_(self):
"""
Run the Dialog with correct heading.
"""
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)

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.lib.ui import critical_error_message_box 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
@ -483,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)

View File

@ -34,8 +34,9 @@ from PyQt4 import QtCore, QtGui
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, \
from openlp.core.lib.ui import critical_error_message_box VerticalType
from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.theme import Theme from openlp.core.theme import Theme
from openlp.core.ui import FileRenameForm, ThemeForm 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, \
@ -313,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':
@ -405,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:
@ -529,6 +529,18 @@ class ThemeManager(QtGui.QWidget):
else: else:
outfile = open(fullpath, u'wb') outfile = open(fullpath, u'wb')
outfile.write(zip.read(file)) outfile.write(zip.read(file))
except (IOError, NameError):
critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
log.exception(u'Importing theme from zip failed %s' % filename)
finally:
# Close the files, to be able to continue creating the theme.
if zip:
zip.close()
if outfile:
outfile.close()
# As all files are closed, we can create the Theme.
if filexml: if filexml:
theme = self._createThemeFromXml(filexml, self.path) theme = self._createThemeFromXml(filexml, self.path)
self.generateAndSaveImage(dir, themename, theme) self.generateAndSaveImage(dir, themename, theme)
@ -539,17 +551,6 @@ class ThemeManager(QtGui.QWidget):
'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):
critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager',
'File is not a valid theme.'))
log.exception(u'Importing theme from zip failed %s' % filename)
finally:
if zip:
zip.close()
if outfile:
outfile.close()
def checkIfThemeExists(self, themeName): def checkIfThemeExists(self, themeName):
""" """
@ -762,11 +763,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(

View File

@ -27,7 +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 add_welcome_page 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):
@ -242,12 +242,8 @@ 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)
@ -450,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'))
@ -465,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(
@ -491,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(

View File

@ -27,11 +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 add_welcome_page from openlp.core.lib.ui import UiStrings, add_welcome_page
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -70,6 +71,12 @@ class OpenLPWizard(QtGui.QWizard):
self.retranslateUi() self.retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self) QtCore.QMetaObject.connectSlotsByName(self)
def registerFields(self):
"""
Hook method for wizards to register any fields they need.
"""
pass
def addProgressPage(self): def addProgressPage(self):
""" """
Add the progress page for the wizard. This page informs the user how Add the progress page for the wizard. This page informs the user how
@ -146,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
@ -164,24 +164,34 @@ def _get_os_dir_path(dir_type):
""" """
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'), u'openlp') 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(os.getenv(u'HOME'), u'Library', return os.path.join(unicode(os.getenv(u'HOME'), encoding),
u'Application Support', u'openlp', u'Data') u'Library', u'Application Support', u'openlp', u'Data')
return os.path.join(os.getenv(u'HOME'), u'Library', return os.path.join(unicode(os.getenv(u'HOME'), encoding),
u'Application Support', u'openlp') 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 os.path.join(os.getenv(u'HOME'), u'.openlp') 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):
""" """
@ -189,7 +199,6 @@ 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):
@ -373,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,14 @@ 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)
self.visible_name = self.getString(StringContent.VisibleName)
self.alertForm = AlertForm(self) self.alertForm = AlertForm(self)
def getSettingsTab(self):
"""
Return the settings tab for the Alerts plugin
"""
self.alertsTab = AlertsTab(self, self.visible_name[u'title'])
return self.alertsTab
def addToolsMenuItem(self, tools_menu): def addToolsMenuItem(self, tools_menu):
""" """
Give the alerts plugin the opportunity to add items to the Give the alerts plugin the opportunity to add items to the
@ -81,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

@ -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:

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')
@ -135,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,7 +33,7 @@ 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.lib.ui import critical_error_message_box from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard from openlp.core.ui.wizard import OpenLPWizard
@ -727,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.

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)
``reference`` For example::
The bible reference to parse.
[(u'John', 3, 16, 18), (u'John', 4, 1, 1)]
**Reference string details:**
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)
@ -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

@ -28,22 +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.lib.ui import add_widget_completer, media_item_combo_box, \ from openlp.core.lib.searchedit import SearchEdit
critical_error_message_box 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):
@ -54,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 = {}
@ -93,18 +92,17 @@ class BibleMediaItem(MediaManagerItem):
u'quickSecondComboBox') 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 = media_item_combo_box(self.quickTab,
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')
@ -192,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
@ -207,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
@ -242,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(
@ -268,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(
@ -369,11 +360,11 @@ 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:
@ -502,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)
@ -510,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(

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,7 +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_save_cancel_button_box, \ from openlp.core.lib.ui import UiStrings, create_accept_reject_button_box, \
create_delete_push_button, create_up_down_push_button_set create_delete_push_button, create_up_down_push_button_set
class Ui_CustomEditDialog(object): class Ui_CustomEditDialog(object):
@ -94,7 +94,7 @@ 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 = create_save_cancel_button_box(customEditDialog) self.buttonBox = create_accept_reject_button_box(customEditDialog)
self.previewButton = QtGui.QPushButton() self.previewButton = QtGui.QPushButton()
self.buttonBox.addButton( self.buttonBox.addButton(
self.previewButton, QtGui.QDialogButtonBox.ActionRole) self.previewButton, QtGui.QDialogButtonBox.ActionRole)
@ -107,13 +107,11 @@ class Ui_CustomEditDialog(object):
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides')) translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
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.'))

View File

@ -27,7 +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_save_cancel_button_box 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):
@ -37,7 +37,7 @@ 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 = create_save_cancel_button_box(customSlideEditDialog) self.buttonBox = create_accept_reject_button_box(customSlideEditDialog)
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,

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

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,21 +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 Receiver
from openlp.core.lib.ui import critical_error_message_box 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.
@ -52,9 +45,6 @@ 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.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged) QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged)
@ -64,15 +54,11 @@ class ImageMediaItem(MediaManagerItem):
'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)
@ -84,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),

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, Receiver SettingsManager, translate, check_item_selected, Receiver
from openlp.core.lib.ui import critical_error_message_box 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,30 +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.mediaObject = Phonon.MediaObject(self)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'video_background_replaced'), QtCore.SIGNAL(u'video_background_replaced'),
self.videobackgroundReplaced) 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)
@ -133,13 +125,22 @@ 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:
@ -151,8 +152,7 @@ class MediaMediaItem(MediaManagerItem):
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))
@ -178,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,13 +171,15 @@ 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()
desktop = None
try:
if os.name != u'nt': if os.name != u'nt':
desktop = self.get_uno_desktop() desktop = self.get_uno_desktop()
else: else:
desktop = self.get_com_desktop() desktop = self.get_com_desktop()
#Sometimes we get a failure and desktop is None except:
if not desktop:
log.exception(u'Failed to find an OpenOffice desktop to terminate') log.exception(u'Failed to find an OpenOffice desktop to terminate')
if not desktop:
return return
docs = desktop.getComponents() docs = desktop.getComponents()
if docs.hasElements(): if docs.hasElements():
@ -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
""" """
doc = self.document return self.__get_text_from_page(slide_no)
pages = doc.getDrawPages()
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.
"""
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.lib.ui import critical_error_message_box, media_item_combo_box 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(),
@ -186,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:
@ -226,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:
@ -260,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

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?

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,7 +147,9 @@ 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):
self.presentation.Slides(num + 1).Export(os.path.join(
self.get_thumbnail_folder(), 'slide%d.png' % (num + 1)),
'png', 320, 240) '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,8 +295,17 @@ 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.
""" """
return _get_text_from_shapes(
self.presentation.Slides(slide_no).NotesPage.Shapes)
def _get_text_from_shapes(shapes):
"""
Returns any text extracted from the shapes on a presentation slide.
``shapes``
A set of shapes to search for text.
"""
text = '' text = ''
shapes = self.presentation.Slides(slide_no).NotesPage.Shapes
for idx in range(shapes.Count): for idx in range(shapes.Count):
shape = shapes(idx + 1) shape = shapes(idx + 1)
if shape.HasTextFrame: if shape.HasTextFrame:

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,6 +154,7 @@ class PptviewDocument(PresentationDocument):
being shut down being shut down
""" """
log.debug(u'ClosePresentation') log.debug(u'ClosePresentation')
if self.controller.process:
self.controller.process.ClosePPT(self.pptid) self.controller.process.ClosePPT(self.pptid)
self.pptid = -1 self.pptid = -1
self.controller.remove_doc(self) self.controller.remove_doc(self)

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.
@ -441,3 +296,151 @@ class PresentationDocument(object):
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

@ -167,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

@ -58,3 +58,5 @@ 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,7 +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_save_cancel_button_box 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):
@ -57,7 +57,7 @@ class Ui_AuthorsDialog(object):
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.dialogLayout.addWidget( self.dialogLayout.addWidget(
create_save_cancel_button_box(authorsDialog)) create_accept_reject_button_box(authorsDialog))
self.retranslateUi(authorsDialog) self.retranslateUi(authorsDialog)
authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height()) authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height())
QtCore.QMetaObject.connectSlotsByName(authorsDialog) QtCore.QMetaObject.connectSlotsByName(authorsDialog)

View File

@ -27,7 +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_save_cancel_button_box from openlp.core.lib.ui import UiStrings, create_accept_reject_button_box
class Ui_EditSongDialog(object): class Ui_EditSongDialog(object):
def setupUi(self, editSongDialog): def setupUi(self, editSongDialog):
@ -241,7 +241,7 @@ class Ui_EditSongDialog(object):
self.themeTabLayout.addWidget(self.commentsGroupBox) self.themeTabLayout.addWidget(self.commentsGroupBox)
self.songTabWidget.addTab(self.themeTab, u'') self.songTabWidget.addTab(self.themeTab, u'')
self.dialogLayout.addWidget(self.songTabWidget) self.dialogLayout.addWidget(self.songTabWidget)
self.buttonBox = create_save_cancel_button_box(editSongDialog) self.buttonBox = create_accept_reject_button_box(editSongDialog)
self.dialogLayout.addWidget(self.buttonBox) self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(editSongDialog) self.retranslateUi(editSongDialog)
QtCore.QMetaObject.connectSlotsByName(editSongDialog) QtCore.QMetaObject.connectSlotsByName(editSongDialog)
@ -257,19 +257,15 @@ class Ui_EditSongDialog(object):
translate('SongsPlugin.EditSongForm', '&Lyrics:')) translate('SongsPlugin.EditSongForm', '&Lyrics:'))
self.verseOrderLabel.setText( self.verseOrderLabel.setText(
translate('SongsPlugin.EditSongForm', '&Verse order:')) translate('SongsPlugin.EditSongForm', '&Verse order:'))
self.verseAddButton.setText( self.verseAddButton.setText(UiStrings.Add)
translate('SongsPlugin.EditSongForm', '&Add')) self.verseEditButton.setText(UiStrings.Edit)
self.verseEditButton.setText(
translate('SongsPlugin.EditSongForm', '&Edit'))
self.verseEditAllButton.setText( self.verseEditAllButton.setText(
translate('SongsPlugin.EditSongForm', 'Ed&it All')) translate('SongsPlugin.EditSongForm', 'Ed&it All'))
self.verseDeleteButton.setText( self.verseDeleteButton.setText(UiStrings.Delete)
translate('SongsPlugin.EditSongForm', '&Delete'))
self.songTabWidget.setTabText( self.songTabWidget.setTabText(
self.songTabWidget.indexOf(self.lyricsTab), self.songTabWidget.indexOf(self.lyricsTab),
translate('SongsPlugin.EditSongForm', 'Title && Lyrics')) translate('SongsPlugin.EditSongForm', 'Title && Lyrics'))
self.authorsGroupBox.setTitle( self.authorsGroupBox.setTitle(UiStrings.Authors)
translate('SongsPlugin.EditSongForm', 'Authors'))
self.authorAddButton.setText( self.authorAddButton.setText(
translate('SongsPlugin.EditSongForm', '&Add to Song')) translate('SongsPlugin.EditSongForm', '&Add to Song'))
self.authorRemoveButton.setText( self.authorRemoveButton.setText(
@ -292,8 +288,7 @@ class Ui_EditSongDialog(object):
self.songTabWidget.indexOf(self.authorsTab), self.songTabWidget.indexOf(self.authorsTab),
translate('SongsPlugin.EditSongForm', translate('SongsPlugin.EditSongForm',
'Authors, Topics && Song Book')) 'Authors, Topics && Song Book'))
self.themeGroupBox.setTitle( self.themeGroupBox.setTitle(UiStrings.Theme)
translate('SongsPlugin.EditSongForm', 'Theme'))
self.themeAddButton.setText( self.themeAddButton.setText(
translate('SongsPlugin.EditSongForm', 'New &Theme')) translate('SongsPlugin.EditSongForm', 'New &Theme'))
self.rightsGroupBox.setTitle( self.rightsGroupBox.setTitle(

View File

@ -161,6 +161,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def newSong(self): def newSong(self):
log.debug(u'New Song') log.debug(u'New Song')
self.song = None
self.initialise() self.initialise()
self.songTabWidget.setCurrentIndex(0) self.songTabWidget.setCurrentIndex(0)
self.titleEdit.setText(u'') self.titleEdit.setText(u'')

View File

@ -27,7 +27,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate, SpellTextEdit from openlp.core.lib import build_icon, translate, SpellTextEdit
from openlp.core.lib.ui import create_save_cancel_button_box from openlp.core.lib.ui import create_accept_reject_button_box
from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib import VerseType
class Ui_EditVerseDialog(object): class Ui_EditVerseDialog(object):
@ -61,7 +61,7 @@ class Ui_EditVerseDialog(object):
self.verseTypeLayout.addStretch() self.verseTypeLayout.addStretch()
self.dialogLayout.addLayout(self.verseTypeLayout) self.dialogLayout.addLayout(self.verseTypeLayout)
self.dialogLayout.addWidget( self.dialogLayout.addWidget(
create_save_cancel_button_box(editVerseDialog)) create_accept_reject_button_box(editVerseDialog))
self.retranslateUi(editVerseDialog) self.retranslateUi(editVerseDialog)
QtCore.QMetaObject.connectSlotsByName(editVerseDialog) QtCore.QMetaObject.connectSlotsByName(editVerseDialog)

View File

@ -27,7 +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_save_cancel_button_box from openlp.core.lib.ui import create_accept_reject_button_box
class Ui_SongBookDialog(object): class Ui_SongBookDialog(object):
def setupUi(self, songBookDialog): def setupUi(self, songBookDialog):
@ -51,7 +51,7 @@ class Ui_SongBookDialog(object):
self.bookLayout.addRow(self.publisherLabel, self.publisherEdit) self.bookLayout.addRow(self.publisherLabel, self.publisherEdit)
self.dialogLayout.addLayout(self.bookLayout) self.dialogLayout.addLayout(self.bookLayout)
self.dialogLayout.addWidget( self.dialogLayout.addWidget(
create_save_cancel_button_box(songBookDialog)) create_accept_reject_button_box(songBookDialog))
self.retranslateUi(songBookDialog) self.retranslateUi(songBookDialog)
songBookDialog.setMaximumHeight(songBookDialog.sizeHint().height()) songBookDialog.setMaximumHeight(songBookDialog.sizeHint().height())
QtCore.QMetaObject.connectSlotsByName(songBookDialog) QtCore.QMetaObject.connectSlotsByName(songBookDialog)

View File

@ -0,0 +1,370 @@
# -*- 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:`songexportform` module provides the wizard for exporting songs to the
OpenLyrics format.
"""
import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, Receiver, SettingsManager, translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard
from openlp.plugins.songs.lib.db import Song
from openlp.plugins.songs.lib.openlyricsexport import OpenLyricsExport
log = logging.getLogger(__name__)
class SongExportForm(OpenLPWizard):
"""
This is the Song Export Wizard, which allows easy exporting of Songs to the
OpenLyrics format.
"""
log.info(u'SongExportForm loaded')
def __init__(self, parent, plugin):
"""
Instantiate the wizard, and run any extra setup we need to.
``parent``
The QWidget-derived parent of the wizard.
``plugin``
The songs plugin.
"""
self.plugin = plugin
OpenLPWizard.__init__(self, parent, plugin, u'songExportWizard',
u':/wizards/wizard_exportsong.bmp')
self.stop_export_flag = False
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_export)
def stop_export(self):
"""
Sets the flag for the exporter to stop the export.
"""
log.debug(u'Stopping songs export')
self.stop_export_flag = True
def setupUi(self, image):
"""
Set up the song wizard UI.
"""
OpenLPWizard.setupUi(self, image)
def customInit(self):
"""
Song wizard specific initialisation.
"""
pass
def customSignals(self):
"""
Song wizard specific signals.
"""
QtCore.QObject.connect(self.availableListWidget,
QtCore.SIGNAL(u'itemActivated(QListWidgetItem*)'),
self.onItemPressed)
QtCore.QObject.connect(self.searchLineEdit,
QtCore.SIGNAL(u'textEdited(const QString&)'),
self.onSearchLineEditChanged)
QtCore.QObject.connect(self.uncheckButton,
QtCore.SIGNAL(u'clicked()'), self.onUncheckButtonClicked)
QtCore.QObject.connect(self.checkButton,
QtCore.SIGNAL(u'clicked()'), self.onCheckButtonClicked)
QtCore.QObject.connect(self.directoryButton,
QtCore.SIGNAL(u'clicked()'), self.onDirectoryButtonClicked)
def addCustomPages(self):
"""
Add song wizard specific pages.
"""
# The page with all available songs.
self.availableSongsPage = QtGui.QWizardPage()
self.availableSongsPage.setObjectName(u'availableSongsPage')
self.availableSongsLayout = QtGui.QHBoxLayout(self.availableSongsPage)
self.availableSongsLayout.setObjectName(u'availableSongsLayout')
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(u'verticalLayout')
self.availableListWidget = QtGui.QListWidget(self.availableSongsPage)
self.availableListWidget.setObjectName(u'availableListWidget')
self.verticalLayout.addWidget(self.availableListWidget)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(u'horizontalLayout')
self.searchLabel = QtGui.QLabel(self.availableSongsPage)
self.searchLabel.setObjectName(u'searchLabel')
self.horizontalLayout.addWidget(self.searchLabel)
self.searchLineEdit = QtGui.QLineEdit(self.availableSongsPage)
self.searchLineEdit.setObjectName(u'searchLineEdit')
self.horizontalLayout.addWidget(self.searchLineEdit)
spacerItem = QtGui.QSpacerItem(40, 20,
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.uncheckButton = QtGui.QPushButton(self.availableSongsPage)
self.uncheckButton.setObjectName(u'uncheckButton')
self.horizontalLayout.addWidget(self.uncheckButton)
self.checkButton = QtGui.QPushButton(self.availableSongsPage)
self.checkButton.setObjectName(u'selectButton')
self.horizontalLayout.addWidget(self.checkButton)
self.verticalLayout.addLayout(self.horizontalLayout)
self.availableSongsLayout.addLayout(self.verticalLayout)
self.addPage(self.availableSongsPage)
# The page with the selected songs.
self.exportSongPage = QtGui.QWizardPage()
self.exportSongPage.setObjectName(u'availableSongsPage')
self.exportSongLayout = QtGui.QHBoxLayout(self.exportSongPage)
self.exportSongLayout.setObjectName(u'exportSongLayout')
self.gridLayout = QtGui.QGridLayout()
self.gridLayout.setObjectName(u'gridLayout')
self.selectedListWidget = QtGui.QListWidget(self.exportSongPage)
self.selectedListWidget.setObjectName(u'selectedListWidget')
self.gridLayout.addWidget(self.selectedListWidget, 1, 0, 1, 1)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(u'horizontalLayout')
self.directoryLabel = QtGui.QLabel(self.exportSongPage)
self.directoryLabel.setObjectName(u'directoryLabel')
self.horizontalLayout.addWidget(self.directoryLabel)
self.directoryLineEdit = QtGui.QLineEdit(self.exportSongPage)
self.directoryLineEdit.setObjectName(u'directoryLineEdit')
self.horizontalLayout.addWidget(self.directoryLineEdit)
self.directoryButton = QtGui.QToolButton(self.exportSongPage)
self.directoryButton.setIcon(build_icon(u':/exports/export_load.png'))
self.directoryButton.setObjectName(u'directoryButton')
self.horizontalLayout.addWidget(self.directoryButton)
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
self.exportSongLayout.addLayout(self.gridLayout)
self.addPage(self.exportSongPage)
def retranslateUi(self):
"""
Song wizard localisation.
"""
self.setWindowTitle(
translate('SongsPlugin.ExportWizardForm', 'Song Export Wizard'))
self.titleLabel.setText(
u'<span style="font-size:14pt; font-weight:600;">%s</span>' %
translate('SongsPlugin.ExportWizardForm',
'Welcome to the Song Export Wizard'))
self.informationLabel.setText(
translate('SongsPlugin.ExportWizardForm', 'This wizard will help to'
' export your songs to the open and free OpenLyrics worship song '
'format.'))
self.availableSongsPage.setTitle(
translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
self.availableSongsPage.setSubTitle(
translate('SongsPlugin.ExportWizardForm',
'Check the songs, you want to export.'))
self.searchLabel.setText(
translate('SongsPlugin.ExportWizardForm', 'Search:'))
self.uncheckButton.setText(
translate('SongsPlugin.ExportWizardForm', 'Uncheck All'))
self.checkButton.setText(
translate('SongsPlugin.ExportWizardForm', 'Check All'))
self.exportSongPage.setTitle(
translate('SongsPlugin.ExportWizardForm', 'Select Directory'))
self.exportSongPage.setSubTitle(
translate('SongsPlugin.ExportWizardForm',
'Select the directory you want the songs to be saved.'))
self.directoryLabel.setText(
translate('SongsPlugin.ExportWizardForm', 'Directory:'))
self.progressPage.setTitle(
translate('SongsPlugin.ExportWizardForm', 'Exporting'))
self.progressPage.setSubTitle(
translate('SongsPlugin.ExportWizardForm',
'Please wait while your songs are exported.'))
self.progressLabel.setText(
translate('SongsPlugin.ExportWizardForm', 'Ready.'))
self.progressBar.setFormat(
translate('SongsPlugin.ExportWizardForm', '%p%'))
def validateCurrentPage(self):
"""
Validate the current page before moving on to the next page.
"""
if self.currentPage() == self.welcomePage:
return True
elif self.currentPage() == self.availableSongsPage:
items = [
item for item in self._findListWidgetItems(
self.availableListWidget) if item.checkState()
]
if not items:
critical_error_message_box(
translate('SongsPlugin.ExportWizardForm',
'No Song Selected'),
translate('SongsPlugin.ExportWizardForm',
'You need to add at least one Song to export.'))
return False
self.selectedListWidget.clear()
# Add the songs to the list of selected songs.
for item in items:
song = QtGui.QListWidgetItem(item.text())
song.setData(QtCore.Qt.UserRole,
QtCore.QVariant(item.data(QtCore.Qt.UserRole).toPyObject()))
song.setFlags(QtCore.Qt.ItemIsEnabled)
self.selectedListWidget.addItem(song)
return True
elif self.currentPage() == self.exportSongPage:
if not self.directoryLineEdit.text():
critical_error_message_box(
translate('SongsPlugin.ExportWizardForm',
'No Save Location specified'),
translate('SongsPlugin.ExportWizardForm',
'You need to specified a directory to save the songs in.'))
return False
return True
elif self.currentPage() == self.progressPage:
self.availableListWidget.clear()
self.selectedListWidget.clear()
return True
def setDefaults(self):
"""
Set default form values for the song export wizard.
"""
self.restart()
self.finishButton.setVisible(False)
self.cancelButton.setVisible(True)
self.availableListWidget.clear()
self.selectedListWidget.clear()
self.directoryLineEdit.clear()
self.searchLineEdit.clear()
# Load the list of songs.
Receiver.send_message(u'cursor_busy')
songs = self.plugin.manager.get_all_objects(Song)
for song in songs:
authors = u', '.join([author.display_name
for author in song.authors])
title = u'%s (%s)' % (unicode(song.title), authors)
item = QtGui.QListWidgetItem(title)
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(song))
item.setFlags(QtCore.Qt.ItemIsSelectable|
QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Unchecked)
self.availableListWidget.addItem(item)
Receiver.send_message(u'cursor_normal')
def preWizard(self):
"""
Perform pre export tasks.
"""
OpenLPWizard.preWizard(self)
self.progressLabel.setText(
translate('SongsPlugin.ExportWizardForm', 'Starting export...'))
Receiver.send_message(u'openlp_process_events')
def performWizard(self):
"""
Perform the actual export. This creates an *openlyricsexport* instance
and calls the *do_export* method.
"""
songs = [
song.data(QtCore.Qt.UserRole).toPyObject()
for song in self._findListWidgetItems(self.selectedListWidget)
]
exporter = OpenLyricsExport(
self, songs, unicode(self.directoryLineEdit.text()))
if exporter.do_export():
self.progressLabel.setText(
translate('SongsPlugin.SongExportForm', 'Finished export.'))
else:
self.progressLabel.setText(
translate('SongsPlugin.SongExportForm',
'Your song export failed.'))
def _findListWidgetItems(self, listWidget, text=u''):
"""
Returns a list of *QListWidgetItem*s of the ``listWidget``. Note, that
hidden items are included.
``listWidget``
The widget to get all items from. (QListWidget)
``text``
The text to search for. (unicode string)
"""
return [item for item in listWidget.findItems(
QtCore.QString(unicode(text)), QtCore.Qt.MatchContains)
]
def onItemPressed(self, item):
"""
Called, when an item in the *availableListWidget* has been pressed. Thes
item is check if it was not checked, whereas it is unchecked when it was
checked.
``item``
The *QListWidgetItem* which was pressed.
"""
item.setCheckState(
QtCore.Qt.Unchecked if item.checkState() else QtCore.Qt.Checked)
def onSearchLineEditChanged(self, text):
"""
The *searchLineEdit*'s text has been changed. Update the list of
available songs. Note that any song, which does not match the ``text``
will be hidden, but not unchecked!
``text``
The text of the *searchLineEdit*. (QString)
"""
search_result = [
song for song in self._findListWidgetItems(
self.availableListWidget, unicode(text))
]
for item in self._findListWidgetItems(self.availableListWidget):
item.setHidden(False if item in search_result else True)
def onUncheckButtonClicked(self):
"""
The *uncheckButton* has been clicked. Set all visible songs unchecked.
"""
for row in range(self.availableListWidget.count()):
item = self.availableListWidget.item(row)
if not item.isHidden():
item.setCheckState(QtCore.Qt.Unchecked)
def onCheckButtonClicked(self):
"""
The *checkButton* has been clicked. Set all visible songs checked.
"""
for row in range(self.availableListWidget.count()):
item = self.availableListWidget.item(row)
if not item.isHidden():
item.setCheckState(QtCore.Qt.Checked)
def onDirectoryButtonClicked(self):
"""
Called when the *directoryButton* was clicked. Opens a dialog and writes
the path to *directoryLineEdit*.
"""
path = unicode(QtGui.QFileDialog.getExistingDirectory(self,
translate('SongsPlugin.ExportWizardForm', 'Selecte to Folder'),
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
options=QtGui.QFileDialog.ShowDirsOnly))
SettingsManager.set_last_dir(self.plugin.settingsSection, path, 1)
self.directoryLineEdit.setText(path)

View File

@ -32,7 +32,7 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsManager, translate from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.lib.ui import critical_error_message_box from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.ui.wizard import OpenLPWizard from openlp.core.ui.wizard import OpenLPWizard
from openlp.plugins.songs.lib.importer import SongFormat from openlp.plugins.songs.lib.importer import SongFormat
@ -140,6 +140,12 @@ class SongImportForm(OpenLPWizard):
QtCore.QObject.connect(self.songBeamerRemoveButton, QtCore.QObject.connect(self.songBeamerRemoveButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onSongBeamerRemoveButtonClicked) self.onSongBeamerRemoveButtonClicked)
QtCore.QObject.connect(self.songShowPlusAddButton,
QtCore.SIGNAL(u'clicked()'),
self.onSongShowPlusAddButtonClicked)
QtCore.QObject.connect(self.songShowPlusRemoveButton,
QtCore.SIGNAL(u'clicked()'),
self.onSongShowPlusRemoveButtonClicked)
def addCustomPages(self): def addCustomPages(self):
""" """
@ -188,6 +194,8 @@ class SongImportForm(OpenLPWizard):
self.addFileSelectItem(u'ew', single_select=True) self.addFileSelectItem(u'ew', single_select=True)
# Words of Worship # Words of Worship
self.addFileSelectItem(u'songBeamer') self.addFileSelectItem(u'songBeamer')
# Song Show Plus
self.addFileSelectItem(u'songShowPlus')
# Commented out for future use. # Commented out for future use.
# self.addFileSelectItem(u'csv', u'CSV', single_select=True) # self.addFileSelectItem(u'csv', u'CSV', single_select=True)
self.sourceLayout.addLayout(self.formatStack) self.sourceLayout.addLayout(self.formatStack)
@ -215,8 +223,7 @@ class SongImportForm(OpenLPWizard):
'Select the import format, and where to import from.')) 'Select the import format, and where to import from.'))
self.formatLabel.setText( self.formatLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Format:')) translate('SongsPlugin.ImportWizardForm', 'Format:'))
self.formatComboBox.setItemText(0, self.formatComboBox.setItemText(0, UiStrings.OLPV2)
translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0'))
self.formatComboBox.setItemText(1, self.formatComboBox.setItemText(1,
translate('SongsPlugin.ImportWizardForm', 'openlp.org 1.x')) translate('SongsPlugin.ImportWizardForm', 'openlp.org 1.x'))
self.formatComboBox.setItemText(2, self.formatComboBox.setItemText(2,
@ -238,6 +245,8 @@ class SongImportForm(OpenLPWizard):
translate('SongsPlugin.ImportWizardForm', 'EasyWorship')) translate('SongsPlugin.ImportWizardForm', 'EasyWorship'))
self.formatComboBox.setItemText(10, self.formatComboBox.setItemText(10,
translate('SongsPlugin.ImportWizardForm', 'SongBeamer')) translate('SongsPlugin.ImportWizardForm', 'SongBeamer'))
self.formatComboBox.setItemText(11,
translate('SongsPlugin.ImportWizardForm', 'SongShow Plus'))
# self.formatComboBox.setItemText(11, # self.formatComboBox.setItemText(11,
# translate('SongsPlugin.ImportWizardForm', 'CSV')) # translate('SongsPlugin.ImportWizardForm', 'CSV'))
self.openLP2FilenameLabel.setText( self.openLP2FilenameLabel.setText(
@ -302,6 +311,10 @@ class SongImportForm(OpenLPWizard):
translate('SongsPlugin.ImportWizardForm', 'Add Files...')) translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.songBeamerRemoveButton.setText( self.songBeamerRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
self.songShowPlusAddButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
self.songShowPlusRemoveButton.setText(
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
# self.csvFilenameLabel.setText( # self.csvFilenameLabel.setText(
# translate('SongsPlugin.ImportWizardForm', 'Filename:')) # translate('SongsPlugin.ImportWizardForm', 'Filename:'))
# self.csvBrowseButton.setText( # self.csvBrowseButton.setText(
@ -439,38 +452,20 @@ class SongImportForm(OpenLPWizard):
'file to import from.')) 'file to import from.'))
self.songBeamerAddButton.setFocus() self.songBeamerAddButton.setFocus()
return False return False
elif source_format == SongFormat.SongShowPlus:
if self.songShowPlusFileListWidget.count() == 0:
critical_error_message_box(
translate('SongsPlugin.ImportWizardForm',
'No SongShow Plus Files Selected'),
translate('SongsPlugin.ImportWizardForm',
'You need to add at least one SongShow Plus '
'file to import from.'))
self.wordsOfWorshipAddButton.setFocus()
return False
return True return True
elif self.currentPage() == self.progressPage: elif self.currentPage() == self.progressPage:
return True return True
def getFileName(self, title, editbox, filters=u''):
"""
Opens a QFileDialog and writes 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 descriptions
as well as the file extensions. For example::
u'OpenLP 2.0 Databases (*.sqlite)'
"""
if filters:
filters += u';;'
filters += u'%s (*)' % translate('SongsPlugin.ImportWizardForm',
'All Files')
filename = QtGui.QFileDialog.getOpenFileName(self, title,
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
filters)
if filename:
editbox.setText(filename)
SettingsManager.set_last_dir(self.plugin.settingsSection,
os.path.split(unicode(filename))[0], 1)
def getFiles(self, title, listbox, filters=u''): def getFiles(self, title, listbox, filters=u''):
""" """
Opens a QFileDialog and writes the filenames to the given listbox. Opens a QFileDialog and writes the filenames to the given listbox.
@ -485,12 +480,11 @@ class SongImportForm(OpenLPWizard):
The file extension filters. It should contain the file descriptions The file extension filters. It should contain the file descriptions
as well as the file extensions. For example:: as well as the file extensions. For example::
u'SongBeamer files (*.sng)' u'SongBeamer Files (*.sng)'
""" """
if filters: if filters:
filters += u';;' filters += u';;'
filters += u'%s (*)' % translate('SongsPlugin.ImportWizardForm', filters += u'%s (*)' % UiStrings.AllFiles
'All Files')
filenames = QtGui.QFileDialog.getOpenFileNames(self, title, filenames = QtGui.QFileDialog.getOpenFileNames(self, title,
SettingsManager.get_last_dir(self.plugin.settingsSection, 1), SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
filters) filters)
@ -615,7 +609,7 @@ class SongImportForm(OpenLPWizard):
'Select Songs of Fellowship Files'), 'Select Songs of Fellowship Files'),
self.songsOfFellowshipFileListWidget, u'%s (*.rtf)' self.songsOfFellowshipFileListWidget, u'%s (*.rtf)'
% translate('SongsPlugin.ImportWizardForm', % translate('SongsPlugin.ImportWizardForm',
'Songs Of Felloship Song Files') 'Songs Of Fellowship Song Files')
) )
def onSongsOfFellowshipRemoveButtonClicked(self): def onSongsOfFellowshipRemoveButtonClicked(self):
@ -665,7 +659,7 @@ class SongImportForm(OpenLPWizard):
translate('SongsPlugin.ImportWizardForm', translate('SongsPlugin.ImportWizardForm',
'Select SongBeamer Files'), 'Select SongBeamer Files'),
self.songBeamerFileListWidget, u'%s (*.sng)' % self.songBeamerFileListWidget, u'%s (*.sng)' %
translate('SongsPlugin.ImportWizardForm', 'SongBeamer files') translate('SongsPlugin.ImportWizardForm', 'SongBeamer Files')
) )
def onSongBeamerRemoveButtonClicked(self): def onSongBeamerRemoveButtonClicked(self):
@ -674,11 +668,23 @@ class SongImportForm(OpenLPWizard):
""" """
self.removeSelectedItems(self.songBeamerFileListWidget) self.removeSelectedItems(self.songBeamerFileListWidget)
def registerFields(self): def onSongShowPlusAddButtonClicked(self):
""" """
Register song import wizard fields. Get SongShow Plus song database files
""" """
pass self.getFiles(
translate('SongsPlugin.ImportWizardForm',
'Select SongShow Plus Files'),
self.songShowPlusFileListWidget, u'%s (*.sbsong)'
% translate('SongsPlugin.ImportWizardForm',
'SongShow Plus Song Files')
)
def onSongShowPlusRemoveButtonClicked(self):
"""
Remove selected SongShow Plus files from the import list
"""
self.removeSelectedItems(self.songShowPlusFileListWidget)
def setDefaults(self): def setDefaults(self):
""" """
@ -699,6 +705,7 @@ class SongImportForm(OpenLPWizard):
self.easiSlidesFilenameEdit.setText(u'') self.easiSlidesFilenameEdit.setText(u'')
self.ewFilenameEdit.setText(u'') self.ewFilenameEdit.setText(u'')
self.songBeamerFileListWidget.clear() self.songBeamerFileListWidget.clear()
self.songShowPlusFileListWidget.clear()
#self.csvFilenameEdit.setText(u'') #self.csvFilenameEdit.setText(u'')
def preWizard(self): def preWizard(self):
@ -775,6 +782,12 @@ class SongImportForm(OpenLPWizard):
importer = self.plugin.importSongs(SongFormat.SongBeamer, importer = self.plugin.importSongs(SongFormat.SongBeamer,
filenames=self.getListOfFiles(self.songBeamerFileListWidget) filenames=self.getListOfFiles(self.songBeamerFileListWidget)
) )
elif source_format == SongFormat.SongShowPlus:
# Import ShongShow Plus songs
importer = self.plugin.importSongs(SongFormat.SongShowPlus,
filenames=self.getListOfFiles(
self.songShowPlusFileListWidget)
)
if importer.do_import(): if importer.do_import():
self.progressLabel.setText( self.progressLabel.setText(
translate('SongsPlugin.SongImportForm', 'Finished import.')) translate('SongsPlugin.SongImportForm', 'Finished import.'))

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 UiStrings
class Ui_SongMaintenanceDialog(object): class Ui_SongMaintenanceDialog(object):
def setupUi(self, songMaintenanceDialog): def setupUi(self, songMaintenanceDialog):
@ -145,30 +146,21 @@ class Ui_SongMaintenanceDialog(object):
def retranslateUi(self, songMaintenanceDialog): def retranslateUi(self, songMaintenanceDialog):
songMaintenanceDialog.setWindowTitle( songMaintenanceDialog.setWindowTitle(
translate('SongsPlugin.SongMaintenanceForm', 'Song Maintenance')) translate('SongsPlugin.SongMaintenanceForm', 'Song Maintenance'))
authorsString = translate('SongsPlugin.SongMaintenanceForm', 'Authors') authorsString = UiStrings.Authors
topicsString = translate('SongsPlugin.SongMaintenanceForm', 'Topics') topicsString = translate('SongsPlugin.SongMaintenanceForm', 'Topics')
booksString = translate('SongsPlugin.SongMaintenanceForm', 'Song Books') booksString = translate('SongsPlugin.SongMaintenanceForm', 'Song Books')
self.listItemAuthors.setText(authorsString) self.listItemAuthors.setText(authorsString)
self.listItemTopics.setText(topicsString) self.listItemTopics.setText(topicsString)
self.listItemBooks.setText(booksString) self.listItemBooks.setText(booksString)
self.authorsAddButton.setText( self.authorsAddButton.setText(UiStrings.Add)
translate('SongsPlugin.SongMaintenanceForm', '&Add')) self.authorsEditButton.setText(UiStrings.Edit)
self.authorsEditButton.setText( self.authorsDeleteButton.setText(UiStrings.Delete)
translate('SongsPlugin.SongMaintenanceForm', '&Edit')) self.topicsAddButton.setText(UiStrings.Add)
self.authorsDeleteButton.setText( self.topicsEditButton.setText(UiStrings.Edit)
translate('SongsPlugin.SongMaintenanceForm', '&Delete')) self.topicsDeleteButton.setText(UiStrings.Delete)
self.topicsAddButton.setText( self.booksAddButton.setText(UiStrings.Add)
translate('SongsPlugin.SongMaintenanceForm', '&Add')) self.booksEditButton.setText(UiStrings.Edit)
self.topicsEditButton.setText( self.booksDeleteButton.setText(UiStrings.Delete)
translate('SongsPlugin.SongMaintenanceForm', '&Edit'))
self.topicsDeleteButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Delete'))
self.booksAddButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Add'))
self.booksEditButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Edit'))
self.booksDeleteButton.setText(
translate('SongsPlugin.SongMaintenanceForm', '&Delete'))
typeListWidth = max(self.fontMetrics().width(authorsString), typeListWidth = max(self.fontMetrics().width(authorsString),
self.fontMetrics().width(topicsString), self.fontMetrics().width(topicsString),
self.fontMetrics().width(booksString)) self.fontMetrics().width(booksString))

View File

@ -457,7 +457,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onTopicDeleteButtonClick(self): def onTopicDeleteButtonClick(self):
""" """
Delete the Book is the Book is not attached to any songs. Delete the Book if the Book is not attached to any songs.
""" """
self._deleteItem(Topic, self.topicsListWidget, self.resetTopics, self._deleteItem(Topic, self.topicsListWidget, self.resetTopics,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'), translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
@ -470,7 +470,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onBookDeleteButtonClick(self): def onBookDeleteButtonClick(self):
""" """
Delete the Book is the Book is not attached to any songs. Delete the Book if the Book is not attached to any songs.
""" """
self._deleteItem(Book, self.booksListWidget, self.resetBooks, self._deleteItem(Book, self.booksListWidget, self.resetBooks,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'), translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),

View File

@ -27,7 +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_save_cancel_button_box from openlp.core.lib.ui import create_accept_reject_button_box
class Ui_TopicsDialog(object): class Ui_TopicsDialog(object):
def setupUi(self, topicsDialog): def setupUi(self, topicsDialog):
@ -45,7 +45,7 @@ class Ui_TopicsDialog(object):
self.nameLayout.addRow(self.nameLabel, self.nameEdit) self.nameLayout.addRow(self.nameLabel, self.nameEdit)
self.dialogLayout.addLayout(self.nameLayout) self.dialogLayout.addLayout(self.nameLayout)
self.dialogLayout.addWidget( self.dialogLayout.addWidget(
create_save_cancel_button_box(topicsDialog)) create_accept_reject_button_box(topicsDialog))
self.retranslateUi(topicsDialog) self.retranslateUi(topicsDialog)
topicsDialog.setMaximumHeight(topicsDialog.sizeHint().height()) topicsDialog.setMaximumHeight(topicsDialog.sizeHint().height())
QtCore.QMetaObject.connectSlotsByName(topicsDialog) QtCore.QMetaObject.connectSlotsByName(topicsDialog)

View File

@ -104,6 +104,15 @@ class VerseType(object):
def retrieve_windows_encoding(recommendation=None): def retrieve_windows_encoding(recommendation=None):
"""
Determines which encoding to use on an information source. The process uses
both automated detection, which is passed to this method as a
recommendation, and user confirmation to return an encoding.
``recommendation``
A recommended encoding discovered programmatically for the user to
confirm.
"""
# map chardet result to compatible windows standard code page # map chardet result to compatible windows standard code page
codepage_mapping = {'IBM866': u'cp866', 'TIS-620': u'cp874', codepage_mapping = {'IBM866': u'cp866', 'TIS-620': u'cp874',
'SHIFT_JIS': u'cp932', 'GB2312': u'cp936', 'HZ-GB-2312': u'cp936', 'SHIFT_JIS': u'cp932', 'GB2312': u'cp936', 'HZ-GB-2312': u'cp936',

View File

@ -71,7 +71,6 @@ class Topic(BaseModel):
def init_schema(url): def init_schema(url):
""" """
Setup the songs database connection and initialise the database schema. Setup the songs database connection and initialise the database schema.

View File

@ -81,14 +81,16 @@ class EasiSlidesImport(SongImport):
def _parse_song(self, song): def _parse_song(self, song):
self._success = True self._success = True
self._add_title(self.title, song.Title1, True) self._add_unicode_attribute(u'title', song.Title1, True)
self._add_alttitle(self.alternate_title, song.Title2) self._add_unicode_attribute(u'alternate_title', song.Title2)
self._add_number(self.song_number, song.SongNumber) self._add_unicode_attribute(u'song_number', song.SongNumber)
if self.song_number == u'0': if self.song_number == u'0':
self.song_number = u'' self.song_number = u''
self._add_authors(song) self._add_authors(song)
self._add_copyright(song) self._add_copyright(song.Copyright)
self._add_book(self.song_book_name, song.BookReference) self._add_copyright(song.LicenceAdmin1)
self._add_copyright(song.LicenceAdmin2)
self._add_unicode_attribute(u'song_book_name', song.BookReference)
self._parse_and_add_lyrics(song) self._parse_and_add_lyrics(song)
return self._success return self._success
@ -110,7 +112,7 @@ class EasiSlidesImport(SongImport):
Signals that this attribute must exist in a valid song. Signals that this attribute must exist in a valid song.
""" """
try: try:
self_attribute = unicode(import_attribute).strip() setattr(self, self_attribute, unicode(import_attribute).strip())
except UnicodeDecodeError: except UnicodeDecodeError:
log.exception(u'UnicodeDecodeError decoding %s' % import_attribute) log.exception(u'UnicodeDecodeError decoding %s' % import_attribute)
self._success = False self._success = False
@ -124,7 +126,7 @@ class EasiSlidesImport(SongImport):
authors = unicode(song.Writer).split(u',') authors = unicode(song.Writer).split(u',')
for author in authors: for author in authors:
author = author.strip() author = author.strip()
if len(author) > 0: if len(author):
self.authors.append(author) self.authors.append(author)
except UnicodeDecodeError: except UnicodeDecodeError:
log.exception(u'Unicode decode error while decoding Writer') log.exception(u'Unicode decode error while decoding Writer')
@ -132,35 +134,18 @@ class EasiSlidesImport(SongImport):
except AttributeError: except AttributeError:
pass pass
def _add_copyright(self, song): def _add_copyright(self, element):
"""
Assign the copyright information from the import to the song being
created.
``song``
The current song being imported.
"""
copyright_list = []
self.__add_copyright_element(copyright_list, song.Copyright)
self.__add_copyright_element(copyright_list, song.LicenceAdmin1)
self.__add_copyright_element(copyright_list, song.LicenceAdmin2)
self.add_copyright(u' '.join(copyright_list))
def __add_copyright_element(self, copyright_list, element):
""" """
Add a piece of copyright to the total copyright information for the Add a piece of copyright to the total copyright information for the
song. song.
``copyright_list``
The array to add the information to.
``element`` ``element``
The imported variable to get the data from. The imported variable to get the data from.
""" """
try: try:
copyright_list.append(unicode(element).strip()) self.add_copyright(unicode(element).strip())
except UnicodeDecodeError: except UnicodeDecodeError:
log.exception(u'Unicode error decoding %s' % element) log.exception(u'Unicode error on decoding copyright: %s' % element)
self._success = False self._success = False
except AttributeError: except AttributeError:
pass pass
@ -285,10 +270,12 @@ class EasiSlidesImport(SongImport):
# as these appeared originally in the file # as these appeared originally in the file
for [reg, vt, vn, inst] in our_verse_order: for [reg, vt, vn, inst] in our_verse_order:
if self._listHas(verses, [reg, vt, vn, inst]): if self._listHas(verses, [reg, vt, vn, inst]):
# this is false, but needs user input
lang = None
versetag = u'%s%s' % (vt, vn) versetag = u'%s%s' % (vt, vn)
versetags.append(versetag) versetags.append(versetag)
lines = u'\n'.join(verses[reg][vt][vn][inst]) lines = u'\n'.join(verses[reg][vt][vn][inst])
self.verses.append([versetag, lines]) self.verses.append([versetag, lines, lang])
SeqTypes = { SeqTypes = {
u'p': u'P1', u'p': u'P1',

View File

@ -34,6 +34,7 @@ from wowimport import WowImport
from cclifileimport import CCLIFileImport from cclifileimport import CCLIFileImport
from ewimport import EasyWorshipSongImport from ewimport import EasyWorshipSongImport
from songbeamerimport import SongBeamerImport from songbeamerimport import SongBeamerImport
from songshowplusimport import SongShowPlusImport
# Imports that might fail # Imports that might fail
try: try:
from olp1import import OpenLP1SongImport from olp1import import OpenLP1SongImport
@ -67,10 +68,11 @@ class SongFormat(object):
CCLI = 5 CCLI = 5
SongsOfFellowship = 6 SongsOfFellowship = 6
Generic = 7 Generic = 7
#CSV = 8
EasiSlides = 8 EasiSlides = 8
EasyWorship = 9 EasyWorship = 9
SongBeamer = 10 SongBeamer = 10
SongShowPlus = 11
#CSV = 12
@staticmethod @staticmethod
def get_class(format): def get_class(format):
@ -102,6 +104,8 @@ class SongFormat(object):
return EasyWorshipSongImport return EasyWorshipSongImport
elif format == SongFormat.SongBeamer: elif format == SongFormat.SongBeamer:
return SongBeamerImport return SongBeamerImport
elif format == SongFormat.SongShowPlus:
return SongShowPlusImport
return None return None
@staticmethod @staticmethod
@ -120,7 +124,8 @@ class SongFormat(object):
SongFormat.Generic, SongFormat.Generic,
SongFormat.EasiSlides, SongFormat.EasiSlides,
SongFormat.EasyWorship, SongFormat.EasyWorship,
SongFormat.SongBeamer SongFormat.SongBeamer,
SongFormat.SongShowPlus
] ]
@staticmethod @staticmethod

View File

@ -31,22 +31,17 @@ import re
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from sqlalchemy.sql import or_ from sqlalchemy.sql import or_
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
ItemCapabilities, translate, check_item_selected, PluginStatus translate, check_item_selected, PluginStatus
from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm SongImportForm, SongExportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML from openlp.plugins.songs.lib import OpenLyrics, SongXML
from openlp.plugins.songs.lib.db import Author, Song from openlp.plugins.songs.lib.db import Author, Song
from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.searchedit import SearchEdit
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class SongListView(BaseListWithDnD):
def __init__(self, parent=None):
self.PluginName = u'Songs'
BaseListWithDnD.__init__(self, parent)
class SongMediaItem(MediaManagerItem): class SongMediaItem(MediaManagerItem):
""" """
This is the custom media manager item for Songs. This is the custom media manager item for Songs.
@ -55,7 +50,6 @@ class SongMediaItem(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 = SongListView
MediaManagerItem.__init__(self, parent, self, icon) MediaManagerItem.__init__(self, parent, self, icon)
self.edit_song_form = EditSongForm(self, self.parent.manager) self.edit_song_form = EditSongForm(self, self.parent.manager)
self.openLyrics = OpenLyrics(self.parent.manager) self.openLyrics = OpenLyrics(self.parent.manager)
@ -147,10 +141,8 @@ class SongMediaItem(MediaManagerItem):
translate('SongsPlugin.MediaItem', 'Titles')), translate('SongsPlugin.MediaItem', 'Titles')),
(3, u':/songs/song_search_lyrics.png', (3, u':/songs/song_search_lyrics.png',
translate('SongsPlugin.MediaItem', 'Lyrics')), translate('SongsPlugin.MediaItem', 'Lyrics')),
(4, u':/songs/song_search_author.png', (4, u':/songs/song_search_author.png', UiStrings.Authors),
translate('SongsPlugin.MediaItem', 'Authors')), (5, u':/slides/slide_theme.png', UiStrings.Themes)
(5, u':/slides/slide_theme.png',
translate('SongsPlugin.MediaItem', 'Themes'))
]) ])
self.configUpdated() self.configUpdated()
@ -266,6 +258,11 @@ class SongMediaItem(MediaManagerItem):
if self.import_wizard.exec_() == QtGui.QDialog.Accepted: if self.import_wizard.exec_() == QtGui.QDialog.Accepted:
Receiver.send_message(u'songs_load_list') Receiver.send_message(u'songs_load_list')
def onExportClick(self):
if not hasattr(self, u'export_wizard'):
self.export_wizard = SongExportForm(self, self.parent)
self.export_wizard.exec_()
def onNewClick(self): def onNewClick(self):
log.debug(u'onNewClick') log.debug(u'onNewClick')
self.edit_song_form.newSong() self.edit_song_form.newSong()

View File

@ -0,0 +1,74 @@
# -*- 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:`openlyricsexport` module provides the functionality for exporting
songs from the database to the OpenLyrics format.
"""
import logging
import os
from lxml import etree
from openlp.core.lib import Receiver, translate
from openlp.plugins.songs.lib import OpenLyrics
log = logging.getLogger(__name__)
class OpenLyricsExport(object):
"""
This provides the Openlyrics export.
"""
def __init__(self, parent, songs, save_path):
"""
Initialise the export.
"""
log.debug(u'initialise OpenLyricsExport')
self.parent = parent
self.manager = parent.plugin.manager
self.songs = songs
self.save_path = save_path
if not os.path.exists(self.save_path):
os.mkdir(self.save_path)
def do_export(self):
"""
Export the songs.
"""
log.debug(u'started OpenLyricsExport')
openLyrics = OpenLyrics(self.manager)
self.parent.progressBar.setMaximum(len(self.songs))
for song in self.songs:
Receiver.send_message(u'openlp_process_events')
if self.parent.stop_export_flag:
return False
self.parent.incrementProgressBar(unicode(translate(
'SongsPlugin.OpenLyricsExport', 'Exporting "%s"...')) %
song.title)
xml = openLyrics.song_to_xml(song)
tree = etree.ElementTree(etree.fromstring(xml))
tree.write(os.path.join(self.save_path, song.title + u'.xml'),
encoding=u'utf-8', xml_declaration=True, pretty_print=True)
return True

View File

@ -36,9 +36,7 @@ from openlp.plugins.songs.lib.songimport import SongImport
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class OpenSongImportError(Exception): #TODO: Use lxml for parsing and make sure we use methods of "SongImport" .
pass
class OpenSongImport(SongImport): class OpenSongImport(SongImport):
""" """
Import songs exported from OpenSong Import songs exported from OpenSong
@ -279,7 +277,7 @@ class OpenSongImport(SongImport):
for num in versenums: for num in versenums:
versetag = u'%s%s' % (our_verse_type, num) versetag = u'%s%s' % (our_verse_type, num)
lines = u'\n'.join(verses[versetype][num]) lines = u'\n'.join(verses[versetype][num])
self.verses.append([versetag, lines]) self.add_verse(lines, versetag)
# Keep track of what we have for error checking later # Keep track of what we have for error checking later
versetags[versetag] = 1 versetags[versetag] = 1
# now figure out the presentation order # now figure out the presentation order
@ -295,6 +293,8 @@ class OpenSongImport(SongImport):
else: else:
log.warn(u'No verse order available for %s, skipping.', log.warn(u'No verse order available for %s, skipping.',
self.title) self.title)
# TODO: make sure that the default order list will be overwritten, if
# the songs provides its own order list.
for tag in order: for tag in order:
if tag[0].isdigit(): if tag[0].isdigit():
# Assume it's a verse if it has no prefix # Assume it's a verse if it has no prefix

View File

@ -50,6 +50,7 @@ class SongImport(QtCore.QObject):
``manager`` ``manager``
An instance of a SongManager, through which all database access is An instance of a SongManager, through which all database access is
performed. performed.
""" """
self.manager = manager self.manager = manager
self.stop_import_flag = False self.stop_import_flag = False
@ -199,7 +200,7 @@ class SongImport(QtCore.QObject):
def add_verse(self, versetext, versetag=u'V', lang=None): def add_verse(self, versetext, versetag=u'V', lang=None):
""" """
Add a verse. This is the whole verse, lines split by \n. It will also Add a verse. This is the whole verse, lines split by \\n. It will also
attempt to detect duplicates. In this case it will just add to the verse attempt to detect duplicates. In this case it will just add to the verse
order. order.
@ -212,6 +213,7 @@ class SongImport(QtCore.QObject):
``lang`` ``lang``
The language code (ISO-639) of the verse, for example *en* or *de*. The language code (ISO-639) of the verse, for example *en* or *de*.
""" """
for (oldversetag, oldverse, oldlang) in self.verses: for (oldversetag, oldverse, oldlang) in self.verses:
if oldverse.strip() == versetext.strip(): if oldverse.strip() == versetext.strip():

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