r1287
@ -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 #
|
||||||
|
@ -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:
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
.. _openlp:
|
|
||||||
|
|
||||||
:mod:`openlp` Module
|
|
||||||
====================
|
|
||||||
|
|
||||||
.. automodule:: openlp
|
|
||||||
:members:
|
|
@ -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
|
||||||
|
@ -48,7 +48,7 @@ copyright = u'2004-2010 Raoul Snyman'
|
|||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '2.0'
|
version = '2.0'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '1.9.3'
|
release = '1.9.5'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
@ -92,22 +92,24 @@ pygments_style = 'sphinx'
|
|||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||||
|
#html_theme = 'openlp_qthelp'
|
||||||
html_theme = 'default'
|
html_theme = 'default'
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
# further. For a list of options available for each theme, see the
|
# further. For a list of options available for each theme, see the
|
||||||
# documentation.
|
# documentation.
|
||||||
html_theme_options = {
|
if html_theme == 'default':
|
||||||
'sidebarbgcolor': '#3a60a9',
|
html_theme_options = {
|
||||||
'relbarbgcolor': '#203b6f',
|
'sidebarbgcolor': '#3a60a9',
|
||||||
'footerbgcolor': '#26437c',
|
'relbarbgcolor': '#203b6f',
|
||||||
'headtextcolor': '#203b6f',
|
'footerbgcolor': '#26437c',
|
||||||
'linkcolor': '#26437c',
|
'headtextcolor': '#203b6f',
|
||||||
'sidebarlinkcolor': '#ceceff'
|
'linkcolor': '#26437c',
|
||||||
}
|
'sidebarlinkcolor': '#ceceff'
|
||||||
|
}
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory.
|
# Add any paths that contain custom themes here, relative to this directory.
|
||||||
#html_theme_path = []
|
html_theme_path = [u'../themes']
|
||||||
|
|
||||||
# The name for this set of Sphinx documents. If None, it defaults to
|
# The name for this set of Sphinx documents. If None, it defaults to
|
||||||
# "<project> v<release> documentation".
|
# "<project> v<release> documentation".
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -17,10 +17,3 @@ Contents:
|
|||||||
mediamanager
|
mediamanager
|
||||||
songs
|
songs
|
||||||
|
|
||||||
Indices and tables
|
|
||||||
==================
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
||||||
* :ref:`modindex`
|
|
||||||
* :ref:`search`
|
|
||||||
|
|
||||||
|
68
documentation/manual/themes/openlp_qthelp/layout.html
Normal 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 %}
|
||||||
|
«  <a href="{{ prev.link|e }}">{{ prev.title }}</a>
|
||||||
|
  ::  
|
||||||
|
{%- endif %}
|
||||||
|
<a class="uplink" href="{{ pathto(master_doc) }}">{{ _('Contents') }}</a>
|
||||||
|
{%- if next %}
|
||||||
|
  ::  
|
||||||
|
<a href="{{ next.link|e }}">{{ next.title }}</a>  »
|
||||||
|
{%- 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 %}
|
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
BIN
documentation/manual/themes/openlp_qthelp/static/bg-page.png
Normal file
After Width: | Height: | Size: 164 B |
After Width: | Height: | Size: 365 B |
@ -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;
|
||||||
|
}
|
12
documentation/manual/themes/openlp_qthelp/theme.conf
Normal 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
|
@ -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__)
|
||||||
|
|
||||||
@ -323,4 +324,33 @@ class Plugin(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
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']}
|
||||||
|
@ -34,6 +34,43 @@ 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 & 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):
|
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.
|
||||||
@ -98,13 +135,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 +170,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,
|
||||||
|
@ -71,38 +71,45 @@ class Theme(object):
|
|||||||
Theme name
|
Theme name
|
||||||
|
|
||||||
``BackgroundMode``
|
``BackgroundMode``
|
||||||
The behaviour of the background. Valid modes are:
|
The behaviour of the background. Valid modes are:
|
||||||
- 0 - Transparent
|
|
||||||
- 1 - Opaque
|
* ``0`` - Transparent
|
||||||
|
* ``1`` - Opaque
|
||||||
|
|
||||||
``BackgroundType``
|
``BackgroundType``
|
||||||
The content of the background. Valid types are:
|
The content of the background. Valid types are:
|
||||||
- 0 - solid color
|
|
||||||
- 1 - gradient color
|
* ``0`` - solid color
|
||||||
- 2 - image
|
* ``1`` - gradient color
|
||||||
|
* ``2`` - image
|
||||||
|
|
||||||
``BackgroundParameter1``
|
``BackgroundParameter1``
|
||||||
Extra information about the background. The contents of this attribute
|
Extra information about the background. The contents of this attribute
|
||||||
depend on the BackgroundType:
|
depend on the BackgroundType:
|
||||||
- image: image filename
|
|
||||||
- gradient: start color
|
* ``image`` - image filename
|
||||||
- solid: color
|
* ``gradient`` - start color
|
||||||
|
* ``solid`` - color
|
||||||
|
|
||||||
``BackgroundParameter2``
|
``BackgroundParameter2``
|
||||||
Extra information about the background. The contents of this attribute
|
Extra information about the background. The contents of this attribute
|
||||||
depend on the BackgroundType:
|
depend on the BackgroundType:
|
||||||
- image: border color
|
|
||||||
- gradient: end color
|
* ``image`` - border color
|
||||||
- solid: N/A
|
* ``gradient`` - end color
|
||||||
|
* ``solid`` - N/A
|
||||||
|
|
||||||
``BackgroundParameter3``
|
``BackgroundParameter3``
|
||||||
Extra information about the background. The contents of this attribute
|
Extra information about the background. The contents of this attribute
|
||||||
depend on the BackgroundType:
|
depend on the BackgroundType:
|
||||||
- image: N/A
|
|
||||||
- gradient: The direction of the gradient. Valid entries are:
|
* ``image`` - N/A
|
||||||
- 0 -> vertical
|
* ``gradient`` - The direction of the gradient. Valid entries are:
|
||||||
- 1 -> horizontal
|
|
||||||
- solid: N/A
|
* ``0`` - vertical
|
||||||
|
* ``1`` - horizontal
|
||||||
|
|
||||||
|
* ``solid`` - N/A
|
||||||
|
|
||||||
``FontName``
|
``FontName``
|
||||||
Name of the font to use for the main font.
|
Name of the font to use for the main font.
|
||||||
@ -118,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):
|
||||||
"""
|
"""
|
||||||
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
@ -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 '
|
||||||
|
@ -34,7 +34,7 @@ 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):
|
||||||
"""
|
"""
|
||||||
@ -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'))
|
||||||
|
@ -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
|
||||||
@ -215,6 +216,9 @@ 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.ToolsOpenDataFolder = icon_action(mainWindow, u'ToolsOpenDataFolder',
|
||||||
|
u':/general/general_open.png')
|
||||||
|
mainWindow.actionList.add_action(self.ToolsOpenDataFolder, u'Tools')
|
||||||
self.settingsPluginListItem = icon_action(mainWindow,
|
self.settingsPluginListItem = icon_action(mainWindow,
|
||||||
u'settingsPluginListItem', u':/system/settings_plugin_list.png')
|
u'settingsPluginListItem', u':/system/settings_plugin_list.png')
|
||||||
mainWindow.actionList.add_action(self.settingsPluginListItem,
|
mainWindow.actionList.add_action(self.settingsPluginListItem,
|
||||||
@ -275,6 +279,7 @@ class Ui_MainWindow(object):
|
|||||||
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))
|
||||||
@ -295,7 +300,7 @@ 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'))
|
||||||
@ -432,6 +437,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',
|
||||||
@ -514,6 +523,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
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.ToolsOpenDataFolder,
|
||||||
|
QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked)
|
||||||
QtCore.QObject.connect(self.settingsPluginListItem,
|
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,
|
||||||
@ -702,6 +713,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
|
||||||
|
@ -461,7 +461,7 @@ 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,
|
||||||
|
@ -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__)
|
||||||
@ -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'),
|
||||||
|
@ -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,7 @@ 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 = '%s;;%s (*.*) (*)' % (images_filter, UiStrings.AllFiles)
|
||||||
translate('OpenLP.ThemeForm', 'All Files'))
|
|
||||||
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)
|
||||||
|
@ -35,7 +35,7 @@ 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
|
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, \
|
||||||
@ -62,28 +62,28 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self.layout.setObjectName(u'layout')
|
self.layout.setObjectName(u'layout')
|
||||||
self.toolbar = OpenLPToolbar(self)
|
self.toolbar = OpenLPToolbar(self)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
translate('OpenLP.ThemeManager', 'New Theme'),
|
UiStrings.NewType % UiStrings.Theme,
|
||||||
u':/themes/theme_new.png',
|
u':/themes/theme_new.png',
|
||||||
translate('OpenLP.ThemeManager', 'Create a new theme.'),
|
translate('OpenLP.ThemeManager', 'Create a new theme.'),
|
||||||
self.onAddTheme)
|
self.onAddTheme)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
translate('OpenLP.ThemeManager', 'Edit Theme'),
|
UiStrings.EditType % UiStrings.Theme,
|
||||||
u':/themes/theme_edit.png',
|
u':/themes/theme_edit.png',
|
||||||
translate('OpenLP.ThemeManager', 'Edit a theme.'),
|
translate('OpenLP.ThemeManager', 'Edit a theme.'),
|
||||||
self.onEditTheme)
|
self.onEditTheme)
|
||||||
self.deleteToolbarAction = self.toolbar.addToolbarButton(
|
self.deleteToolbarAction = self.toolbar.addToolbarButton(
|
||||||
translate('OpenLP.ThemeManager', 'Delete Theme'),
|
UiStrings.DeleteType % UiStrings.Theme,
|
||||||
u':/general/general_delete.png',
|
u':/general/general_delete.png',
|
||||||
translate('OpenLP.ThemeManager', 'Delete a theme.'),
|
translate('OpenLP.ThemeManager', 'Delete a theme.'),
|
||||||
self.onDeleteTheme)
|
self.onDeleteTheme)
|
||||||
self.toolbar.addSeparator()
|
self.toolbar.addSeparator()
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
translate('OpenLP.ThemeManager', 'Import Theme'),
|
UiStrings.ImportType % UiStrings.Theme,
|
||||||
u':/general/general_import.png',
|
u':/general/general_import.png',
|
||||||
translate('OpenLP.ThemeManager', 'Import a theme.'),
|
translate('OpenLP.ThemeManager', 'Import a theme.'),
|
||||||
self.onImportTheme)
|
self.onImportTheme)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
translate('OpenLP.ThemeManager', 'Export Theme'),
|
UiStrings.ExportType % UiStrings.Theme,
|
||||||
u':/general/general_export.png',
|
u':/general/general_export.png',
|
||||||
translate('OpenLP.ThemeManager', 'Export a theme.'),
|
translate('OpenLP.ThemeManager', 'Export a theme.'),
|
||||||
self.onExportTheme)
|
self.onExportTheme)
|
||||||
|
@ -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(
|
||||||
|
@ -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
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
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 create_valign_combo
|
from openlp.core.lib.ui import UiStrings, create_valign_combo
|
||||||
|
|
||||||
class AlertsTab(SettingsTab):
|
class AlertsTab(SettingsTab):
|
||||||
"""
|
"""
|
||||||
@ -117,10 +117,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.PreviewGroupBox.setTitle(
|
self.PreviewGroupBox.setTitle(UiStrings.Preview)
|
||||||
translate('AlertsPlugin.AlertsTab', 'Preview'))
|
self.FontPreview.setText(UiStrings.OLPV2)
|
||||||
self.FontPreview.setText(
|
|
||||||
translate('AlertsPlugin.AlertsTab', 'OpenLP 2.0'))
|
|
||||||
|
|
||||||
def onBackgroundColorButtonClicked(self):
|
def onBackgroundColorButtonClicked(self):
|
||||||
new_color = QtGui.QColorDialog.getColor(
|
new_color = QtGui.QColorDialog.getColor(
|
||||||
|
@ -29,6 +29,7 @@ import logging
|
|||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
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
|
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -137,38 +138,7 @@ class BiblePlugin(Plugin):
|
|||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
## Import Action ##
|
## Import Action ##
|
||||||
self.textStrings[StringContent.Import] = {
|
self.textStrings[StringContent.Import] = {
|
||||||
u'title': translate('BiblesPlugin', '&Import'),
|
u'title': UiStrings.Import,
|
||||||
u'tooltip': translate('BiblesPlugin', 'Import a Bible')
|
u'tooltip': translate('BiblesPlugin', 'Import a Bible')
|
||||||
}
|
}
|
||||||
## New Action ##
|
Plugin.setPluginTextStrings(self)
|
||||||
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')
|
|
||||||
}
|
|
||||||
|
@ -35,7 +35,7 @@ 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.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 UiStrings, critical_error_message_box
|
||||||
from openlp.core.ui.wizard import OpenLPWizard
|
from openlp.core.ui.wizard import OpenLPWizard
|
||||||
from openlp.core.utils import AppLocation, string_is_unicode
|
from openlp.core.utils import AppLocation, string_is_unicode
|
||||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||||
@ -745,8 +745,7 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
"""
|
"""
|
||||||
if filters:
|
if filters:
|
||||||
filters += u';;'
|
filters += u';;'
|
||||||
filters += u'%s (*)' % translate('BiblesPlugin.ImportWizardForm',
|
filters += u'%s (*)' % UiStrings.AllFiles
|
||||||
'All Files')
|
|
||||||
filename = QtGui.QFileDialog.getOpenFileName(self, title,
|
filename = QtGui.QFileDialog.getOpenFileName(self, title,
|
||||||
os.path.dirname(SettingsManager.get_last_dir(
|
os.path.dirname(SettingsManager.get_last_dir(
|
||||||
self.plugin.settingsSection, 1)), filters)
|
self.plugin.settingsSection, 1)), filters)
|
||||||
|
@ -69,69 +69,90 @@ def get_reference_match(match_type):
|
|||||||
def parse_reference(reference):
|
def parse_reference(reference):
|
||||||
"""
|
"""
|
||||||
This is the next generation über-awesome function that takes a person's
|
This is the next generation über-awesome function that takes a person's
|
||||||
typed in string and converts it to a reference list, a list of references to
|
typed in string and converts it to a list of references to be queried from
|
||||||
be queried from the Bible database files.
|
the Bible database files.
|
||||||
|
|
||||||
This is a user manual like description, how the references are working.
|
``reference``
|
||||||
|
A string. The Bible reference to parse.
|
||||||
|
|
||||||
- Each reference starts with the book name. A chapter name is manditory.
|
Returns ``None`` or a reference list.
|
||||||
``John 3`` refers to Gospel of John chapter 3
|
|
||||||
- A reference range can be given after a range separator.
|
|
||||||
``John 3-5`` refers to John chapters 3 to 5
|
|
||||||
- Single verses can be addressed after a verse separator
|
|
||||||
``John 3:16`` refers to John chapter 3 verse 16
|
|
||||||
``John 3:16-4:3`` refers to John chapter 3 verse 16 to chapter 4 verse 3
|
|
||||||
- After a verse reference all further single values are treat as verse in
|
|
||||||
the last selected chapter.
|
|
||||||
``John 3:16-18`` refers to John chapter 3 verses 16 to 18
|
|
||||||
- After a list separator it is possible to refer to additional verses. They
|
|
||||||
are build analog to the first ones. This way it is possible to define each
|
|
||||||
number of verse references. It is not possible to refer to verses in
|
|
||||||
additional books.
|
|
||||||
``John 3:16,18`` refers to John chapter 3 verses 16 and 18
|
|
||||||
``John 3:16-18,20`` refers to John chapter 3 verses 16 to 18 and 20
|
|
||||||
``John 3:16-18,4:1`` refers to John chapter 3 verses 16 to 18 and
|
|
||||||
chapter 3 verse 1
|
|
||||||
- If there is a range separator without further verse declaration the last
|
|
||||||
refered chapter is addressed until the end.
|
|
||||||
|
|
||||||
``range_string`` is a regular expression which matches for verse range
|
|
||||||
declarations:
|
|
||||||
|
|
||||||
1. ``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?``
|
|
||||||
It starts with a optional chapter reference ``from_chapter`` followed by
|
|
||||||
a verse separator.
|
|
||||||
2. ``(?P<from_verse>[0-9]+)``
|
|
||||||
The verse reference ``from_verse`` is manditory
|
|
||||||
3. ``(?P<range_to>%(sep_r)s(?:`` ... ``|%(sep_e)s)?)?``
|
|
||||||
A ``range_to`` declaration is optional. It starts with a range separator
|
|
||||||
and contains optional a chapter and verse declaration or a end
|
|
||||||
separator.
|
|
||||||
4. ``(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?``
|
|
||||||
The ``to_chapter`` reference with separator is equivalent to group 1.
|
|
||||||
5. ``(?P<to_verse>[0-9]+)``
|
|
||||||
The ``to_verse`` reference is equivalent to group 2.
|
|
||||||
|
|
||||||
The full reference is matched against get_reference_match(u'full'). This
|
|
||||||
regular expression looks like this:
|
|
||||||
|
|
||||||
1. ``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*``
|
|
||||||
The ``book`` group starts with the first non-whitespace character. There
|
|
||||||
are optional leading digits followed by non-digits. The group ends
|
|
||||||
before the whitspace in front of the next digit.
|
|
||||||
2. ``(?P<ranges>(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$``
|
|
||||||
The second group contains all ``ranges``. This can be multiple
|
|
||||||
declarations of a range_string separated by a list separator.
|
|
||||||
|
|
||||||
The reference list is a list of tuples, with each tuple structured like
|
The reference list is a list of tuples, with each tuple structured like
|
||||||
this::
|
this::
|
||||||
|
|
||||||
(book, chapter, from_verse, to_verse)
|
(book, chapter, from_verse, to_verse)
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
[(u'John', 3, 16, 18), (u'John', 4, 1, 1)]
|
||||||
|
|
||||||
``reference``
|
**Reference string details:**
|
||||||
The bible reference to parse.
|
|
||||||
|
Each reference starts with the book name and a chapter number. These are
|
||||||
|
both mandatory.
|
||||||
|
|
||||||
|
* ``John 3`` refers to Gospel of John chapter 3
|
||||||
|
|
||||||
|
A reference range can be given after a range separator.
|
||||||
|
|
||||||
|
* ``John 3-5`` refers to John chapters 3 to 5
|
||||||
|
|
||||||
|
Single verses can be addressed after a verse separator.
|
||||||
|
|
||||||
|
* ``John 3:16`` refers to John chapter 3 verse 16
|
||||||
|
* ``John 3:16-4:3`` refers to John chapter 3 verse 16 to chapter 4 verse 3
|
||||||
|
|
||||||
|
After a verse reference all further single values are treat as verse in
|
||||||
|
the last selected chapter.
|
||||||
|
|
||||||
|
* ``John 3:16-18`` refers to John chapter 3 verses 16 to 18
|
||||||
|
|
||||||
|
After a list separator it is possible to refer to additional verses. They
|
||||||
|
are build analog to the first ones. This way it is possible to define each
|
||||||
|
number of verse references. It is not possible to refer to verses in
|
||||||
|
additional books.
|
||||||
|
|
||||||
|
* ``John 3:16,18`` refers to John chapter 3 verses 16 and 18
|
||||||
|
* ``John 3:16-18,20`` refers to John chapter 3 verses 16 to 18 and 20
|
||||||
|
* ``John 3:16-18,4:1`` refers to John chapter 3 verses 16 to 18 and
|
||||||
|
chapter 4 verse 1
|
||||||
|
|
||||||
|
If there is a range separator without further verse declaration the last
|
||||||
|
refered chapter is addressed until the end.
|
||||||
|
|
||||||
|
``range_string`` is a regular expression which matches for verse range
|
||||||
|
declarations:
|
||||||
|
|
||||||
|
``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?``
|
||||||
|
It starts with a optional chapter reference ``from_chapter`` followed by
|
||||||
|
a verse separator.
|
||||||
|
|
||||||
|
``(?P<from_verse>[0-9]+)``
|
||||||
|
The verse reference ``from_verse`` is manditory
|
||||||
|
|
||||||
|
``(?P<range_to>%(sep_r)s(?:`` ... ``|%(sep_e)s)?)?``
|
||||||
|
A ``range_to`` declaration is optional. It starts with a range separator
|
||||||
|
and contains optional a chapter and verse declaration or a end
|
||||||
|
separator.
|
||||||
|
|
||||||
|
``(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?``
|
||||||
|
The ``to_chapter`` reference with separator is equivalent to group 1.
|
||||||
|
|
||||||
|
``(?P<to_verse>[0-9]+)``
|
||||||
|
The ``to_verse`` reference is equivalent to group 2.
|
||||||
|
|
||||||
|
The full reference is matched against get_reference_match(u'full'). This
|
||||||
|
regular expression looks like this:
|
||||||
|
|
||||||
|
``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*``
|
||||||
|
The ``book`` group starts with the first non-whitespace character. There
|
||||||
|
are optional leading digits followed by non-digits. The group ends
|
||||||
|
before the whitspace in front of the next digit.
|
||||||
|
|
||||||
|
``(?P<ranges>(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$``
|
||||||
|
The second group contains all ``ranges``. This can be multiple
|
||||||
|
declarations of a range_string separated by a list separator.
|
||||||
|
|
||||||
Returns None or a reference list.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'parse_reference("%s")', reference)
|
log.debug(u'parse_reference("%s")', reference)
|
||||||
match = get_reference_match(u'full').match(reference)
|
match = get_reference_match(u'full').match(reference)
|
||||||
@ -201,7 +222,7 @@ def parse_reference(reference):
|
|||||||
|
|
||||||
class SearchResults(object):
|
class SearchResults(object):
|
||||||
"""
|
"""
|
||||||
Encapsulate a set of search results. This is Bible-type independent.
|
Encapsulate a set of search results. This is Bible-type independent.
|
||||||
"""
|
"""
|
||||||
def __init__(self, book, chapter, verselist):
|
def __init__(self, book, chapter, verselist):
|
||||||
"""
|
"""
|
||||||
@ -214,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
|
||||||
|
@ -30,6 +30,7 @@ from forms import EditCustomForm
|
|||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||||
from openlp.core.lib.db import Manager
|
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 import CustomMediaItem, CustomTab
|
||||||
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
|
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
|
||||||
|
|
||||||
@ -114,52 +115,11 @@ class CustomPlugin(Plugin):
|
|||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
## Import Action ##
|
## Import Action ##
|
||||||
self.textStrings[StringContent.Import] = {
|
self.textStrings[StringContent.Import] = {
|
||||||
u'title': translate('CustomsPlugin', 'Import'),
|
u'title': UiStrings.Import,
|
||||||
u'tooltip': translate('CustomsPlugin',
|
u'tooltip': translate('CustomsPlugin',
|
||||||
'Import a Custom')
|
'Import a Custom')
|
||||||
}
|
}
|
||||||
## Load Action ##
|
Plugin.setPluginTextStrings(self)
|
||||||
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')
|
|
||||||
}
|
|
||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
"""
|
"""
|
||||||
|
@ -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_save_cancel_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):
|
||||||
@ -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.'))
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||||
|
from openlp.core.lib.ui import UiStrings
|
||||||
from openlp.plugins.images.lib import ImageMediaItem
|
from openlp.plugins.images.lib import ImageMediaItem
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -72,45 +73,4 @@ 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 ##
|
Plugin.setPluginTextStrings(self)
|
||||||
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')
|
|
||||||
}
|
|
||||||
|
@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui
|
|||||||
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
||||||
ItemCapabilities, SettingsManager, translate, check_item_selected, \
|
ItemCapabilities, SettingsManager, translate, check_item_selected, \
|
||||||
check_directory_exists, Receiver
|
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
|
from openlp.core.utils import AppLocation, delete_file, get_images_filter
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -64,7 +64,7 @@ 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')))
|
unicode(UiStrings.AllFiles))
|
||||||
self.replaceAction.setText(
|
self.replaceAction.setText(
|
||||||
translate('ImagePlugin.MediaItem', 'Replace Background'))
|
translate('ImagePlugin.MediaItem', 'Replace Background'))
|
||||||
self.replaceAction.setToolTip(
|
self.replaceAction.setToolTip(
|
||||||
|
@ -30,6 +30,7 @@ import mimetypes
|
|||||||
from PyQt4.phonon import Phonon
|
from PyQt4.phonon import Phonon
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
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
|
from openlp.plugins.media.lib import MediaMediaItem, MediaTab
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -101,45 +102,4 @@ 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 ##
|
Plugin.setPluginTextStrings(self)
|
||||||
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')
|
|
||||||
}
|
|
||||||
|
@ -429,7 +429,7 @@ class ImpressDocument(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
|
||||||
"""
|
"""
|
||||||
return __get_text_from_slide(slide_no)
|
return self.__get_text_from_page(slide_no)
|
||||||
|
|
||||||
def get_slide_notes(self, slide_no):
|
def get_slide_notes(self, slide_no):
|
||||||
"""
|
"""
|
||||||
@ -438,7 +438,7 @@ class ImpressDocument(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_page(slide_no, True)
|
return self.__get_text_from_page(slide_no, True)
|
||||||
|
|
||||||
def __get_text_from_page(self, slide_no, notes=False):
|
def __get_text_from_page(self, slide_no, notes=False):
|
||||||
"""
|
"""
|
||||||
|
@ -31,6 +31,7 @@ import os
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
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.core.utils import AppLocation
|
||||||
from openlp.plugins.presentations.lib import PresentationController, \
|
from openlp.plugins.presentations.lib import PresentationController, \
|
||||||
PresentationMediaItem, PresentationTab
|
PresentationMediaItem, PresentationTab
|
||||||
@ -167,33 +168,4 @@ class PresentationPlugin(Plugin):
|
|||||||
'container title')
|
'container title')
|
||||||
}
|
}
|
||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
## Load Action ##
|
Plugin.setPluginTextStrings(self)
|
||||||
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')
|
|
||||||
}
|
|
||||||
|
@ -57,4 +57,6 @@ from songbookform import SongBookForm
|
|||||||
from editverseform import EditVerseForm
|
from editverseform import EditVerseForm
|
||||||
from editsongform import EditSongForm
|
from editsongform import EditSongForm
|
||||||
from songmaintenanceform import SongMaintenanceForm
|
from songmaintenanceform import SongMaintenanceForm
|
||||||
from songimportform import SongImportForm
|
from songimportform import SongImportForm
|
||||||
|
from songexportform import SongExportForm
|
||||||
|
|
||||||
|
@ -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_save_cancel_button_box
|
||||||
|
|
||||||
class Ui_EditSongDialog(object):
|
class Ui_EditSongDialog(object):
|
||||||
def setupUi(self, editSongDialog):
|
def setupUi(self, 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(
|
||||||
|
372
openlp/plugins/songs/forms/songexportform.py
Normal 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)
|
@ -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
|
||||||
|
|
||||||
@ -215,8 +215,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,
|
||||||
@ -489,8 +488,7 @@ class SongImportForm(OpenLPWizard):
|
|||||||
"""
|
"""
|
||||||
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)
|
||||||
|
@ -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))
|
||||||
|
@ -33,8 +33,9 @@ from sqlalchemy.sql import or_
|
|||||||
|
|
||||||
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \
|
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \
|
||||||
ItemCapabilities, translate, check_item_selected, PluginStatus
|
ItemCapabilities, 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
|
||||||
@ -147,10 +148,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 +265,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()
|
||||||
|
74
openlp/plugins/songs/lib/openlyricsexport.py
Executable 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
|
@ -36,6 +36,7 @@ from openlp.plugins.songs.lib.songimport import SongImport
|
|||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
#TODO: Use lxml for parsing and make sure we use methods of "SongImport" .
|
||||||
class OpenSongImport(SongImport):
|
class OpenSongImport(SongImport):
|
||||||
"""
|
"""
|
||||||
Import songs exported from OpenSong
|
Import songs exported from OpenSong
|
||||||
@ -146,7 +147,7 @@ class OpenSongImport(SongImport):
|
|||||||
log.info(u'Zip importing %s', parts[-1])
|
log.info(u'Zip importing %s', parts[-1])
|
||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
unicode(translate('SongsPlugin.ImportWizardForm',
|
unicode(translate('SongsPlugin.ImportWizardForm',
|
||||||
'Importing %s...')) % parts[-1])
|
'Importing %s...')) % parts[-1])
|
||||||
songfile = z.open(song)
|
songfile = z.open(song)
|
||||||
self.do_import_file(songfile)
|
self.do_import_file(songfile)
|
||||||
if self.commit:
|
if self.commit:
|
||||||
@ -276,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
|
||||||
@ -292,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
|
||||||
|
@ -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():
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
"""
|
"""
|
||||||
The :mod:`xml` module provides the XML functionality.
|
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"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<song version="1.0">
|
<song version="1.0">
|
||||||
@ -38,7 +38,7 @@ The basic XML for storing the lyrics in the song database is of the format::
|
|||||||
</song>
|
</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"
|
<song xmlns="http://openlyrics.info/namespace/2009/song"
|
||||||
version="0.7"
|
version="0.7"
|
||||||
@ -60,6 +60,7 @@ The XML of `OpenLyrics <http://openlyrics.info/>`_ songs is of the format::
|
|||||||
</song>
|
</song>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -86,11 +87,13 @@ class SongXML(object):
|
|||||||
|
|
||||||
def add_verse_to_lyrics(self, type, number, content, lang=None):
|
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``
|
``type``
|
||||||
A string denoting the type of verse. Possible values are "V",
|
A string denoting the type of verse. Possible values are *Verse*,
|
||||||
"C", "B", "P", "I", "E" and "O".
|
*Chorus*, *Bridge*, *Pre-Chorus*, *Intro*, *Ending* and *Other*.
|
||||||
|
Any other type is **not** allowed, this also includes translated
|
||||||
|
types.
|
||||||
|
|
||||||
``number``
|
``number``
|
||||||
An integer denoting the number of the item, for example: verse 1.
|
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::
|
The returned list has the following format::
|
||||||
|
|
||||||
[[{'lang': 'en', 'type': 'V', 'label': '1'}, u"The English verse."],
|
[[{'lang': 'en', 'type': 'Verse', 'label': '1'}, u"English verse"],
|
||||||
[{'lang': 'en', 'type': 'C', 'label': '1'}, u"The English chorus."]]
|
[{'lang': 'en', 'type': 'Chorus', 'label': '1'}, u"English chorus"]]
|
||||||
"""
|
"""
|
||||||
self.song_xml = None
|
self.song_xml = None
|
||||||
if xml[:5] == u'<?xml':
|
if xml[:5] == u'<?xml':
|
||||||
@ -158,60 +161,63 @@ class OpenLyrics(object):
|
|||||||
to/from a song.
|
to/from a song.
|
||||||
|
|
||||||
As OpenLyrics has a rich set of different features, we cannot support them
|
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*.
|
OpenLP does not support the attribute *type* and *lang*.
|
||||||
|
|
||||||
*<chord>*
|
``<chord>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
*<comments>*
|
``<comments>``
|
||||||
The *<comments>* property is fully supported. But comments in lyrics
|
The ``<comments>`` property is fully supported. But comments in lyrics
|
||||||
are not supported.
|
are not supported.
|
||||||
|
|
||||||
*<copyright>*
|
``<copyright>``
|
||||||
This property is fully supported.
|
This property is fully supported.
|
||||||
|
|
||||||
*<customVersion>*
|
``<customVersion>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
*<key>*
|
``<key>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
*<keywords>*
|
``<keywords>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
*<lines>*
|
``<lines>``
|
||||||
The attribute *part* is not supported.
|
The attribute *part* is not supported.
|
||||||
|
|
||||||
*<publisher>*
|
``<publisher>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
*<songbooks>*
|
``<songbooks>``
|
||||||
As OpenLP does only support one songbook, we cannot consider more than
|
As OpenLP does only support one songbook, we cannot consider more than
|
||||||
one songbook.
|
one songbook.
|
||||||
|
|
||||||
*<tempo>*
|
``<tempo>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
*<themes>*
|
``<themes>``
|
||||||
Topics, as they are called in OpenLP, are fully supported, whereby only
|
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
|
the topic text (e. g. Grace) is considered, but neither the *id* nor
|
||||||
*lang*.
|
*lang*.
|
||||||
|
|
||||||
*<transposition>*
|
``<transposition>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
*<variant>*
|
``<variant>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
*<verse name="v1a" lang="he" translit="en">*
|
``<verse name="v1a" lang="he" translit="en">``
|
||||||
The attribute *translit* is not supported.
|
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.
|
OpenLP supports this property.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
IMPLEMENTED_VERSION = u'0.7'
|
||||||
def __init__(self, manager):
|
def __init__(self, manager):
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
|
|
||||||
@ -221,8 +227,14 @@ class OpenLyrics(object):
|
|||||||
"""
|
"""
|
||||||
sxml = SongXML()
|
sxml = SongXML()
|
||||||
verse_list = sxml.get_verses(song.lyrics)
|
verse_list = sxml.get_verses(song.lyrics)
|
||||||
song_xml = objectify.fromstring(
|
song_xml = objectify.fromstring(u'<song/>')
|
||||||
u'<song version="0.7" createdIn="OpenLP 2.0"/>')
|
# 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')
|
properties = etree.SubElement(song_xml, u'properties')
|
||||||
titles = etree.SubElement(properties, u'titles')
|
titles = etree.SubElement(properties, u'titles')
|
||||||
self._add_text_to_element(u'title', titles, song.title.strip())
|
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)
|
self._add_text_to_element(u'copyright', properties, song.copyright)
|
||||||
if song.verse_order:
|
if song.verse_order:
|
||||||
self._add_text_to_element(
|
self._add_text_to_element(
|
||||||
u'verseOrder', properties, song.verse_order)
|
u'verseOrder', properties, song.verse_order.lower())
|
||||||
if song.ccli_number:
|
if song.ccli_number:
|
||||||
self._add_text_to_element(u'ccliNo', properties, song.ccli_number)
|
self._add_text_to_element(u'ccliNo', properties, song.ccli_number)
|
||||||
if song.authors:
|
if song.authors:
|
||||||
@ -262,6 +274,8 @@ class OpenLyrics(object):
|
|||||||
verse[0][u'type'][0].lower(), verse[0][u'label'])
|
verse[0][u'type'][0].lower(), verse[0][u'label'])
|
||||||
element = \
|
element = \
|
||||||
self._add_text_to_element(u'verse', lyrics, None, verse_tag)
|
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)
|
element = self._add_text_to_element(u'lines', element)
|
||||||
for line in unicode(verse[1]).split(u'\n'):
|
for line in unicode(verse[1]).split(u'\n'):
|
||||||
self._add_text_to_element(u'line', element, line)
|
self._add_text_to_element(u'line', element, line)
|
||||||
@ -449,7 +463,7 @@ class OpenLyrics(object):
|
|||||||
text += u'\n'
|
text += u'\n'
|
||||||
text += u'\n'.join([unicode(line) for line in lines.line])
|
text += u'\n'.join([unicode(line) for line in lines.line])
|
||||||
verse_name = self._get(verse, u'name')
|
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_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_name)
|
||||||
verse_part = re.compile(u'[0-9]*').sub(u'', verse_name[1:])
|
verse_part = re.compile(u'[0-9]*').sub(u'', verse_name[1:])
|
||||||
# OpenLyrics allows e. g. "c", but we need "c1".
|
# OpenLyrics allows e. g. "c", but we need "c1".
|
||||||
@ -477,9 +491,9 @@ class OpenLyrics(object):
|
|||||||
for name in temp_verse_order:
|
for name in temp_verse_order:
|
||||||
if name[0] == previous_type:
|
if name[0] == previous_type:
|
||||||
if name[1] != previous_number:
|
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:
|
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_type = name[0]
|
||||||
previous_number = name[1]
|
previous_number = name[1]
|
||||||
previous_part = name[2]
|
previous_part = name[2]
|
||||||
|
@ -31,6 +31,7 @@ from PyQt4 import QtCore, QtGui
|
|||||||
|
|
||||||
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
from openlp.core.lib import Plugin, StringContent, build_icon, translate
|
||||||
from openlp.core.lib.db import Manager
|
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 import SongMediaItem, SongsTab, SongXML
|
||||||
from openlp.plugins.songs.lib.db import init_schema, Song
|
from openlp.plugins.songs.lib.db import init_schema, Song
|
||||||
from openlp.plugins.songs.lib.importer import SongFormat
|
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
|
The actual **Export** menu item, so that your actions can
|
||||||
use it as their parent.
|
use it as their parent.
|
||||||
"""
|
"""
|
||||||
# No menu items for now.
|
# Main song import menu item - will eventually be the only one
|
||||||
pass
|
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):
|
def addToolsMenuItem(self, tools_menu):
|
||||||
"""
|
"""
|
||||||
@ -172,6 +182,10 @@ class SongsPlugin(Plugin):
|
|||||||
if self.mediaItem:
|
if self.mediaItem:
|
||||||
self.mediaItem.onImportClick()
|
self.mediaItem.onImportClick()
|
||||||
|
|
||||||
|
def onSongExportItemClicked(self):
|
||||||
|
if self.mediaItem:
|
||||||
|
self.mediaItem.onExportClick()
|
||||||
|
|
||||||
def about(self):
|
def about(self):
|
||||||
about_text = translate('SongsPlugin', '<strong>Songs Plugin</strong>'
|
about_text = translate('SongsPlugin', '<strong>Songs Plugin</strong>'
|
||||||
'<br />The songs plugin provides the ability to display and '
|
'<br />The songs plugin provides the ability to display and '
|
||||||
@ -225,42 +239,7 @@ class SongsPlugin(Plugin):
|
|||||||
u'title': translate('SongsPlugin', 'Songs', 'container title')
|
u'title': translate('SongsPlugin', 'Songs', 'container title')
|
||||||
}
|
}
|
||||||
# Middle Header Bar
|
# Middle Header Bar
|
||||||
## New Action ##
|
Plugin.setPluginTextStrings(self)
|
||||||
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')
|
|
||||||
}
|
|
||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
"""
|
"""
|
||||||
|
@ -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>
|
|
Before Width: | Height: | Size: 862 B |
Before Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 784 B |
@ -80,12 +80,10 @@
|
|||||||
<file>import_load.png</file>
|
<file>import_load.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="exports">
|
<qresource prefix="exports">
|
||||||
<file>export_selectall.png</file>
|
|
||||||
<file>export_remove.png</file>
|
|
||||||
<file>export_load.png</file>
|
<file>export_load.png</file>
|
||||||
<file>export_move_to_list.png</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="wizards">
|
<qresource prefix="wizards">
|
||||||
|
<file>wizard_exportsong.bmp</file>
|
||||||
<file>wizard_importsong.bmp</file>
|
<file>wizard_importsong.bmp</file>
|
||||||
<file>wizard_importbible.bmp</file>
|
<file>wizard_importbible.bmp</file>
|
||||||
<file>wizard_createtheme.bmp</file>
|
<file>wizard_createtheme.bmp</file>
|
||||||
|
BIN
resources/images/wizard_exportsong.bmp
Normal file
After Width: | Height: | Size: 168 KiB |