This commit is contained in:
Tim Bentley 2011-02-10 17:41:55 +00:00
commit f3a93aaa54
55 changed files with 1289 additions and 717 deletions

View File

@ -4,8 +4,8 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# 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 #

View File

@ -1,8 +1,10 @@
.. _core-theme:
:mod:`theme` Module
===================
Theme Function Library
======================
.. automodule:: openlp.core.theme
: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
:members:
.. autoclass:: openlp.plugins.bibles.forms.importwizardform.ImportWizardForm
.. autoclass:: openlp.plugins.bibles.forms.bibleimportform.BibleImportForm
:members:
Helper Classes & Functions

View File

@ -48,7 +48,7 @@ copyright = u'2004-2010 Raoul Snyman'
# The short X.Y version.
version = '2.0'
# 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
# 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
# Sphinx are currently 'default' and 'sphinxdoc'.
#html_theme = 'openlp_qthelp'
html_theme = 'default'
# 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
# documentation.
html_theme_options = {
'sidebarbgcolor': '#3a60a9',
'relbarbgcolor': '#203b6f',
'footerbgcolor': '#26437c',
'headtextcolor': '#203b6f',
'linkcolor': '#26437c',
'sidebarlinkcolor': '#ceceff'
}
if html_theme == 'default':
html_theme_options = {
'sidebarbgcolor': '#3a60a9',
'relbarbgcolor': '#203b6f',
'footerbgcolor': '#26437c',
'headtextcolor': '#203b6f',
'linkcolor': '#26437c',
'sidebarlinkcolor': '#ceceff'
}
# 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
# "<project> v<release> documentation".

View File

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

View File

@ -17,10 +17,3 @@ Contents:
mediamanager
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

@ -31,6 +31,7 @@ import logging
from PyQt4 import QtCore
from openlp.core.lib import Receiver
from openlp.core.lib.ui import UiStrings
log = logging.getLogger(__name__)
@ -323,4 +324,33 @@ class Plugin(QtCore.QObject):
"""
Called to define all translatable texts of the plugin
"""
pass
## Load Action ##
self._setSingularTextString(StringContent.Load,
UiStrings.Load, UiStrings.LoadANew)
## New Action ##
self._setSingularTextString(StringContent.New,
UiStrings.Add, UiStrings.AddANew)
## Edit Action ##
self._setSingularTextString(StringContent.Edit,
UiStrings.Edit, UiStrings.EditSelect)
## Delete Action ##
self._setSingularTextString(StringContent.Delete,
UiStrings.Delete, UiStrings.DeleteSelect)
## Preview Action ##
self._setSingularTextString(StringContent.Preview,
UiStrings.Preview, UiStrings.PreviewSelect)
## Send Live Action ##
self._setSingularTextString(StringContent.Live,
UiStrings.Live, UiStrings.SendSelectLive)
## Add to Service Action ##
self._setSingularTextString(StringContent.Service,
UiStrings.Service, UiStrings.AddSelectService)
def _setSingularTextString(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 %
self.getString(StringContent.Name)[u'singular']}

View File

@ -34,6 +34,43 @@ from openlp.core.lib import build_icon, Receiver, translate
log = logging.getLogger(__name__)
class UiStrings(object):
"""
Provide standard strings for objects to use.
"""
# These strings should need a good reason to be retranslated elsewhere.
# Should some/more/less of these have an &amp; attached?
Add = translate('OpenLP.Ui', '&Add')
AddANew = unicode(translate('OpenLP.Ui', 'Add a new %s'))
AddSelectService = unicode(translate('OpenLP.Ui',
'Add the selected %s to the service'))
AllFiles = translate('OpenLP.Ui', 'All Files')
Authors = translate('OpenLP.Ui', 'Authors')
Delete = translate('OpenLP.Ui', '&Delete')
DeleteSelect = unicode(translate('OpenLP.Ui', 'Delete the selected %s'))
DeleteType = unicode(translate('OpenLP.Ui', 'Delete %s'))
Edit = translate('OpenLP.Ui', '&Edit')
EditSelect = unicode(translate('OpenLP.Ui', 'Edit the selected %s'))
EditType = unicode(translate('OpenLP.Ui', 'Edit %s'))
Error = translate('OpenLP.Ui', 'Error')
ExportType = unicode(translate('OpenLP.Ui', 'Export %s'))
Import = translate('OpenLP.Ui', 'Import')
ImportType = unicode(translate('OpenLP.Ui', 'Import %s'))
Live = translate('OpenLP.Ui', 'Live')
Load = translate('OpenLP.Ui', 'Load')
LoadANew = unicode(translate('OpenLP.Ui', 'Load a new %s'))
New = translate('OpenLP.Ui', 'New')
NewType = unicode(translate('OpenLP.Ui', 'New %s'))
OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0')
Preview = translate('OpenLP.Ui', 'Preview')
PreviewSelect = unicode(translate('OpenLP.Ui', 'Preview the selected %s'))
SendSelectLive = unicode(translate('OpenLP.Ui',
'Send the selected %s live'))
Service = translate('OpenLP.Ui', 'Service')
Theme = translate('OpenLP.Ui', 'Theme')
Themes = translate('OpenLP.Ui', 'Themes')
def add_welcome_page(parent, image):
"""
Generate an opening welcome page for a wizard using a provided image.
@ -98,13 +135,12 @@ def critical_error_message_box(title=None, message=None, parent=None,
``question``
Should this message box question the user.
"""
error = translate('OpenLP.Ui', 'Error')
if question:
return QtGui.QMessageBox.critical(parent, error, message,
return QtGui.QMessageBox.critical(parent, UiStrings.Error, message,
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
data = {u'message': message}
data[u'title'] = title if title else error
data[u'title'] = title if title else UiStrings.Error
return Receiver.send_message(u'openlp_error_message', data)
def media_item_combo_box(parent, name):
@ -134,7 +170,7 @@ def create_delete_push_button(parent, icon=None):
delete_button.setObjectName(u'deleteButton')
delete_icon = icon if icon else u':/general/general_delete.png'
delete_button.setIcon(build_icon(delete_icon))
delete_button.setText(translate('OpenLP.Ui', '&Delete'))
delete_button.setText(UiStrings.Delete)
delete_button.setToolTip(
translate('OpenLP.Ui', 'Delete the selected item.'))
QtCore.QObject.connect(delete_button,

View File

@ -71,38 +71,45 @@ class Theme(object):
Theme name
``BackgroundMode``
The behaviour of the background. Valid modes are:
- 0 - Transparent
- 1 - Opaque
The behaviour of the background. Valid modes are:
* ``0`` - Transparent
* ``1`` - Opaque
``BackgroundType``
The content of the background. Valid types are:
- 0 - solid color
- 1 - gradient color
- 2 - image
The content of the background. Valid types are:
* ``0`` - solid color
* ``1`` - gradient color
* ``2`` - image
``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:
- image: image filename
- gradient: start color
- solid: color
* ``image`` - image filename
* ``gradient`` - start color
* ``solid`` - color
``BackgroundParameter2``
Extra information about the background. The contents of this attribute
depend on the BackgroundType:
- image: border color
- gradient: end color
- solid: N/A
* ``image`` - border color
* ``gradient`` - end color
* ``solid`` - N/A
``BackgroundParameter3``
Extra information about the background. The contents of this attribute
depend on the BackgroundType:
- image: N/A
- gradient: The direction of the gradient. Valid entries are:
- 0 -> vertical
- 1 -> horizontal
- solid: N/A
* ``image`` - N/A
* ``gradient`` - The direction of the gradient. Valid entries are:
* ``0`` - vertical
* ``1`` - horizontal
* ``solid`` - N/A
``FontName``
Name of the font to use for the main font.
@ -118,36 +125,41 @@ class Theme(object):
``Shadow``
The shadow type to apply to the main font.
- 0 - no shadow
- non-zero - use shadow
* ``0`` - no shadow
* non-zero - use shadow
``ShadowColor``
Color for the shadow
``Outline``
The outline to apply to the main font
- 0 - no outline
- non-zero - use outline
* ``0`` - no outline
* non-zero - use outline
``OutlineColor``
Color for the outline (or None if Outline is 0)
``HorizontalAlign``
The horizontal alignment to apply to text. Valid alignments are:
- 0 - left align
- 1 - right align
- 2 - centre align
* ``0`` - left align
* ``1`` - right align
* ``2`` - centre align
``VerticalAlign``
The vertical alignment to apply to the text. Valid alignments are:
- 0 - top align
- 1 - bottom align
- 2 - centre align
* ``0`` - top align
* ``1`` - bottom align
* ``2`` - centre align
``WrapStyle``
The wrap style to apply to the text. Valid styles are:
- 0 - normal
- 1 - lyrics
* ``0`` - normal
* ``1`` - lyrics
"""
def __init__(self, xml):
"""

View File

@ -28,7 +28,7 @@ The :mod:`ui` module provides the core user interface for OpenLP
"""
from PyQt4 import QtGui
from openlp.core.lib import translate, Receiver
from openlp.core.lib import translate
class HideMode(object):
"""

View File

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

View File

@ -34,7 +34,7 @@ import cPickle
from PyQt4 import QtCore, QtGui
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):
"""
@ -164,8 +164,7 @@ class DisplayTagTab(SettingsTab):
self.startTagLabel.setText(
translate('OpenLP.DisplayTagTab', 'Start tag'))
self.endTagLabel.setText(translate('OpenLP.DisplayTagTab', 'End tag'))
self.deletePushButton.setText(
translate('OpenLP.DisplayTagTab', 'Delete'))
self.deletePushButton.setText(UiStrings.Delete)
self.defaultPushButton.setText(
translate('OpenLP.DisplayTagTab', 'Default'))
self.newPushButton.setText(translate('OpenLP.DisplayTagTab', 'New'))

View File

@ -30,7 +30,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
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, \
ThemeManager, SlideController, PluginForm, MediaDockManager, \
ShortcutListForm
@ -215,6 +216,9 @@ class Ui_MainWindow(object):
self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
u':/tools/tools_add.png')
mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools')
self.ToolsOpenDataFolder = icon_action(mainWindow, u'ToolsOpenDataFolder',
u':/general/general_open.png')
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,
@ -275,6 +279,7 @@ class Ui_MainWindow(object):
self.SettingsLanguageMenu.menuAction(), None,
self.SettingsShortcutsItem, self.SettingsConfigureItem))
add_actions(self.ToolsMenu, (self.ToolsAddToolItem, None))
add_actions(self.ToolsMenu, (self.ToolsOpenDataFolder, None))
add_actions(self.HelpMenu, (self.HelpDocumentationItem,
self.HelpOnlineHelpItem, None, self.HelpWebSiteItem,
self.HelpAboutItem))
@ -295,7 +300,7 @@ class Ui_MainWindow(object):
"""
Set up the translation system
"""
mainWindow.mainTitle = translate('OpenLP.MainWindow', 'OpenLP 2.0')
mainWindow.mainTitle = UiStrings.OLPV2
mainWindow.setWindowTitle(mainWindow.mainTitle)
self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
@ -432,6 +437,10 @@ class Ui_MainWindow(object):
translate('OpenLP.MainWindow', 'Add &Tool...'))
self.ToolsAddToolItem.setStatusTip(translate('OpenLP.MainWindow',
'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(
translate('OpenLP.MainWindow', '&Default'))
self.ModeDefaultItem.setStatusTip(translate('OpenLP.MainWindow',
@ -514,6 +523,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
QtCore.QObject.connect(self.HelpAboutItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked)
QtCore.QObject.connect(self.ToolsOpenDataFolder,
QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked)
QtCore.QObject.connect(self.settingsPluginListItem,
QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked)
QtCore.QObject.connect(self.SettingsConfigureItem,
@ -702,6 +713,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.pluginForm.load()
self.pluginForm.exec_()
def onToolsOpenDataFolderClicked(self):
"""
Open data folder
"""
path = AppLocation.get_data_path()
QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + path))
def onSettingsConfigureItemClicked(self):
"""
Show the Settings dialog

View File

@ -461,7 +461,7 @@ class ServiceManager(QtGui.QWidget):
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.
"""
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,

View File

@ -32,7 +32,7 @@ from PyQt4.phonon import Phonon
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
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
log = logging.getLogger(__name__)
@ -87,12 +87,11 @@ class SlideController(QtGui.QWidget):
# Type label for the top of the slide controller
self.typeLabel = QtGui.QLabel(self.panel)
if self.isLive:
self.typeLabel.setText(translate('OpenLP.SlideController', 'Live'))
self.typeLabel.setText(UiStrings.Live)
self.split = 1
self.typePrefix = u'live'
else:
self.typeLabel.setText(translate('OpenLP.SlideController',
'Preview'))
self.typeLabel.setText(UiStrings.Preview)
self.split = 0
self.typePrefix = u'preview'
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)
self.toolbar.addToolbarSeparator(u'Loop Separator')
self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Start Loop', u':/media/media_time.png',
translate('OpenLP.SlideController', 'Start continuous loop'),
self.onStartLoop)
self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Stop Loop', u':/media/media_stop.png',
translate('OpenLP.SlideController', 'Stop continuous loop'),
self.onStopLoop)
@ -197,11 +198,13 @@ class SlideController(QtGui.QWidget):
else:
self.toolbar.addToolbarSeparator(u'Close Separator')
self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Go Live', u':/general/general_live.png',
translate('OpenLP.SlideController', 'Move to live'),
self.onGoLive)
self.toolbar.addToolbarSeparator(u'Close Separator')
self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Edit Song', u':/general/general_edit.png',
translate('OpenLP.SlideController',
'Edit and reload song preview'),

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \
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 themewizard import Ui_ThemeWizard
@ -483,8 +483,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
Background Image button pushed.
"""
images_filter = get_images_filter()
images_filter = '%s;;%s (*.*) (*)' % (images_filter,
translate('OpenLP.ThemeForm', 'All Files'))
images_filter = '%s;;%s (*.*) (*)' % (images_filter, UiStrings.AllFiles)
filename = QtGui.QFileDialog.getOpenFileName(self,
translate('OpenLP.ThemeForm', 'Select Image'), u'',
images_filter)

View File

@ -35,7 +35,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \
build_icon, Receiver, SettingsManager, translate, check_item_selected, \
BackgroundType, BackgroundGradientType, check_directory_exists
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.theme import Theme
from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
@ -62,28 +62,28 @@ class ThemeManager(QtGui.QWidget):
self.layout.setObjectName(u'layout')
self.toolbar = OpenLPToolbar(self)
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'New Theme'),
UiStrings.NewType % UiStrings.Theme,
u':/themes/theme_new.png',
translate('OpenLP.ThemeManager', 'Create a new theme.'),
self.onAddTheme)
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Edit Theme'),
UiStrings.EditType % UiStrings.Theme,
u':/themes/theme_edit.png',
translate('OpenLP.ThemeManager', 'Edit a theme.'),
self.onEditTheme)
self.deleteToolbarAction = self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Delete Theme'),
UiStrings.DeleteType % UiStrings.Theme,
u':/general/general_delete.png',
translate('OpenLP.ThemeManager', 'Delete a theme.'),
self.onDeleteTheme)
self.toolbar.addSeparator()
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Import Theme'),
UiStrings.ImportType % UiStrings.Theme,
u':/general/general_import.png',
translate('OpenLP.ThemeManager', 'Import a theme.'),
self.onImportTheme)
self.toolbar.addToolbarButton(
translate('OpenLP.ThemeManager', 'Export Theme'),
UiStrings.ExportType % UiStrings.Theme,
u':/general/general_export.png',
translate('OpenLP.ThemeManager', 'Export a theme.'),
self.onExportTheme)

View File

@ -27,6 +27,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, Receiver, ThemeLevel, translate
from openlp.core.lib.ui import UiStrings
class ThemesTab(SettingsTab):
"""
@ -98,7 +99,7 @@ class ThemesTab(SettingsTab):
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
def retranslateUi(self):
self.tabTitleVisible = translate('OpenLP.ThemesTab', 'Themes')
self.tabTitleVisible = UiStrings.Themes
self.GlobalGroupBox.setTitle(
translate('OpenLP.ThemesTab', 'Global Theme'))
self.LevelGroupBox.setTitle(

View File

@ -24,7 +24,7 @@
# 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 os

View File

@ -27,7 +27,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate
from openlp.core.lib.ui import create_valign_combo
from openlp.core.lib.ui import UiStrings, create_valign_combo
class AlertsTab(SettingsTab):
"""
@ -117,10 +117,8 @@ class AlertsTab(SettingsTab):
translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
self.TimeoutSpinBox.setSuffix(
translate('AlertsPlugin.AlertsTab', 's'))
self.PreviewGroupBox.setTitle(
translate('AlertsPlugin.AlertsTab', 'Preview'))
self.FontPreview.setText(
translate('AlertsPlugin.AlertsTab', 'OpenLP 2.0'))
self.PreviewGroupBox.setTitle(UiStrings.Preview)
self.FontPreview.setText(UiStrings.OLPV2)
def onBackgroundColorButtonClicked(self):
new_color = QtGui.QColorDialog.getColor(

View File

@ -29,6 +29,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import UiStrings
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
log = logging.getLogger(__name__)
@ -137,38 +138,7 @@ class BiblePlugin(Plugin):
# Middle Header Bar
## Import Action ##
self.textStrings[StringContent.Import] = {
u'title': translate('BiblesPlugin', '&Import'),
u'title': UiStrings.Import,
u'tooltip': translate('BiblesPlugin', 'Import a Bible')
}
## New Action ##
self.textStrings[StringContent.New] = {
u'title': translate('BiblesPlugin', '&Add'),
u'tooltip': translate('BiblesPlugin', 'Add a new Bible')
}
## 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')
}
Plugin.setPluginTextStrings(self)

View File

@ -35,7 +35,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.lib.db import delete_database
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.utils import AppLocation, string_is_unicode
from openlp.plugins.bibles.lib.manager import BibleFormat
@ -745,8 +745,7 @@ class BibleImportForm(OpenLPWizard):
"""
if filters:
filters += u';;'
filters += u'%s (*)' % translate('BiblesPlugin.ImportWizardForm',
'All Files')
filters += u'%s (*)' % UiStrings.AllFiles
filename = QtGui.QFileDialog.getOpenFileName(self, title,
os.path.dirname(SettingsManager.get_last_dir(
self.plugin.settingsSection, 1)), filters)

View File

@ -69,69 +69,90 @@ def get_reference_match(match_type):
def parse_reference(reference):
"""
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
be queried from the Bible database files.
typed in string and converts it to a list of references to be queried from
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.
``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.
Returns ``None`` or a reference list.
The reference list is a list of tuples, with each tuple structured like
this::
(book, chapter, from_verse, to_verse)
For example::
[(u'John', 3, 16, 18), (u'John', 4, 1, 1)]
``reference``
The bible reference to parse.
**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)
match = get_reference_match(u'full').match(reference)
@ -201,7 +222,7 @@ def parse_reference(reference):
class SearchResults(object):
"""
Encapsulate a set of search results. This is Bible-type independent.
Encapsulate a set of search results. This is Bible-type independent.
"""
def __init__(self, book, chapter, verselist):
"""
@ -214,7 +235,8 @@ class SearchResults(object):
The chapter of the book.
``verselist``
The list of verses for this reading
The list of verses for this reading.
"""
self.book = book
self.chapter = chapter

View File

@ -30,6 +30,7 @@ from forms import EditCustomForm
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.db import Manager
from openlp.core.lib.ui import UiStrings
from openlp.plugins.custom.lib import CustomMediaItem, CustomTab
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
@ -114,52 +115,11 @@ class CustomPlugin(Plugin):
# Middle Header Bar
## Import Action ##
self.textStrings[StringContent.Import] = {
u'title': translate('CustomsPlugin', 'Import'),
u'title': UiStrings.Import,
u'tooltip': translate('CustomsPlugin',
'Import a Custom')
}
## Load Action ##
self.textStrings[StringContent.Load] = {
u'title': translate('CustomsPlugin', 'Load'),
u'tooltip': translate('CustomsPlugin',
'Load a new Custom')
}
## 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')
}
Plugin.setPluginTextStrings(self)
def finalise(self):
"""

View File

@ -27,7 +27,7 @@
from PyQt4 import QtCore, QtGui
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_save_cancel_button_box, \
create_delete_push_button, create_up_down_push_button_set
class Ui_CustomEditDialog(object):
@ -107,13 +107,11 @@ class Ui_CustomEditDialog(object):
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
self.titleLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Title:'))
self.addButton.setText(
translate('CustomPlugin.EditCustomForm', '&Add'))
self.addButton.setText(UiStrings.Add)
self.addButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Add a new slide at '
'bottom.'))
self.editButton.setText(
translate('CustomPlugin.EditCustomForm', '&Edit'))
self.editButton.setText(UiStrings.Edit)
self.editButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit the selected '
'slide.'))

View File

@ -27,6 +27,7 @@
import logging
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import UiStrings
from openlp.plugins.images.lib import ImageMediaItem
log = logging.getLogger(__name__)
@ -72,45 +73,4 @@ class ImagePlugin(Plugin):
u'title': translate('ImagePlugin', 'Images', 'container title')
}
# Middle Header Bar
## Load Button ##
self.textStrings[StringContent.Load] = {
u'title': translate('ImagePlugin', 'Load'),
u'tooltip': translate('ImagePlugin',
'Load a new Image')
}
## New Button ##
self.textStrings[StringContent.New] = {
u'title': translate('ImagePlugin', 'Add'),
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')
}
Plugin.setPluginTextStrings(self)

View File

@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
ItemCapabilities, SettingsManager, translate, check_item_selected, \
check_directory_exists, 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
log = logging.getLogger(__name__)
@ -64,7 +64,7 @@ class ImageMediaItem(MediaManagerItem):
'Select Image(s)')
file_formats = get_images_filter()
self.OnNewFileMasks = u'%s;;%s (*.*) (*)' % (file_formats,
unicode(translate('ImagePlugin.MediaItem', 'All Files')))
unicode(UiStrings.AllFiles))
self.replaceAction.setText(
translate('ImagePlugin.MediaItem', 'Replace Background'))
self.replaceAction.setToolTip(

View File

@ -30,6 +30,7 @@ import mimetypes
from PyQt4.phonon import Phonon
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import UiStrings
from openlp.plugins.media.lib import MediaMediaItem, MediaTab
log = logging.getLogger(__name__)
@ -101,45 +102,4 @@ class MediaPlugin(Plugin):
u'title': translate('MediaPlugin', 'Media', 'container title')
}
# Middle Header Bar
## Load Action ##
self.textStrings[StringContent.Load] = {
u'title': translate('MediaPlugin', 'Load'),
u'tooltip': translate('MediaPlugin',
'Load a new Media')
}
## New Action ##
self.textStrings[StringContent.New] = {
u'title': translate('MediaPlugin', 'Add'),
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')
}
Plugin.setPluginTextStrings(self)

View File

@ -429,7 +429,7 @@ class ImpressDocument(PresentationDocument):
``slide_no``
The slide the text is required for, starting at 1
"""
return __get_text_from_slide(slide_no)
return self.__get_text_from_page(slide_no)
def get_slide_notes(self, slide_no):
"""
@ -438,7 +438,7 @@ class ImpressDocument(PresentationDocument):
``slide_no``
The slide the notes are required for, starting at 1
"""
return __get_text_from_page(slide_no, True)
return self.__get_text_from_page(slide_no, True)
def __get_text_from_page(self, slide_no, notes=False):
"""

View File

@ -31,6 +31,7 @@ import os
import logging
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import UiStrings
from openlp.core.utils import AppLocation
from openlp.plugins.presentations.lib import PresentationController, \
PresentationMediaItem, PresentationTab
@ -167,33 +168,4 @@ class PresentationPlugin(Plugin):
'container title')
}
# Middle Header Bar
## Load Action ##
self.textStrings[StringContent.Load] = {
u'title': translate('PresentationPlugin', 'Load'),
u'tooltip': translate('PresentationPlugin',
'Load a new Presentation')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('PresentationPlugin', 'Delete'),
u'tooltip': translate('PresentationPlugin',
'Delete the selected Presentation')
}
## 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')
}
Plugin.setPluginTextStrings(self)

View File

@ -57,4 +57,6 @@ from songbookform import SongBookForm
from editverseform import EditVerseForm
from editsongform import EditSongForm
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 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_save_cancel_button_box
class Ui_EditSongDialog(object):
def setupUi(self, editSongDialog):
@ -257,19 +257,15 @@ class Ui_EditSongDialog(object):
translate('SongsPlugin.EditSongForm', '&Lyrics:'))
self.verseOrderLabel.setText(
translate('SongsPlugin.EditSongForm', '&Verse order:'))
self.verseAddButton.setText(
translate('SongsPlugin.EditSongForm', '&Add'))
self.verseEditButton.setText(
translate('SongsPlugin.EditSongForm', '&Edit'))
self.verseAddButton.setText(UiStrings.Add)
self.verseEditButton.setText(UiStrings.Edit)
self.verseEditAllButton.setText(
translate('SongsPlugin.EditSongForm', 'Ed&it All'))
self.verseDeleteButton.setText(
translate('SongsPlugin.EditSongForm', '&Delete'))
self.verseDeleteButton.setText(UiStrings.Delete)
self.songTabWidget.setTabText(
self.songTabWidget.indexOf(self.lyricsTab),
translate('SongsPlugin.EditSongForm', 'Title && Lyrics'))
self.authorsGroupBox.setTitle(
translate('SongsPlugin.EditSongForm', 'Authors'))
self.authorsGroupBox.setTitle(UiStrings.Authors)
self.authorAddButton.setText(
translate('SongsPlugin.EditSongForm', '&Add to Song'))
self.authorRemoveButton.setText(
@ -292,8 +288,7 @@ class Ui_EditSongDialog(object):
self.songTabWidget.indexOf(self.authorsTab),
translate('SongsPlugin.EditSongForm',
'Authors, Topics && Song Book'))
self.themeGroupBox.setTitle(
translate('SongsPlugin.EditSongForm', 'Theme'))
self.themeGroupBox.setTitle(UiStrings.Theme)
self.themeAddButton.setText(
translate('SongsPlugin.EditSongForm', 'New &Theme'))
self.rightsGroupBox.setTitle(

View File

@ -0,0 +1,372 @@
# -*- 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 registerFields(self):
"""
Register song export wizard fields.
"""
pass
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()
# 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 songs unchecked.
"""
for row in range(self.availableListWidget.count()):
item = self.availableListWidget.item(row)
item.setCheckState(QtCore.Qt.Unchecked)
def onCheckButtonClicked(self):
"""
The *checkButton* has been clicked. Set all songs checked.
"""
for row in range(self.availableListWidget.count()):
item = self.availableListWidget.item(row)
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 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.plugins.songs.lib.importer import SongFormat
@ -215,8 +215,7 @@ class SongImportForm(OpenLPWizard):
'Select the import format, and where to import from.'))
self.formatLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Format:'))
self.formatComboBox.setItemText(0,
translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0'))
self.formatComboBox.setItemText(0, UiStrings.OLPV2)
self.formatComboBox.setItemText(1,
translate('SongsPlugin.ImportWizardForm', 'openlp.org 1.x'))
self.formatComboBox.setItemText(2,
@ -489,8 +488,7 @@ class SongImportForm(OpenLPWizard):
"""
if filters:
filters += u';;'
filters += u'%s (*)' % translate('SongsPlugin.ImportWizardForm',
'All Files')
filters += u'%s (*)' % UiStrings.AllFiles
filenames = QtGui.QFileDialog.getOpenFileNames(self, title,
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
filters)

View File

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

View File

@ -33,8 +33,9 @@ from sqlalchemy.sql import or_
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \
ItemCapabilities, translate, check_item_selected, PluginStatus
from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm
SongImportForm, SongExportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML
from openlp.plugins.songs.lib.db import Author, Song
from openlp.core.lib.searchedit import SearchEdit
@ -147,10 +148,8 @@ class SongMediaItem(MediaManagerItem):
translate('SongsPlugin.MediaItem', 'Titles')),
(3, u':/songs/song_search_lyrics.png',
translate('SongsPlugin.MediaItem', 'Lyrics')),
(4, u':/songs/song_search_author.png',
translate('SongsPlugin.MediaItem', 'Authors')),
(5, u':/slides/slide_theme.png',
translate('SongsPlugin.MediaItem', 'Themes'))
(4, u':/songs/song_search_author.png', UiStrings.Authors),
(5, u':/slides/slide_theme.png', UiStrings.Themes)
])
self.configUpdated()
@ -266,6 +265,11 @@ class SongMediaItem(MediaManagerItem):
if self.import_wizard.exec_() == QtGui.QDialog.Accepted:
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):
log.debug(u'onNewClick')
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,6 +36,7 @@ from openlp.plugins.songs.lib.songimport import SongImport
log = logging.getLogger(__name__)
#TODO: Use lxml for parsing and make sure we use methods of "SongImport" .
class OpenSongImport(SongImport):
"""
Import songs exported from OpenSong
@ -146,7 +147,7 @@ class OpenSongImport(SongImport):
log.info(u'Zip importing %s', parts[-1])
self.import_wizard.incrementProgressBar(
unicode(translate('SongsPlugin.ImportWizardForm',
'Importing %s...')) % parts[-1])
'Importing %s...')) % parts[-1])
songfile = z.open(song)
self.do_import_file(songfile)
if self.commit:
@ -276,7 +277,7 @@ class OpenSongImport(SongImport):
for num in versenums:
versetag = u'%s%s' % (our_verse_type, 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
versetags[versetag] = 1
# now figure out the presentation order
@ -292,6 +293,8 @@ class OpenSongImport(SongImport):
else:
log.warn(u'No verse order available for %s, skipping.',
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:
if tag[0].isdigit():
# Assume it's a verse if it has no prefix

View File

@ -50,6 +50,7 @@ class SongImport(QtCore.QObject):
``manager``
An instance of a SongManager, through which all database access is
performed.
"""
self.manager = manager
self.stop_import_flag = False
@ -199,7 +200,7 @@ class SongImport(QtCore.QObject):
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
order.
@ -212,6 +213,7 @@ class SongImport(QtCore.QObject):
``lang``
The language code (ISO-639) of the verse, for example *en* or *de*.
"""
for (oldversetag, oldverse, oldlang) in self.verses:
if oldverse.strip() == versetext.strip():

View File

@ -26,7 +26,7 @@
"""
The :mod:`xml` module provides the XML functionality.
The basic XML for storing the lyrics in the song database is of the format::
The basic XML for storing the lyrics in the song database looks like this::
<?xml version="1.0" encoding="UTF-8"?>
<song version="1.0">
@ -38,7 +38,7 @@ The basic XML for storing the lyrics in the song database is of the format::
</song>
The XML of `OpenLyrics <http://openlyrics.info/>`_ songs is of the format::
The XML of an `OpenLyrics <http://openlyrics.info/>`_ song looks like this::
<song xmlns="http://openlyrics.info/namespace/2009/song"
version="0.7"
@ -60,6 +60,7 @@ The XML of `OpenLyrics <http://openlyrics.info/>`_ songs is of the format::
</song>
"""
import datetime
import logging
import re
@ -86,11 +87,13 @@ class SongXML(object):
def add_verse_to_lyrics(self, type, number, content, lang=None):
"""
Add a verse to the *<lyrics>* tag.
Add a verse to the ``<lyrics>`` tag.
``type``
A string denoting the type of verse. Possible values are "V",
"C", "B", "P", "I", "E" and "O".
A string denoting the type of verse. Possible values are *Verse*,
*Chorus*, *Bridge*, *Pre-Chorus*, *Intro*, *Ending* and *Other*.
Any other type is **not** allowed, this also includes translated
types.
``number``
An integer denoting the number of the item, for example: verse 1.
@ -126,8 +129,8 @@ class SongXML(object):
The returned list has the following format::
[[{'lang': 'en', 'type': 'V', 'label': '1'}, u"The English verse."],
[{'lang': 'en', 'type': 'C', 'label': '1'}, u"The English chorus."]]
[[{'lang': 'en', 'type': 'Verse', 'label': '1'}, u"English verse"],
[{'lang': 'en', 'type': 'Chorus', 'label': '1'}, u"English chorus"]]
"""
self.song_xml = None
if xml[:5] == u'<?xml':
@ -158,60 +161,63 @@ class OpenLyrics(object):
to/from a song.
As OpenLyrics has a rich set of different features, we cannot support them
all. The following features are supported by the :class:`OpenLyrics`::
all. The following features are supported by the :class:`OpenLyrics` class:
*<authors>*
``<authors>``
OpenLP does not support the attribute *type* and *lang*.
*<chord>*
``<chord>``
This property is not supported.
*<comments>*
The *<comments>* property is fully supported. But comments in lyrics
``<comments>``
The ``<comments>`` property is fully supported. But comments in lyrics
are not supported.
*<copyright>*
``<copyright>``
This property is fully supported.
*<customVersion>*
``<customVersion>``
This property is not supported.
*<key>*
``<key>``
This property is not supported.
*<keywords>*
``<keywords>``
This property is not supported.
*<lines>*
``<lines>``
The attribute *part* is not supported.
*<publisher>*
``<publisher>``
This property is not supported.
*<songbooks>*
``<songbooks>``
As OpenLP does only support one songbook, we cannot consider more than
one songbook.
*<tempo>*
``<tempo>``
This property is not supported.
*<themes>*
``<themes>``
Topics, as they are called in OpenLP, are fully supported, whereby only
the topic text (e. g. Grace) is considered, but neither the *id* nor
*lang*.
*<transposition>*
``<transposition>``
This property is not supported.
*<variant>*
``<variant>``
This property is not supported.
*<verse name="v1a" lang="he" translit="en">*
The attribute *translit* is not supported.
``<verse name="v1a" lang="he" translit="en">``
The attribute *translit* is not supported. Note, the attribute *lang* is
considered, but there is not further functionality implemented yet.
*<verseOrder>*
``<verseOrder>``
OpenLP supports this property.
"""
IMPLEMENTED_VERSION = u'0.7'
def __init__(self, manager):
self.manager = manager
@ -221,8 +227,14 @@ class OpenLyrics(object):
"""
sxml = SongXML()
verse_list = sxml.get_verses(song.lyrics)
song_xml = objectify.fromstring(
u'<song version="0.7" createdIn="OpenLP 2.0"/>')
song_xml = objectify.fromstring(u'<song/>')
# Append the necessary meta data to the song.
song_xml.set(u'xmlns', u'http://openlyrics.info/namespace/2009/song')
song_xml.set(u'version', OpenLyrics.IMPLEMENTED_VERSION)
song_xml.set(u'createdIn', u'OpenLP 1.9.4') # Use variable
song_xml.set(u'modifiedIn', u'OpenLP 1.9.4') # Use variable
song_xml.set(u'modifiedDate',
datetime.datetime.now().strftime(u'%Y-%m-%dT%H:%M:%S'))
properties = etree.SubElement(song_xml, u'properties')
titles = etree.SubElement(properties, u'titles')
self._add_text_to_element(u'title', titles, song.title.strip())
@ -236,7 +248,7 @@ class OpenLyrics(object):
self._add_text_to_element(u'copyright', properties, song.copyright)
if song.verse_order:
self._add_text_to_element(
u'verseOrder', properties, song.verse_order)
u'verseOrder', properties, song.verse_order.lower())
if song.ccli_number:
self._add_text_to_element(u'ccliNo', properties, song.ccli_number)
if song.authors:
@ -262,6 +274,8 @@ class OpenLyrics(object):
verse[0][u'type'][0].lower(), verse[0][u'label'])
element = \
self._add_text_to_element(u'verse', lyrics, None, verse_tag)
if verse[0].has_key(u'lang'):
element.set(u'lang', verse[0][u'lang'])
element = self._add_text_to_element(u'lines', element)
for line in unicode(verse[1]).split(u'\n'):
self._add_text_to_element(u'line', element, line)
@ -449,7 +463,7 @@ class OpenLyrics(object):
text += u'\n'
text += u'\n'.join([unicode(line) for line in lines.line])
verse_name = self._get(verse, u'name')
verse_type = unicode(VerseType.to_string(verse_name[0]))[0]
verse_type = unicode(VerseType.to_string(verse_name[0]))
verse_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_name)
verse_part = re.compile(u'[0-9]*').sub(u'', verse_name[1:])
# OpenLyrics allows e. g. "c", but we need "c1".
@ -477,9 +491,9 @@ class OpenLyrics(object):
for name in temp_verse_order:
if name[0] == previous_type:
if name[1] != previous_number:
verse_order.append(u''.join((name[0], name[1])))
verse_order.append(u''.join((name[0][0], name[1])))
else:
verse_order.append(u''.join((name[0], name[1])))
verse_order.append(u''.join((name[0][0], name[1])))
previous_type = name[0]
previous_number = name[1]
previous_part = name[2]

View File

@ -31,6 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.db import Manager
from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.lib import SongMediaItem, SongsTab, SongXML
from openlp.plugins.songs.lib.db import init_schema, Song
from openlp.plugins.songs.lib.importer import SongFormat
@ -106,8 +107,17 @@ class SongsPlugin(Plugin):
The actual **Export** menu item, so that your actions can
use it as their parent.
"""
# No menu items for now.
pass
# Main song import menu item - will eventually be the only one
self.SongExportItem = QtGui.QAction(export_menu)
self.SongExportItem.setObjectName(u'SongExportItem')
self.SongExportItem.setText(translate(
'SongsPlugin', '&Song'))
self.SongExportItem.setToolTip(translate('SongsPlugin',
'Exports songs using the export wizard.'))
export_menu.addAction(self.SongExportItem)
# Signals and slots
QtCore.QObject.connect(self.SongExportItem,
QtCore.SIGNAL(u'triggered()'), self.onSongExportItemClicked)
def addToolsMenuItem(self, tools_menu):
"""
@ -172,6 +182,10 @@ class SongsPlugin(Plugin):
if self.mediaItem:
self.mediaItem.onImportClick()
def onSongExportItemClicked(self):
if self.mediaItem:
self.mediaItem.onExportClick()
def about(self):
about_text = translate('SongsPlugin', '<strong>Songs Plugin</strong>'
'<br />The songs plugin provides the ability to display and '
@ -225,42 +239,7 @@ class SongsPlugin(Plugin):
u'title': translate('SongsPlugin', 'Songs', 'container title')
}
# Middle Header Bar
## New Action ##
self.textStrings[StringContent.New] = {
u'title': translate('SongsPlugin', 'Add'),
u'tooltip': translate('SongsPlugin',
'Add a new Song')
}
## Edit Action ##
self.textStrings[StringContent.Edit] = {
u'title': translate('SongsPlugin', 'Edit'),
u'tooltip': translate('SongsPlugin',
'Edit the selected Song')
}
## Delete Action ##
self.textStrings[StringContent.Delete] = {
u'title': translate('SongsPlugin', 'Delete'),
u'tooltip': translate('SongsPlugin',
'Delete the selected Song')
}
## Preview Action ##
self.textStrings[StringContent.Preview] = {
u'title': translate('SongsPlugin', 'Preview'),
u'tooltip': translate('SongsPlugin',
'Preview the selected Song')
}
## Send Live Action ##
self.textStrings[StringContent.Live] = {
u'title': translate('SongsPlugin', 'Live'),
u'tooltip': translate('SongsPlugin',
'Send the selected Song live')
}
## Add to Service Action ##
self.textStrings[StringContent.Service] = {
u'title': translate('SongsPlugin', 'Service'),
u'tooltip': translate('SongsPlugin',
'Add the selected Song to the service')
}
Plugin.setPluginTextStrings(self)
def finalise(self):
"""

View File

@ -1,241 +0,0 @@
<ui version="4.0" >
<class>SongExportDialog</class>
<widget class="QDialog" name="SongExportDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>641</width>
<height>607</height>
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="SongExportLayout" >
<property name="spacing" >
<number>8</number>
</property>
<property name="margin" >
<number>8</number>
</property>
<item>
<widget class="QWidget" native="1" name="SongListsWidget" >
<layout class="QHBoxLayout" name="SongListsLayout" >
<property name="spacing" >
<number>8</number>
</property>
<property name="margin" >
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="AvailableGroupBox" >
<property name="title" >
<string>Available Songs</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QListWidget" name="AvailableListWidget" />
</item>
<item>
<widget class="QToolButton" name="AvailableAllToolButton" >
<property name="text" >
<string>Select All</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" native="1" name="SelectionWidget" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize" >
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<layout class="QVBoxLayout" name="SelectionLayout" >
<property name="spacing" >
<number>8</number>
</property>
<property name="sizeConstraint" >
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="margin" >
<number>0</number>
</property>
<item>
<spacer name="TopVerticalSpacer" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>132</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="SelectToolButton" >
<property name="text" >
<string>Select Songs</string>
</property>
<property name="icon" >
<iconset resource="../images/openlp-2.qrc" >
<normaloff>:/exports/export_move_to_list.png</normaloff>:/exports/export_move_to_list.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="DeselectToolButton" >
<property name="text" >
<string>Deselect Songs</string>
</property>
<property name="icon" >
<iconset resource="../images/openlp-2.qrc" >
<normaloff>:/exports/export_remove.png</normaloff>:/exports/export_remove.png</iconset>
</property>
<property name="iconSize" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="BottomVerticalSpacer" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>131</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="SelectedGroupBox" >
<property name="title" >
<string>Selected Songs</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<item>
<widget class="QListWidget" name="SelectedListWidget" />
</item>
<item>
<widget class="QToolButton" name="SelectedAllToolButton" >
<property name="text" >
<string>Select All</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTabWidget" name="ExportTabWidget" >
<property name="currentIndex" >
<number>0</number>
</property>
<widget class="QWidget" name="OpenLyricTab" >
<attribute name="title" >
<string>OpenLyric Format</string>
</attribute>
</widget>
<widget class="QWidget" name="TextFileTab" >
<attribute name="title" >
<string>Text File</string>
</attribute>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="SongExportButtonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>SongExportButtonBox</tabstop>
<tabstop>AvailableListWidget</tabstop>
<tabstop>AvailableAllToolButton</tabstop>
<tabstop>SelectToolButton</tabstop>
<tabstop>DeselectToolButton</tabstop>
<tabstop>SelectedListWidget</tabstop>
<tabstop>SelectedAllToolButton</tabstop>
<tabstop>ExportTabWidget</tabstop>
</tabstops>
<resources>
<include location="../images/openlp-2.qrc" />
</resources>
<connections>
<connection>
<sender>SongExportButtonBox</sender>
<signal>accepted()</signal>
<receiver>SongExportDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>SongExportButtonBox</sender>
<signal>rejected()</signal>
<receiver>SongExportDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 784 B

View File

@ -80,12 +80,10 @@
<file>import_load.png</file>
</qresource>
<qresource prefix="exports">
<file>export_selectall.png</file>
<file>export_remove.png</file>
<file>export_load.png</file>
<file>export_move_to_list.png</file>
</qresource>
<qresource prefix="wizards">
<file>wizard_exportsong.bmp</file>
<file>wizard_importsong.bmp</file>
<file>wizard_importbible.bmp</file>
<file>wizard_createtheme.bmp</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB