forked from openlp/openlp
r1305
This commit is contained in:
commit
0bcc877a41
@ -4,8 +4,8 @@
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2010 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||
# Carsten Tinggaard, Frode Woldsund #
|
||||
|
@ -1,124 +0,0 @@
|
||||
openlp.org 2.x Song Database Structure
|
||||
========================================================================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
The song database in openlp.org 2.x is similar to the 1.x format. The
|
||||
biggest differences are the addition of extra tables, and the use of
|
||||
SQLite version 3.
|
||||
|
||||
The song database contains the following tables:
|
||||
- authors
|
||||
- authors_songs
|
||||
- song_books
|
||||
- songs
|
||||
- songs_topics
|
||||
- topics
|
||||
|
||||
|
||||
"authors" Table
|
||||
---------------
|
||||
This table holds the names of all the authors. It has the following
|
||||
columns:
|
||||
|
||||
* id
|
||||
* first_name
|
||||
* last_name
|
||||
* display_name
|
||||
|
||||
|
||||
"authors_songs" Table
|
||||
---------------------
|
||||
This is a bridging table between the "authors" and "songs" tables, which
|
||||
serves to create a many-to-many relationship between the two tables. It
|
||||
has the following columns:
|
||||
|
||||
* author_id
|
||||
* song_id
|
||||
|
||||
|
||||
"song_books" Table
|
||||
------------------
|
||||
The "song_books" table holds a list of books that a congregation gets
|
||||
their songs from, or old hymnals now no longer used. This table has the
|
||||
following columns:
|
||||
|
||||
* id
|
||||
* name
|
||||
* publisher
|
||||
|
||||
|
||||
"songs" Table
|
||||
-------------
|
||||
This table contains the songs, and each song has a list of attributes.
|
||||
The "songs" table has the following columns:
|
||||
|
||||
* id
|
||||
* song_book_id
|
||||
* title
|
||||
* lyrics
|
||||
* verse_order
|
||||
* copyright
|
||||
* comments
|
||||
* ccli_number
|
||||
* song_number
|
||||
* theme_name
|
||||
* search_title
|
||||
* search_lyrics
|
||||
|
||||
|
||||
"songs_topics" Table
|
||||
--------------------
|
||||
This is a bridging table between the "songs" and "topics" tables, which
|
||||
serves to create a many-to-many relationship between the two tables. It
|
||||
has the following columns:
|
||||
|
||||
* song_id
|
||||
* topic_id
|
||||
|
||||
|
||||
"topics" Table
|
||||
--------------
|
||||
The topics table holds a selection of topics that songs can cover. This
|
||||
is useful when a worship leader wants to select songs with a certain
|
||||
theme. This table has the following columns:
|
||||
|
||||
* id
|
||||
* name
|
||||
|
||||
|
||||
The lyrics definition (more or less similar to interformat to/from ChangingSong
|
||||
The tags <i></i><b></b><u></u> can also be used within the lyrics test.
|
||||
|
||||
! Please note that this format has been checked at http://validator.w3.org/#validate_by_upload
|
||||
|
||||
<lyrics lang="en_US">
|
||||
<title>Amazing Grace</title>
|
||||
<verse name="v1">
|
||||
<theme>name of verse specific theme (optional)</theme>
|
||||
<comment>any text (optional)</comment>
|
||||
<part name="men">
|
||||
Amazing grace, how ...
|
||||
</part>
|
||||
<part name="women">
|
||||
A b c
|
||||
D e f
|
||||
</part>
|
||||
...
|
||||
</verse>
|
||||
<verse name="c">
|
||||
<theme>name of verse specific theme (optional)</theme>
|
||||
<comment>any text (optional)</comment>
|
||||
...
|
||||
</verse>
|
||||
</lyrics>
|
||||
<lyrics lang="de_DE">
|
||||
<title>Erstaunliche Anmut</title>
|
||||
<verse name="v1">
|
||||
Erstaunliche Anmut, wie
|
||||
...
|
||||
</verse>
|
||||
<verse name="c">
|
||||
...
|
||||
</verse>
|
||||
</lyrics>
|
@ -6,18 +6,18 @@ Object Library
|
||||
.. automodule:: openlp.core.lib
|
||||
:members:
|
||||
|
||||
:mod:`BaseListWithDnD`
|
||||
----------------------
|
||||
|
||||
.. autoclass:: openlp.core.lib.baselistwithdnd.BaseListWithDnD
|
||||
:members:
|
||||
|
||||
:mod:`EventReceiver`
|
||||
--------------------
|
||||
|
||||
.. autoclass:: openlp.core.lib.eventreceiver.EventReceiver
|
||||
:members:
|
||||
|
||||
:mod:`ListWidgetWithDnD`
|
||||
----------------------
|
||||
|
||||
.. autoclass:: openlp.core.lib.listwidgetwithdnd.ListWidgetWithDnD
|
||||
:members:
|
||||
|
||||
:mod:`MediaManagerItem`
|
||||
-----------------------
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
.. _core-theme:
|
||||
|
||||
:mod:`theme` Module
|
||||
===================
|
||||
Theme Function Library
|
||||
======================
|
||||
|
||||
.. automodule:: openlp.core.theme
|
||||
: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
|
||||
:members:
|
||||
|
||||
.. autoclass:: openlp.plugins.bibles.forms.importwizardform.ImportWizardForm
|
||||
.. autoclass:: openlp.plugins.bibles.forms.bibleimportform.BibleImportForm
|
||||
:members:
|
||||
|
||||
Helper Classes & Functions
|
||||
|
@ -48,7 +48,7 @@ copyright = u'2004-2010 Raoul Snyman'
|
||||
# The short X.Y version.
|
||||
version = '2.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.9.3'
|
||||
release = '1.9.5'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@ -92,22 +92,24 @@ pygments_style = 'sphinx'
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
#html_theme = 'openlp_qthelp'
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
html_theme_options = {
|
||||
'sidebarbgcolor': '#3a60a9',
|
||||
'relbarbgcolor': '#203b6f',
|
||||
'footerbgcolor': '#26437c',
|
||||
'headtextcolor': '#203b6f',
|
||||
'linkcolor': '#26437c',
|
||||
'sidebarlinkcolor': '#ceceff'
|
||||
}
|
||||
if html_theme == 'default':
|
||||
html_theme_options = {
|
||||
'sidebarbgcolor': '#3a60a9',
|
||||
'relbarbgcolor': '#203b6f',
|
||||
'footerbgcolor': '#26437c',
|
||||
'headtextcolor': '#203b6f',
|
||||
'linkcolor': '#26437c',
|
||||
'sidebarlinkcolor': '#ceceff'
|
||||
}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
html_theme_path = [u'../themes']
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
|
@ -149,15 +149,15 @@ Or, as root::
|
||||
root@linux: # nividia-settings
|
||||
|
||||
If you do not want to write the changes to your ``xorg.conf`` file simply run
|
||||
the nVidia Settings program (``nvidia-settings``) from your desktop's menu,
|
||||
usually in an administration or system menu, or from the terminal as a normal
|
||||
user run::
|
||||
the nVidia Settings program (:command:`nvidia-settings`) from your desktop's
|
||||
menu, usually in an administration or system menu, or from the terminal as a
|
||||
normal user run::
|
||||
|
||||
user@linux:~ $ nvidia-settings
|
||||
|
||||
Once you have opened nVidia Settings, click on
|
||||
:guilabel:`X Server Display Configuration`. Then select the monitor you are
|
||||
wanting to use as your second monitor and click :guilabel:`Configure`.
|
||||
Once you have opened nVidia Settings, click on :guilabel:`X Server Display
|
||||
Configuration`. Then select the monitor you are wanting to use as your second
|
||||
monitor and click :guilabel:`Configure`.
|
||||
|
||||
.. image:: pics/nvlinux1.png
|
||||
|
||||
|
@ -17,10 +17,3 @@ Contents:
|
||||
mediamanager
|
||||
songs
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
|
68
documentation/manual/themes/openlp_qthelp/layout.html
Normal file
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 %}
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
documentation/manual/themes/openlp_qthelp/static/bg-page.png
Normal file
BIN
documentation/manual/themes/openlp_qthelp/static/bg-page.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 164 B |
Binary file not shown.
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
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
|
10
openlp.pyw
10
openlp.pyw
@ -76,7 +76,7 @@ class OpenLP(QtGui.QApplication):
|
||||
"""
|
||||
Load and store current Application Version
|
||||
"""
|
||||
if u'--dev-version' in sys.argv:
|
||||
if u'--dev-version' in sys.argv or u'-d' in sys.argv:
|
||||
# If we're running the dev version, let's use bzr to get the version
|
||||
try:
|
||||
# If bzrlib is availble, use it
|
||||
@ -194,7 +194,10 @@ class OpenLP(QtGui.QApplication):
|
||||
# now kill the splashscreen
|
||||
self.splash.finish(self.mainWindow)
|
||||
self.mainWindow.repaint()
|
||||
VersionThread(self.mainWindow, app_version).start()
|
||||
update_check = QtCore.QSettings().value(
|
||||
u'general/update check', QtCore.QVariant(True)).toBool()
|
||||
if update_check:
|
||||
VersionThread(self.mainWindow, app_version).start()
|
||||
return self.exec_()
|
||||
|
||||
def hookException(self, exctype, value, traceback):
|
||||
@ -213,6 +216,7 @@ class OpenLP(QtGui.QApplication):
|
||||
Sets the Busy Cursor for the Application
|
||||
"""
|
||||
self.setOverrideCursor(QtCore.Qt.BusyCursor)
|
||||
self.processEvents()
|
||||
|
||||
def setNormalCursor(self):
|
||||
"""
|
||||
@ -280,4 +284,4 @@ if __name__ == u'__main__':
|
||||
"""
|
||||
Instantiate and run the application.
|
||||
"""
|
||||
main()
|
||||
main()
|
||||
|
@ -315,10 +315,11 @@ def check_directory_exists(dir):
|
||||
``dir``
|
||||
Theme directory to make sure exists
|
||||
"""
|
||||
log.debug(u'check_directory_exists')
|
||||
log.debug(u'check_directory_exists %s' % dir)
|
||||
if not os.path.exists(dir):
|
||||
os.makedirs(dir)
|
||||
|
||||
from listwidgetwithdnd import ListWidgetWithDnD
|
||||
from theme import ThemeLevel, ThemeXML, BackgroundGradientType, \
|
||||
BackgroundType, HorizontalType, VerticalType
|
||||
from displaytags import DisplayTags
|
||||
@ -339,4 +340,3 @@ from dockwidget import OpenLPDockWidget
|
||||
from renderer import Renderer
|
||||
from rendermanager import RenderManager
|
||||
from mediamanageritem import MediaManagerItem
|
||||
from baselistwithdnd import BaseListWithDnD
|
||||
|
@ -86,10 +86,10 @@ class BaseModel(object):
|
||||
"""
|
||||
Creates an instance of a class and populates it, returning the instance
|
||||
"""
|
||||
me = cls()
|
||||
instance = cls()
|
||||
for key in kwargs:
|
||||
me.__setattr__(key, kwargs[key])
|
||||
return me
|
||||
instance.__setattr__(key, kwargs[key])
|
||||
return instance
|
||||
|
||||
class Manager(object):
|
||||
"""
|
||||
|
@ -60,8 +60,8 @@ class DisplayTags(object):
|
||||
DisplayTags.html_expands.append(tag)
|
||||
|
||||
@staticmethod
|
||||
def remove_html_tag(id):
|
||||
def remove_html_tag(tag_id):
|
||||
"""
|
||||
Removes amd individual html_expands list.
|
||||
Removes an individual html_expands tag.
|
||||
"""
|
||||
DisplayTags.html_expands.pop(id)
|
||||
DisplayTags.html_expands.pop(tag_id)
|
||||
|
@ -31,6 +31,8 @@ import logging
|
||||
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import build_icon
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class OpenLPDockWidget(QtGui.QDockWidget):
|
||||
@ -47,4 +49,4 @@ class OpenLPDockWidget(QtGui.QDockWidget):
|
||||
if name:
|
||||
self.setObjectName(name)
|
||||
if icon:
|
||||
self.setWindowIcon(icon)
|
||||
self.setWindowIcon(build_icon(icon))
|
||||
|
@ -28,7 +28,8 @@ import logging
|
||||
|
||||
from PyQt4 import QtWebKit
|
||||
|
||||
from openlp.core.lib import BackgroundType, BackgroundGradientType
|
||||
from openlp.core.lib import BackgroundType, BackgroundGradientType, \
|
||||
VerticalType
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -314,7 +315,7 @@ body {
|
||||
</html>
|
||||
"""
|
||||
|
||||
def build_html(item, screen, alert, islive):
|
||||
def build_html(item, screen, alert, islive, background):
|
||||
"""
|
||||
Build the full web paged structure for display
|
||||
|
||||
@ -332,7 +333,9 @@ def build_html(item, screen, alert, islive):
|
||||
theme = item.themedata
|
||||
webkitvers = webkit_version()
|
||||
# Image generated and poked in
|
||||
if item.bg_image_bytes:
|
||||
if background:
|
||||
image = u'src="data:image/png;base64,%s"' % background
|
||||
elif item.bg_image_bytes:
|
||||
image = u'src="data:image/png;base64,%s"' % item.bg_image_bytes
|
||||
else:
|
||||
image = u'style="display:none;"'
|
||||
@ -534,12 +537,7 @@ def build_lyrics_format_css(theme, width, height):
|
||||
align = u'right'
|
||||
else:
|
||||
align = u'left'
|
||||
if theme.display_vertical_align == 2:
|
||||
valign = u'bottom'
|
||||
elif theme.display_vertical_align == 1:
|
||||
valign = u'middle'
|
||||
else:
|
||||
valign = u'top'
|
||||
valign = VerticalType.to_string(theme.display_vertical_align)
|
||||
if theme.font_main_outline:
|
||||
left_margin = int(theme.font_main_outline_size) * 2
|
||||
else:
|
||||
@ -632,13 +630,7 @@ def build_alert_css(alertTab, width):
|
||||
"""
|
||||
if not alertTab:
|
||||
return u''
|
||||
align = u''
|
||||
if alertTab.location == 2:
|
||||
align = u'bottom'
|
||||
elif alertTab.location == 1:
|
||||
align = u'middle'
|
||||
else:
|
||||
align = u'top'
|
||||
align = VerticalType.to_string(alertTab.location)
|
||||
alert = style % (width, align, alertTab.font_face, alertTab.font_size,
|
||||
alertTab.font_color, alertTab.bg_color)
|
||||
return alert
|
||||
|
@ -61,10 +61,10 @@ class Image(object):
|
||||
image = None
|
||||
image_bytes = None
|
||||
|
||||
|
||||
class ImageManager(QtCore.QObject):
|
||||
"""
|
||||
Image Manager handles the conversion and sizing of images.
|
||||
|
||||
"""
|
||||
log.info(u'Image Manager loaded')
|
||||
|
||||
|
@ -28,17 +28,17 @@ Extend QListWidget to handle drag and drop functionality
|
||||
"""
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class BaseListWithDnD(QtGui.QListWidget):
|
||||
class ListWidgetWithDnD(QtGui.QListWidget):
|
||||
"""
|
||||
Provide a list widget to store objects and handle drag and drop events
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
def __init__(self, parent=None, name=u''):
|
||||
"""
|
||||
Initialise the list widget
|
||||
"""
|
||||
QtGui.QListWidget.__init__(self, parent)
|
||||
# this must be set by the class which is inheriting
|
||||
assert(self.PluginName)
|
||||
self.mimeDataText = name
|
||||
assert(self.mimeDataText)
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
"""
|
||||
@ -47,9 +47,10 @@ class BaseListWithDnD(QtGui.QListWidget):
|
||||
just tell it what plugin to call
|
||||
"""
|
||||
if event.buttons() != QtCore.Qt.LeftButton:
|
||||
event.ignore()
|
||||
return
|
||||
drag = QtGui.QDrag(self)
|
||||
mimeData = QtCore.QMimeData()
|
||||
drag.setMimeData(mimeData)
|
||||
mimeData.setText(self.PluginName)
|
||||
drag.start(QtCore.Qt.CopyAction)
|
||||
mimeData.setText(self.mimeDataText)
|
||||
drag.start(QtCore.Qt.CopyAction)
|
@ -33,7 +33,7 @@ from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import context_menu_action, context_menu_separator, \
|
||||
SettingsManager, OpenLPToolbar, ServiceItem, StringContent, build_icon, \
|
||||
translate, Receiver
|
||||
translate, Receiver, ListWidgetWithDnD
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -73,11 +73,6 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
assumes that the new action is to load a file. If not, you
|
||||
need to override the ``OnNew`` method.
|
||||
|
||||
``self.ListViewWithDnD_class``
|
||||
This must be a **class**, not an object, descended from
|
||||
``openlp.core.lib.BaseListWithDnD`` that is not used in any
|
||||
other part of OpenLP.
|
||||
|
||||
``self.PreviewFunction``
|
||||
This must be a method which returns a QImage to represent the
|
||||
item (usually a preview). No scaling is required, that is
|
||||
@ -98,16 +93,11 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
visible_title = self.plugin.getString(StringContent.VisibleName)
|
||||
self.title = unicode(visible_title[u'title'])
|
||||
self.settingsSection = self.plugin.name.lower()
|
||||
if isinstance(icon, QtGui.QIcon):
|
||||
self.icon = icon
|
||||
elif isinstance(icon, basestring):
|
||||
self.icon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(icon)),
|
||||
QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
else:
|
||||
self.icon = None
|
||||
self.icon = None
|
||||
if icon:
|
||||
self.icon = build_icon(icon)
|
||||
self.toolbar = None
|
||||
self.remoteTriggered = None
|
||||
self.serviceItemIconName = None
|
||||
self.singleServiceItem = True
|
||||
self.pageLayout = QtGui.QVBoxLayout(self)
|
||||
self.pageLayout.setSpacing(0)
|
||||
@ -163,7 +153,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
|
||||
``icon``
|
||||
The icon of the button. This can be an instance of QIcon, or a
|
||||
string cotaining either the absolute path to the image, or an
|
||||
string containing either the absolute path to the image, or an
|
||||
internal resource path starting with ':/'.
|
||||
|
||||
``slot``
|
||||
@ -207,68 +197,50 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
"""
|
||||
Create buttons for the media item toolbar
|
||||
"""
|
||||
toolbar_actions = []
|
||||
## Import Button ##
|
||||
if self.hasImportIcon:
|
||||
import_string = self.plugin.getString(StringContent.Import)
|
||||
self.addToolbarButton(
|
||||
import_string[u'title'],
|
||||
import_string[u'tooltip'],
|
||||
u':/general/general_import.png', self.onImportClick)
|
||||
toolbar_actions.append([StringContent.Import,
|
||||
u':/general/general_import.png', self.onImportClick])
|
||||
## Load Button ##
|
||||
if self.hasFileIcon:
|
||||
load_string = self.plugin.getString(StringContent.Load)
|
||||
self.addToolbarButton(
|
||||
load_string[u'title'],
|
||||
load_string[u'tooltip'],
|
||||
u':/general/general_open.png', self.onFileClick)
|
||||
toolbar_actions.append([StringContent.Load,
|
||||
u':/general/general_open.png', self.onFileClick])
|
||||
## New Button ##
|
||||
if self.hasNewIcon:
|
||||
new_string = self.plugin.getString(StringContent.New)
|
||||
self.addToolbarButton(
|
||||
new_string[u'title'],
|
||||
new_string[u'tooltip'],
|
||||
u':/general/general_new.png', self.onNewClick)
|
||||
toolbar_actions.append([StringContent.New,
|
||||
u':/general/general_new.png', self.onNewClick])
|
||||
## Edit Button ##
|
||||
if self.hasEditIcon:
|
||||
edit_string = self.plugin.getString(StringContent.Edit)
|
||||
self.addToolbarButton(
|
||||
edit_string[u'title'],
|
||||
edit_string[u'tooltip'],
|
||||
u':/general/general_edit.png', self.onEditClick)
|
||||
toolbar_actions.append([StringContent.Edit,
|
||||
u':/general/general_edit.png', self.onEditClick])
|
||||
## Delete Button ##
|
||||
if self.hasDeleteIcon:
|
||||
delete_string = self.plugin.getString(StringContent.Delete)
|
||||
self.addToolbarButton(
|
||||
delete_string[u'title'],
|
||||
delete_string[u'tooltip'],
|
||||
u':/general/general_delete.png', self.onDeleteClick)
|
||||
toolbar_actions.append([StringContent.Delete,
|
||||
u':/general/general_delete.png', self.onDeleteClick])
|
||||
## Separator Line ##
|
||||
self.addToolbarSeparator()
|
||||
## Preview ##
|
||||
preview_string = self.plugin.getString(StringContent.Preview)
|
||||
self.addToolbarButton(
|
||||
preview_string[u'title'],
|
||||
preview_string[u'tooltip'],
|
||||
u':/general/general_preview.png', self.onPreviewClick)
|
||||
## Live Button ##
|
||||
live_string = self.plugin.getString(StringContent.Live)
|
||||
self.addToolbarButton(
|
||||
live_string[u'title'],
|
||||
live_string[u'tooltip'],
|
||||
u':/general/general_live.png', self.onLiveClick)
|
||||
toolbar_actions.append([StringContent.Preview,
|
||||
u':/general/general_preview.png', self.onPreviewClick])
|
||||
## Live Button ##
|
||||
toolbar_actions.append([StringContent.Live,
|
||||
u':/general/general_live.png', self.onLiveClick])
|
||||
## Add to service Button ##
|
||||
service_string = self.plugin.getString(StringContent.Service)
|
||||
self.addToolbarButton(
|
||||
service_string[u'title'],
|
||||
service_string[u'tooltip'],
|
||||
u':/general/general_add.png', self.onAddClick)
|
||||
toolbar_actions.append([StringContent.Service,
|
||||
u':/general/general_add.png', self.onAddClick])
|
||||
for action in toolbar_actions:
|
||||
self.addToolbarButton(
|
||||
self.plugin.getString(action[0])[u'title'],
|
||||
self.plugin.getString(action[0])[u'tooltip'],
|
||||
action[1], action[2])
|
||||
|
||||
def addListViewToToolBar(self):
|
||||
"""
|
||||
Creates the main widget for listing items the media item is tracking
|
||||
"""
|
||||
# Add the List widget
|
||||
self.listView = self.ListViewWithDnD_class(self)
|
||||
self.listView = ListWidgetWithDnD(self, self.title)
|
||||
self.listView.uniformItemSizes = True
|
||||
self.listView.setSpacing(1)
|
||||
self.listView.setSelectionMode(
|
||||
@ -280,7 +252,6 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
self.pageLayout.addWidget(self.listView)
|
||||
# define and add the context menu
|
||||
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||
name_string = self.plugin.getString(StringContent.Name)
|
||||
if self.hasEditIcon:
|
||||
self.listView.addAction(
|
||||
context_menu_action(
|
||||
@ -371,33 +342,34 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
count += 1
|
||||
return filelist
|
||||
|
||||
def validate(self, file, thumb):
|
||||
def validate(self, image, thumb):
|
||||
"""
|
||||
Validates to see if the file still exists or thumbnail is up to date
|
||||
Validates whether an image still exists and, if it does, is the
|
||||
thumbnail representation of the image up to date.
|
||||
"""
|
||||
if not os.path.exists(file):
|
||||
if not os.path.exists(image):
|
||||
return False
|
||||
if os.path.exists(thumb):
|
||||
filedate = os.stat(file).st_mtime
|
||||
thumbdate = os.stat(thumb).st_mtime
|
||||
# if file updated rebuild icon
|
||||
if filedate > thumbdate:
|
||||
self.iconFromFile(file, thumb)
|
||||
imageDate = os.stat(image).st_mtime
|
||||
thumbDate = os.stat(thumb).st_mtime
|
||||
# If image has been updated rebuild icon
|
||||
if imageDate > thumbDate:
|
||||
self.iconFromFile(image, thumb)
|
||||
else:
|
||||
self.iconFromFile(file, thumb)
|
||||
self.iconFromFile(image, thumb)
|
||||
return True
|
||||
|
||||
def iconFromFile(self, file, thumb):
|
||||
def iconFromFile(self, image, thumb):
|
||||
"""
|
||||
Create a thumbnail icon from a given file
|
||||
Create a thumbnail icon from a given image.
|
||||
|
||||
``file``
|
||||
The file to create the icon from
|
||||
``image``
|
||||
The image file to create the icon from.
|
||||
|
||||
``thumb``
|
||||
The filename to save the thumbnail to
|
||||
"""
|
||||
icon = build_icon(unicode(file))
|
||||
icon = build_icon(unicode(image))
|
||||
pixmap = icon.pixmap(QtCore.QSize(88, 50))
|
||||
ext = os.path.splitext(thumb)[1].lower()
|
||||
pixmap.save(thumb, ext[1:])
|
||||
@ -408,12 +380,16 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
u'defined by the plugin')
|
||||
|
||||
def onNewClick(self):
|
||||
raise NotImplementedError(u'MediaManagerItem.onNewClick needs to be '
|
||||
u'defined by the plugin')
|
||||
"""
|
||||
Hook for plugins to define behaviour for adding new items.
|
||||
"""
|
||||
pass
|
||||
|
||||
def onEditClick(self):
|
||||
raise NotImplementedError(u'MediaManagerItem.onEditClick needs to be '
|
||||
u'defined by the plugin')
|
||||
"""
|
||||
Hook for plugins to define behaviour for editing items.
|
||||
"""
|
||||
pass
|
||||
|
||||
def onDeleteClick(self):
|
||||
raise NotImplementedError(u'MediaManagerItem.onDeleteClick needs to '
|
||||
@ -500,7 +476,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
"""
|
||||
if not self.listView.selectedIndexes() and not self.remoteTriggered:
|
||||
QtGui.QMessageBox.information(self,
|
||||
translate('OpenLP.MediaManagerItem', 'No items selected'),
|
||||
translate('OpenLP.MediaManagerItem', 'No Items Selected'),
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
'You must select one or more items'))
|
||||
else:
|
||||
@ -512,7 +488,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
'No Service Item Selected'),
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
'You must select an existing service item to add to.'))
|
||||
elif self.title.lower() == serviceItem.name.lower():
|
||||
elif self.plugin.name.lower() == serviceItem.name.lower():
|
||||
self.generateSlideData(serviceItem)
|
||||
self.parent.serviceManager.addServiceItem(serviceItem,
|
||||
replace=True)
|
||||
@ -529,10 +505,7 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
Common method for generating a service item
|
||||
"""
|
||||
serviceItem = ServiceItem(self.parent)
|
||||
if self.serviceItemIconName:
|
||||
serviceItem.add_icon(self.serviceItemIconName)
|
||||
else:
|
||||
serviceItem.add_icon(self.parent.icon_path)
|
||||
serviceItem.add_icon(self.parent.icon_path)
|
||||
if self.generateSlideData(serviceItem, item, xmlVersion):
|
||||
return serviceItem
|
||||
else:
|
||||
@ -544,3 +517,25 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
individual service items need to be processed by the plugins
|
||||
"""
|
||||
pass
|
||||
|
||||
def _getIdOfItemToGenerate(self, item, remoteItem):
|
||||
"""
|
||||
Utility method to check items being submitted for slide generation.
|
||||
|
||||
``item``
|
||||
The item to check.
|
||||
|
||||
``remoteItem``
|
||||
The id to assign if the slide generation was remotely triggered.
|
||||
"""
|
||||
if item is None:
|
||||
if self.remoteTriggered is None:
|
||||
item = self.listView.currentItem()
|
||||
if item is None:
|
||||
return False
|
||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
else:
|
||||
item_id = remoteItem
|
||||
else:
|
||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
return item_id
|
||||
|
@ -31,6 +31,7 @@ import logging
|
||||
from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.lib import Receiver
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -42,7 +43,11 @@ class PluginStatus(object):
|
||||
Inactive = 0
|
||||
Disabled = -1
|
||||
|
||||
|
||||
class StringContent(object):
|
||||
"""
|
||||
Provide standard strings for objects to use.
|
||||
"""
|
||||
Name = u'name'
|
||||
Import = u'import'
|
||||
Load = u'load'
|
||||
@ -54,6 +59,7 @@ class StringContent(object):
|
||||
Service = u'service'
|
||||
VisibleName = u'visible_name'
|
||||
|
||||
|
||||
class Plugin(QtCore.QObject):
|
||||
"""
|
||||
Base class for openlp plugins to inherit from.
|
||||
@ -108,7 +114,8 @@ class Plugin(QtCore.QObject):
|
||||
"""
|
||||
log.info(u'loaded')
|
||||
|
||||
def __init__(self, name, version=None, pluginHelpers=None):
|
||||
def __init__(self, name, version=None, pluginHelpers=None,
|
||||
mediaItemClass=None, settingsTabClass=None):
|
||||
"""
|
||||
This is the constructor for the plugin object. This provides an easy
|
||||
way for descendent plugins to populate common data. This method *must*
|
||||
@ -116,7 +123,7 @@ class Plugin(QtCore.QObject):
|
||||
|
||||
class MyPlugin(Plugin):
|
||||
def __init__(self):
|
||||
Plugin.__init(self, u'MyPlugin', u'0.1')
|
||||
Plugin.__init__(self, u'MyPlugin', u'0.1')
|
||||
|
||||
``name``
|
||||
Defaults to *None*. The name of the plugin.
|
||||
@ -126,6 +133,12 @@ class Plugin(QtCore.QObject):
|
||||
|
||||
``pluginHelpers``
|
||||
Defaults to *None*. A list of helper objects.
|
||||
|
||||
``mediaItemClass``
|
||||
The class name of the plugin's media item.
|
||||
|
||||
``settingsTabClass``
|
||||
The class name of the plugin's settings tab.
|
||||
"""
|
||||
QtCore.QObject.__init__(self)
|
||||
self.name = name
|
||||
@ -135,6 +148,8 @@ class Plugin(QtCore.QObject):
|
||||
self.version = version
|
||||
self.settingsSection = self.name.lower()
|
||||
self.icon = None
|
||||
self.mediaItemClass = mediaItemClass
|
||||
self.settingsTabClass = settingsTabClass
|
||||
self.weight = 0
|
||||
self.status = PluginStatus.Inactive
|
||||
# Set up logging
|
||||
@ -193,7 +208,9 @@ class Plugin(QtCore.QObject):
|
||||
Construct a MediaManagerItem object with all the buttons and things
|
||||
you need, and return it for integration into openlp.org.
|
||||
"""
|
||||
pass
|
||||
if self.mediaItemClass:
|
||||
return self.mediaItemClass(self, self, self.icon)
|
||||
return None
|
||||
|
||||
def addImportMenuItem(self, importMenu):
|
||||
"""
|
||||
@ -224,9 +241,13 @@ class Plugin(QtCore.QObject):
|
||||
|
||||
def getSettingsTab(self):
|
||||
"""
|
||||
Create a tab for the settings window.
|
||||
Create a tab for the settings window to display the configurable
|
||||
options for this plugin to the user.
|
||||
"""
|
||||
pass
|
||||
if self.settingsTabClass:
|
||||
return self.settingsTabClass(self.name,
|
||||
self.getString(StringContent.VisibleName)[u'title'])
|
||||
return None
|
||||
|
||||
def addToMenu(self, menubar):
|
||||
"""
|
||||
@ -314,8 +335,39 @@ class Plugin(QtCore.QObject):
|
||||
"""
|
||||
return self.textStrings[name]
|
||||
|
||||
def setPluginTextStrings(self):
|
||||
def setPluginUiTextStrings(self, tooltips):
|
||||
"""
|
||||
Called to define all translatable texts of the plugin
|
||||
"""
|
||||
pass
|
||||
## Load Action ##
|
||||
self.__setNameTextString(StringContent.Load,
|
||||
UiStrings.Load, tooltips[u'load'])
|
||||
## Import Action ##
|
||||
self.__setNameTextString(StringContent.Import,
|
||||
UiStrings.Import, tooltips[u'import'])
|
||||
## New Action ##
|
||||
self.__setNameTextString(StringContent.New,
|
||||
UiStrings.Add, tooltips[u'new'])
|
||||
## Edit Action ##
|
||||
self.__setNameTextString(StringContent.Edit,
|
||||
UiStrings.Edit, tooltips[u'edit'])
|
||||
## Delete Action ##
|
||||
self.__setNameTextString(StringContent.Delete,
|
||||
UiStrings.Delete, tooltips[u'delete'])
|
||||
## Preview Action ##
|
||||
self.__setNameTextString(StringContent.Preview,
|
||||
UiStrings.Preview, tooltips[u'preview'])
|
||||
## Send Live Action ##
|
||||
self.__setNameTextString(StringContent.Live,
|
||||
UiStrings.Live, tooltips[u'live'])
|
||||
## Add to Service Action ##
|
||||
self.__setNameTextString(StringContent.Service,
|
||||
UiStrings.Service, tooltips[u'service'])
|
||||
|
||||
def __setNameTextString(self, name, title, tooltip):
|
||||
"""
|
||||
Utility method for creating a plugin's textStrings. This method makes
|
||||
use of the singular name of the plugin object so must only be called
|
||||
after this has been set.
|
||||
"""
|
||||
self.textStrings[name] = {u'title': title, u'tooltip': tooltip}
|
||||
|
@ -68,7 +68,6 @@ class RenderManager(object):
|
||||
self.theme_level = u''
|
||||
self.override_background = None
|
||||
self.theme_data = None
|
||||
self.alertTab = None
|
||||
self.force_page = False
|
||||
|
||||
def update_display(self):
|
||||
@ -261,4 +260,4 @@ class RenderManager(object):
|
||||
log.debug(u'calculate default %d, %d, %f',
|
||||
self.width, self.height, self.screen_ratio )
|
||||
# 90% is start of footer
|
||||
self.footer_start = int(self.height * 0.90)
|
||||
self.footer_start = int(self.height * 0.90)
|
||||
|
@ -93,15 +93,15 @@ class SearchEdit(QtGui.QLineEdit):
|
||||
``event``
|
||||
The event that happened.
|
||||
"""
|
||||
sz = self.clearButton.size()
|
||||
size = self.clearButton.size()
|
||||
frameWidth = self.style().pixelMetric(
|
||||
QtGui.QStyle.PM_DefaultFrameWidth)
|
||||
self.clearButton.move(self.rect().right() - frameWidth - sz.width(),
|
||||
(self.rect().bottom() + 1 - sz.height()) / 2)
|
||||
self.clearButton.move(self.rect().right() - frameWidth - size.width(),
|
||||
(self.rect().bottom() + 1 - size.height()) / 2)
|
||||
if hasattr(self, u'menuButton'):
|
||||
sz = self.menuButton.size()
|
||||
size = self.menuButton.size()
|
||||
self.menuButton.move(self.rect().left() + frameWidth + 2,
|
||||
(self.rect().bottom() + 1 - sz.height()) / 2)
|
||||
(self.rect().bottom() + 1 - size.height()) / 2)
|
||||
|
||||
def currentSearchType(self):
|
||||
"""
|
||||
|
@ -28,11 +28,13 @@ The :mod:`serviceitem` provides the service item functionality including the
|
||||
type and capability of an item.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from openlp.core.lib import build_icon, clean_tags, expand_tags
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -59,6 +61,8 @@ class ItemCapabilities(object):
|
||||
OnLoadUpdate = 8
|
||||
AddIfNewItem = 9
|
||||
ProvidesOwnDisplay = 10
|
||||
AllowsDetailedTitleDisplay = 11
|
||||
AllowsVarableStartTime = 12
|
||||
|
||||
|
||||
class ServiceItem(object):
|
||||
@ -104,6 +108,8 @@ class ServiceItem(object):
|
||||
self.data_string = u''
|
||||
self.edit_id = None
|
||||
self.xml_version = None
|
||||
self.start_time = 0
|
||||
self.media_length = 0
|
||||
self._new_item()
|
||||
|
||||
def _new_item(self):
|
||||
@ -256,7 +262,9 @@ class ServiceItem(object):
|
||||
u'capabilities': self.capabilities,
|
||||
u'search': self.search_string,
|
||||
u'data': self.data_string,
|
||||
u'xml_version': self.xml_version
|
||||
u'xml_version': self.xml_version,
|
||||
u'start_time': self.start_time,
|
||||
u'media_length': self.media_length
|
||||
}
|
||||
service_data = []
|
||||
if self.service_item_type == ServiceItemType.Text:
|
||||
@ -300,6 +308,10 @@ class ServiceItem(object):
|
||||
self.data_string = header[u'data']
|
||||
if u'xml_version' in header:
|
||||
self.xml_version = header[u'xml_version']
|
||||
if u'start_time' in header:
|
||||
self.start_time = header[u'start_time']
|
||||
if u'media_length' in header:
|
||||
self.media_length = header[u'media_length']
|
||||
if self.service_item_type == ServiceItemType.Text:
|
||||
for slide in serviceitem[u'serviceitem'][u'data']:
|
||||
self._raw_frames.append(slide)
|
||||
@ -314,6 +326,20 @@ class ServiceItem(object):
|
||||
path, text_image[u'title'], text_image[u'image'] )
|
||||
self._new_item()
|
||||
|
||||
def get_display_title(self):
|
||||
"""
|
||||
Returns the title of the service item.
|
||||
"""
|
||||
if self.is_text():
|
||||
return self.title
|
||||
else:
|
||||
if ItemCapabilities.AllowsDetailedTitleDisplay in self.capabilities:
|
||||
return self._raw_frames[0][u'title']
|
||||
elif len(self._raw_frames) > 1:
|
||||
return self.title
|
||||
else:
|
||||
return self._raw_frames[0][u'title']
|
||||
|
||||
def merge(self, other):
|
||||
"""
|
||||
Updates the _uuid with the value from the original one
|
||||
@ -405,3 +431,24 @@ class ServiceItem(object):
|
||||
return self._raw_frames[row][u'path']
|
||||
except IndexError:
|
||||
return u''
|
||||
|
||||
def get_media_time(self):
|
||||
"""
|
||||
Returns the start and finish time for a media item
|
||||
"""
|
||||
start = None
|
||||
end = None
|
||||
if self.start_time != 0:
|
||||
start = UiStrings.StartTimeCode % \
|
||||
unicode(datetime.timedelta(seconds=self.start_time))
|
||||
if self.media_length != 0:
|
||||
end = UiStrings.LengthTime % \
|
||||
unicode(datetime.timedelta(seconds=self.media_length))
|
||||
if not start and not end:
|
||||
return None
|
||||
elif start and not end:
|
||||
return start
|
||||
elif not start and end:
|
||||
return end
|
||||
else:
|
||||
return u'%s : %s' % (start, end)
|
||||
|
@ -47,13 +47,16 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||
# Default dictionary based on the current locale.
|
||||
if ENCHANT_AVAILABLE:
|
||||
try:
|
||||
self.dict = enchant.Dict()
|
||||
self.dictionary = enchant.Dict()
|
||||
except DictNotFoundError:
|
||||
self.dict = enchant.Dict(u'en_US')
|
||||
self.dictionary = enchant.Dict(u'en_US')
|
||||
self.highlighter = Highlighter(self.document())
|
||||
self.highlighter.setDict(self.dict)
|
||||
self.highlighter.spellingDictionary = self.dictionary
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
"""
|
||||
Handle mouse clicks within the text edit region.
|
||||
"""
|
||||
if event.button() == QtCore.Qt.RightButton:
|
||||
# Rewrite the mouse event to a left button event so the cursor is
|
||||
# moved to the location of the pointer.
|
||||
@ -63,6 +66,9 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||
QtGui.QPlainTextEdit.mousePressEvent(self, event)
|
||||
|
||||
def contextMenuEvent(self, event):
|
||||
"""
|
||||
Provide the context menu for the text edit region.
|
||||
"""
|
||||
popupMenu = self.createStandardContextMenu()
|
||||
# Select the word under the cursor.
|
||||
cursor = self.textCursor()
|
||||
@ -74,10 +80,10 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||
# suggestions if it is.
|
||||
if ENCHANT_AVAILABLE and self.textCursor().hasSelection():
|
||||
text = unicode(self.textCursor().selectedText())
|
||||
if not self.dict.check(text):
|
||||
if not self.dictionary.check(text):
|
||||
spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
|
||||
'Spelling Suggestions'))
|
||||
for word in self.dict.suggest(text):
|
||||
for word in self.dictionary.suggest(text):
|
||||
action = SpellAction(word, spell_menu)
|
||||
action.correct.connect(self.correctWord)
|
||||
spell_menu.addAction(action)
|
||||
@ -126,28 +132,32 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||
cursor.insertText(html[u'start tag'])
|
||||
cursor.insertText(html[u'end tag'])
|
||||
|
||||
class Highlighter(QtGui.QSyntaxHighlighter):
|
||||
|
||||
class Highlighter(QtGui.QSyntaxHighlighter):
|
||||
"""
|
||||
Provides a text highlighter for pointing out spelling errors in text.
|
||||
"""
|
||||
WORDS = u'(?iu)[\w\']+'
|
||||
|
||||
def __init__(self, *args):
|
||||
QtGui.QSyntaxHighlighter.__init__(self, *args)
|
||||
self.dict = None
|
||||
|
||||
def setDict(self, dict):
|
||||
self.dict = dict
|
||||
self.spellingDictionary = None
|
||||
|
||||
def highlightBlock(self, text):
|
||||
if not self.dict:
|
||||
"""
|
||||
Highlight misspelt words in a block of text
|
||||
"""
|
||||
if not self.spellingDictionary:
|
||||
return
|
||||
text = unicode(text)
|
||||
format = QtGui.QTextCharFormat()
|
||||
format.setUnderlineColor(QtCore.Qt.red)
|
||||
format.setUnderlineStyle(QtGui.QTextCharFormat.SpellCheckUnderline)
|
||||
charFormat = QtGui.QTextCharFormat()
|
||||
charFormat.setUnderlineColor(QtCore.Qt.red)
|
||||
charFormat.setUnderlineStyle(QtGui.QTextCharFormat.SpellCheckUnderline)
|
||||
for word_object in re.finditer(self.WORDS, text):
|
||||
if not self.dict.check(word_object.group()):
|
||||
if not self.spellingDictionary.check(word_object.group()):
|
||||
self.setFormat(word_object.start(),
|
||||
word_object.end() - word_object.start(), format)
|
||||
word_object.end() - word_object.start(), charFormat)
|
||||
|
||||
|
||||
class SpellAction(QtGui.QAction):
|
||||
"""
|
||||
|
@ -91,21 +91,30 @@ class ThemeLevel(object):
|
||||
Song = 3
|
||||
|
||||
class BackgroundType(object):
|
||||
"""
|
||||
Type enumeration for backgrounds.
|
||||
"""
|
||||
Solid = 0
|
||||
Gradient = 1
|
||||
Image = 2
|
||||
|
||||
@staticmethod
|
||||
def to_string(type):
|
||||
if type == BackgroundType.Solid:
|
||||
def to_string(background_type):
|
||||
"""
|
||||
Return a string representation of a background type.
|
||||
"""
|
||||
if background_type == BackgroundType.Solid:
|
||||
return u'solid'
|
||||
elif type == BackgroundType.Gradient:
|
||||
elif background_type == BackgroundType.Gradient:
|
||||
return u'gradient'
|
||||
elif type == BackgroundType.Image:
|
||||
elif background_type == BackgroundType.Image:
|
||||
return u'image'
|
||||
|
||||
@staticmethod
|
||||
def from_string(type_string):
|
||||
"""
|
||||
Return a background type for the given string.
|
||||
"""
|
||||
if type_string == u'solid':
|
||||
return BackgroundType.Solid
|
||||
elif type_string == u'gradient':
|
||||
@ -114,6 +123,9 @@ class BackgroundType(object):
|
||||
return BackgroundType.Image
|
||||
|
||||
class BackgroundGradientType(object):
|
||||
"""
|
||||
Type enumeration for background gradients.
|
||||
"""
|
||||
Horizontal = 0
|
||||
Vertical = 1
|
||||
Circular = 2
|
||||
@ -121,20 +133,26 @@ class BackgroundGradientType(object):
|
||||
LeftBottom = 4
|
||||
|
||||
@staticmethod
|
||||
def to_string(type):
|
||||
if type == BackgroundGradientType.Horizontal:
|
||||
def to_string(gradient_type):
|
||||
"""
|
||||
Return a string representation of a background gradient type.
|
||||
"""
|
||||
if gradient_type == BackgroundGradientType.Horizontal:
|
||||
return u'horizontal'
|
||||
elif type == BackgroundGradientType.Vertical:
|
||||
elif gradient_type == BackgroundGradientType.Vertical:
|
||||
return u'vertical'
|
||||
elif type == BackgroundGradientType.Circular:
|
||||
elif gradient_type == BackgroundGradientType.Circular:
|
||||
return u'circular'
|
||||
elif type == BackgroundGradientType.LeftTop:
|
||||
elif gradient_type == BackgroundGradientType.LeftTop:
|
||||
return u'leftTop'
|
||||
elif type == BackgroundGradientType.LeftBottom:
|
||||
elif gradient_type == BackgroundGradientType.LeftBottom:
|
||||
return u'leftBottom'
|
||||
|
||||
@staticmethod
|
||||
def from_string(type_string):
|
||||
"""
|
||||
Return a background gradient type for the given string.
|
||||
"""
|
||||
if type_string == u'horizontal':
|
||||
return BackgroundGradientType.Horizontal
|
||||
elif type_string == u'vertical':
|
||||
@ -146,20 +164,53 @@ class BackgroundGradientType(object):
|
||||
elif type_string == u'leftBottom':
|
||||
return BackgroundGradientType.LeftBottom
|
||||
|
||||
|
||||
class HorizontalType(object):
|
||||
"""
|
||||
Type enumeration for horizontal alignment.
|
||||
"""
|
||||
Left = 0
|
||||
Center = 1
|
||||
Right = 2
|
||||
Center = 2
|
||||
Right = 1
|
||||
|
||||
@staticmethod
|
||||
def to_string(horizontal_type):
|
||||
"""
|
||||
Return a string representation of a horizontal type.
|
||||
"""
|
||||
if horizontal_type == HorizontalType.Right:
|
||||
return u'right'
|
||||
elif horizontal_type == HorizontalType.Center:
|
||||
return u'center'
|
||||
else:
|
||||
return u'left'
|
||||
|
||||
|
||||
class VerticalType(object):
|
||||
"""
|
||||
Type enumeration for vertical alignment.
|
||||
"""
|
||||
Top = 0
|
||||
Middle = 1
|
||||
Bottom = 2
|
||||
|
||||
boolean_list = [u'italics', u'override', u'outline', u'shadow',
|
||||
@staticmethod
|
||||
def to_string(vertical_type):
|
||||
"""
|
||||
Return a string representation of a vertical type.
|
||||
"""
|
||||
if vertical_type == VerticalType.Bottom:
|
||||
return u'bottom'
|
||||
elif vertical_type == VerticalType.Middle:
|
||||
return u'middle'
|
||||
else:
|
||||
return u'top'
|
||||
|
||||
|
||||
BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow',
|
||||
u'slide_transition']
|
||||
|
||||
integer_list = [u'size', u'line_adjustment', u'x', u'height', u'y',
|
||||
INTEGER_LIST = [u'size', u'line_adjustment', u'x', u'height', u'y',
|
||||
u'width', u'shadow_size', u'outline_size', u'horizontal_align',
|
||||
u'vertical_align', u'wrap_style']
|
||||
|
||||
@ -514,9 +565,9 @@ class ThemeXML(object):
|
||||
return
|
||||
field = self._de_hump(element)
|
||||
tag = master + u'_' + field
|
||||
if field in boolean_list:
|
||||
if field in BOOLEAN_LIST:
|
||||
setattr(self, tag, str_to_bool(value))
|
||||
elif field in integer_list:
|
||||
elif field in INTEGER_LIST:
|
||||
setattr(self, tag, int(value))
|
||||
else:
|
||||
# make string value unicode
|
||||
@ -559,8 +610,7 @@ class ThemeXML(object):
|
||||
self.background_end_color,
|
||||
self.background_direction)
|
||||
else:
|
||||
filename = \
|
||||
os.path.split(self.background_filename)[1]
|
||||
filename = os.path.split(self.background_filename)[1]
|
||||
self.add_background_image(filename)
|
||||
self.add_font(self.font_main_name,
|
||||
self.font_main_color,
|
||||
|
@ -61,7 +61,7 @@ class OpenLPToolbar(QtGui.QToolBar):
|
||||
|
||||
``icon``
|
||||
The icon of the button. This can be an instance of QIcon, or a
|
||||
string cotaining either the absolute path to the image, or an
|
||||
string containing either the absolute path to the image, or an
|
||||
internal resource path starting with ':/'.
|
||||
|
||||
``tooltip``
|
||||
@ -73,13 +73,13 @@ class OpenLPToolbar(QtGui.QToolBar):
|
||||
``checkable``
|
||||
If *True* the button has two, *off* and *on*, states. Default is
|
||||
*False*, which means the buttons has only one state.
|
||||
|
||||
|
||||
``shortcut``
|
||||
The primary shortcut for this action
|
||||
|
||||
|
||||
``alternate``
|
||||
The alternate shortcut for this action
|
||||
|
||||
|
||||
``context``
|
||||
Specify the context in which this shortcut is valid
|
||||
"""
|
||||
|
285
openlp/core/lib/ui.py
Normal file
285
openlp/core/lib/ui.py
Normal file
@ -0,0 +1,285 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||
# Carsten Tinggaard, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`ui` module provides standard UI components for OpenLP.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, Receiver, translate
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class UiStrings(object):
|
||||
"""
|
||||
Provide standard strings for objects to use.
|
||||
"""
|
||||
# These strings should need a good reason to be retranslated elsewhere.
|
||||
# Should some/more/less of these have an & attached?
|
||||
Add = translate('OpenLP.Ui', '&Add')
|
||||
Advanced = translate('OpenLP.Ui', 'Advanced')
|
||||
AllFiles = translate('OpenLP.Ui', 'All Files')
|
||||
Authors = translate('OpenLP.Ui', 'Authors')
|
||||
CreateService = translate('OpenLP.Ui', 'Create a new service.')
|
||||
Delete = translate('OpenLP.Ui', '&Delete')
|
||||
Edit = translate('OpenLP.Ui', '&Edit')
|
||||
Error = translate('OpenLP.Ui', 'Error')
|
||||
Import = translate('OpenLP.Ui', 'Import')
|
||||
LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
|
||||
Live = translate('OpenLP.Ui', 'Live')
|
||||
Load = translate('OpenLP.Ui', 'Load')
|
||||
New = translate('OpenLP.Ui', 'New')
|
||||
NewService = translate('OpenLP.Ui', 'New Service')
|
||||
OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0')
|
||||
OpenService = translate('OpenLP.Ui', 'Open Service')
|
||||
Preview = translate('OpenLP.Ui', 'Preview')
|
||||
ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
|
||||
ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background')
|
||||
ResetBG = translate('OpenLP.Ui', 'Reset Background')
|
||||
ResetLiveBG = translate('OpenLP.Ui', 'Reset Live Background')
|
||||
SaveService = translate('OpenLP.Ui', 'Save Service')
|
||||
Service = translate('OpenLP.Ui', 'Service')
|
||||
StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s'))
|
||||
Theme = translate('OpenLP.Ui', 'Theme')
|
||||
Themes = translate('OpenLP.Ui', 'Themes')
|
||||
|
||||
def add_welcome_page(parent, image):
|
||||
"""
|
||||
Generate an opening welcome page for a wizard using a provided image.
|
||||
|
||||
``parent``
|
||||
A ``QWizard`` object to add the welcome page to.
|
||||
|
||||
``image``
|
||||
A splash image for the wizard.
|
||||
"""
|
||||
parent.welcomePage = QtGui.QWizardPage()
|
||||
parent.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
|
||||
QtGui.QPixmap(image))
|
||||
parent.welcomePage.setObjectName(u'WelcomePage')
|
||||
parent.welcomeLayout = QtGui.QVBoxLayout(parent.welcomePage)
|
||||
parent.welcomeLayout.setObjectName(u'WelcomeLayout')
|
||||
parent.titleLabel = QtGui.QLabel(parent.welcomePage)
|
||||
parent.titleLabel.setObjectName(u'TitleLabel')
|
||||
parent.welcomeLayout.addWidget(parent.titleLabel)
|
||||
parent.welcomeLayout.addSpacing(40)
|
||||
parent.informationLabel = QtGui.QLabel(parent.welcomePage)
|
||||
parent.informationLabel.setWordWrap(True)
|
||||
parent.informationLabel.setObjectName(u'InformationLabel')
|
||||
parent.welcomeLayout.addWidget(parent.informationLabel)
|
||||
parent.welcomeLayout.addStretch()
|
||||
parent.addPage(parent.welcomePage)
|
||||
|
||||
def create_accept_reject_button_box(parent, okay=False):
|
||||
"""
|
||||
Creates a standard dialog button box with two buttons. The buttons default
|
||||
to save and cancel but the ``okay`` parameter can be used to make the
|
||||
buttons okay and cancel instead.
|
||||
The button box is connected to the parent's ``accept()`` and ``reject()``
|
||||
methods to handle the default ``accepted()`` and ``rejected()`` signals.
|
||||
|
||||
``parent``
|
||||
The parent object. This should be a ``QWidget`` descendant.
|
||||
|
||||
``okay``
|
||||
If true creates an okay/cancel combination instead of save/cancel.
|
||||
"""
|
||||
button_box = QtGui.QDialogButtonBox(parent)
|
||||
accept_button = QtGui.QDialogButtonBox.Save
|
||||
if okay:
|
||||
accept_button = QtGui.QDialogButtonBox.Ok
|
||||
button_box.setStandardButtons(accept_button | QtGui.QDialogButtonBox.Cancel)
|
||||
button_box.setObjectName(u'%sButtonBox' % parent)
|
||||
QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'accepted()'),
|
||||
parent.accept)
|
||||
QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'rejected()'),
|
||||
parent.reject)
|
||||
return button_box
|
||||
|
||||
def critical_error_message_box(title=None, message=None, parent=None,
|
||||
question=False):
|
||||
"""
|
||||
Provides a standard critical message box for errors that OpenLP displays
|
||||
to users.
|
||||
|
||||
``title``
|
||||
The title for the message box.
|
||||
|
||||
``message``
|
||||
The message to display to the user.
|
||||
|
||||
``parent``
|
||||
The parent UI element to attach the dialog to.
|
||||
|
||||
``question``
|
||||
Should this message box question the user.
|
||||
"""
|
||||
if question:
|
||||
return QtGui.QMessageBox.critical(parent, UiStrings.Error, message,
|
||||
QtGui.QMessageBox.StandardButtons(
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
||||
data = {u'message': message}
|
||||
data[u'title'] = title if title else UiStrings.Error
|
||||
return Receiver.send_message(u'openlp_error_message', data)
|
||||
|
||||
def media_item_combo_box(parent, name):
|
||||
"""
|
||||
Provide a standard combo box for media items.
|
||||
"""
|
||||
combo = QtGui.QComboBox(parent)
|
||||
combo.setObjectName(name)
|
||||
combo.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
combo.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
return combo
|
||||
|
||||
def create_delete_push_button(parent, icon=None):
|
||||
"""
|
||||
Creates a standard push button with a delete label and optional icon. The
|
||||
button is connected to the parent's ``onDeleteButtonClicked()`` method to
|
||||
handle the ``clicked()`` signal.
|
||||
|
||||
``parent``
|
||||
The parent object. This should be a ``QWidget`` descendant.
|
||||
|
||||
``icon``
|
||||
An icon to display on the button. This can be either a ``QIcon``, a
|
||||
resource path or a file name.
|
||||
"""
|
||||
delete_button = QtGui.QPushButton(parent)
|
||||
delete_button.setObjectName(u'deleteButton')
|
||||
delete_icon = icon if icon else u':/general/general_delete.png'
|
||||
delete_button.setIcon(build_icon(delete_icon))
|
||||
delete_button.setText(UiStrings.Delete)
|
||||
delete_button.setToolTip(
|
||||
translate('OpenLP.Ui', 'Delete the selected item.'))
|
||||
QtCore.QObject.connect(delete_button,
|
||||
QtCore.SIGNAL(u'clicked()'), parent.onDeleteButtonClicked)
|
||||
return delete_button
|
||||
|
||||
def create_up_down_push_button_set(parent):
|
||||
"""
|
||||
Creates a standard set of two push buttons, one for up and the other for
|
||||
down, for use with lists. The buttons use arrow icons and no text and are
|
||||
connected to the parent's ``onUpButtonClicked()`` and
|
||||
``onDownButtonClicked()`` to handle their respective ``clicked()`` signals.
|
||||
|
||||
``parent``
|
||||
The parent object. This should be a ``QWidget`` descendant.
|
||||
"""
|
||||
up_button = QtGui.QPushButton(parent)
|
||||
up_button.setIcon(build_icon(u':/services/service_up.png'))
|
||||
up_button.setObjectName(u'upButton')
|
||||
up_button.setToolTip(
|
||||
translate('OpenLP.Ui', 'Move selection up one position.'))
|
||||
down_button = QtGui.QPushButton(parent)
|
||||
down_button.setIcon(build_icon(u':/services/service_down.png'))
|
||||
down_button.setObjectName(u'downButton')
|
||||
down_button.setToolTip(
|
||||
translate('OpenLP.Ui', 'Move selection down one position.'))
|
||||
QtCore.QObject.connect(up_button,
|
||||
QtCore.SIGNAL(u'clicked()'), parent.onUpButtonClicked)
|
||||
QtCore.QObject.connect(down_button,
|
||||
QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked)
|
||||
return up_button, down_button
|
||||
|
||||
def base_action(parent, name):
|
||||
"""
|
||||
Return the most basic action with the object name set.
|
||||
"""
|
||||
action = QtGui.QAction(parent)
|
||||
action.setObjectName(name)
|
||||
return action
|
||||
|
||||
def checkable_action(parent, name, checked=None):
|
||||
"""
|
||||
Return a standard action with the checkable attribute set.
|
||||
"""
|
||||
action = base_action(parent, name)
|
||||
action.setCheckable(True)
|
||||
if checked is not None:
|
||||
action.setChecked(checked)
|
||||
return action
|
||||
|
||||
def icon_action(parent, name, icon, checked=None):
|
||||
"""
|
||||
Return a standard action with an icon.
|
||||
"""
|
||||
if checked is not None:
|
||||
action = checkable_action(parent, name, checked)
|
||||
else:
|
||||
action = base_action(parent, name)
|
||||
action.setIcon(build_icon(icon))
|
||||
return action
|
||||
|
||||
def shortcut_action(parent, text, shortcuts, function):
|
||||
"""
|
||||
Return a shortcut enabled action.
|
||||
"""
|
||||
action = QtGui.QAction(text, parent)
|
||||
action.setShortcuts(shortcuts)
|
||||
action.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), function)
|
||||
return action
|
||||
|
||||
def add_widget_completer(cache, widget):
|
||||
"""
|
||||
Adds a text autocompleter to a widget.
|
||||
|
||||
``cache``
|
||||
The list of items to use as suggestions.
|
||||
|
||||
``widget``
|
||||
The object to use the completer.
|
||||
"""
|
||||
completer = QtGui.QCompleter(cache)
|
||||
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
|
||||
widget.setCompleter(completer)
|
||||
|
||||
def create_valign_combo(form, parent, layout):
|
||||
"""
|
||||
Creates a standard label and combo box for asking users to select a
|
||||
vertical alignment.
|
||||
|
||||
``form``
|
||||
The UI screen that the label and combo will appear on.
|
||||
|
||||
``parent``
|
||||
The parent object. This should be a ``QWidget`` descendant.
|
||||
|
||||
``layout``
|
||||
A layout object to add the label and combo widgets to.
|
||||
"""
|
||||
verticalLabel = QtGui.QLabel(parent)
|
||||
verticalLabel.setObjectName(u'VerticalLabel')
|
||||
verticalLabel.setText(translate('OpenLP.Ui', '&Vertical Align:'))
|
||||
form.verticalComboBox = QtGui.QComboBox(parent)
|
||||
form.verticalComboBox.setObjectName(u'VerticalComboBox')
|
||||
form.verticalComboBox.addItem(translate('OpenLP.Ui', 'Top'))
|
||||
form.verticalComboBox.addItem(translate('OpenLP.Ui', 'Middle'))
|
||||
form.verticalComboBox.addItem(translate('OpenLP.Ui', 'Bottom'))
|
||||
verticalLabel.setBuddy(form.verticalComboBox)
|
||||
layout.addRow(verticalLabel, form.verticalComboBox)
|
@ -33,11 +33,14 @@ processing version 1 themes in OpenLP version 2.
|
||||
from xml.etree.ElementTree import ElementTree, XML
|
||||
from PyQt4 import QtGui
|
||||
|
||||
DELPHI_COLORS = {u'clRed': 0xFF0000,
|
||||
u'clBlue': 0x0000FF,
|
||||
u'clYellow': 0xFFFF00,
|
||||
u'clBlack': 0x000000,
|
||||
u'clWhite': 0xFFFFFF}
|
||||
DELPHI_COLORS = {
|
||||
u'clAqua': 0x00FFFF, u'clBlack': 0x000000, u'clBlue': 0x0000FF,
|
||||
u'clFuchsia': 0xFF00FF, u'clGray': 0x808080, u'clGreen': 0x008000,
|
||||
u'clLime': 0x00FF00, u'clMaroon': 0x800000, u'clNavy': 0x000080,
|
||||
u'clOlive': 0x808000, u'clPurple': 0x800080, u'clRed': 0xFF0000,
|
||||
u'clSilver': 0xC0C0C0, u'clTeal': 0x008080, u'clWhite': 0xFFFFFF,
|
||||
u'clYellow': 0xFFFF00
|
||||
}
|
||||
|
||||
BLANK_STYLE_XML = \
|
||||
'''<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
@ -68,38 +71,45 @@ class Theme(object):
|
||||
Theme name
|
||||
|
||||
``BackgroundMode``
|
||||
The behaviour of the background. Valid modes are:
|
||||
- 0 - Transparent
|
||||
- 1 - Opaque
|
||||
The behaviour of the background. Valid modes are:
|
||||
|
||||
* ``0`` - Transparent
|
||||
* ``1`` - Opaque
|
||||
|
||||
``BackgroundType``
|
||||
The content of the background. Valid types are:
|
||||
- 0 - solid color
|
||||
- 1 - gradient color
|
||||
- 2 - image
|
||||
The content of the background. Valid types are:
|
||||
|
||||
* ``0`` - solid color
|
||||
* ``1`` - gradient color
|
||||
* ``2`` - image
|
||||
|
||||
``BackgroundParameter1``
|
||||
Extra information about the background. The contents of this attribute
|
||||
Extra information about the background. The contents of this attribute
|
||||
depend on the BackgroundType:
|
||||
- image: image filename
|
||||
- gradient: start color
|
||||
- solid: color
|
||||
|
||||
* ``image`` - image filename
|
||||
* ``gradient`` - start color
|
||||
* ``solid`` - color
|
||||
|
||||
``BackgroundParameter2``
|
||||
Extra information about the background. The contents of this attribute
|
||||
depend on the BackgroundType:
|
||||
- image: border color
|
||||
- gradient: end color
|
||||
- solid: N/A
|
||||
|
||||
* ``image`` - border color
|
||||
* ``gradient`` - end color
|
||||
* ``solid`` - N/A
|
||||
|
||||
``BackgroundParameter3``
|
||||
Extra information about the background. The contents of this attribute
|
||||
depend on the BackgroundType:
|
||||
- image: N/A
|
||||
- gradient: The direction of the gradient. Valid entries are:
|
||||
- 0 -> vertical
|
||||
- 1 -> horizontal
|
||||
- solid: N/A
|
||||
|
||||
* ``image`` - N/A
|
||||
* ``gradient`` - The direction of the gradient. Valid entries are:
|
||||
|
||||
* ``0`` - vertical
|
||||
* ``1`` - horizontal
|
||||
|
||||
* ``solid`` - N/A
|
||||
|
||||
``FontName``
|
||||
Name of the font to use for the main font.
|
||||
@ -115,36 +125,41 @@ class Theme(object):
|
||||
|
||||
``Shadow``
|
||||
The shadow type to apply to the main font.
|
||||
- 0 - no shadow
|
||||
- non-zero - use shadow
|
||||
|
||||
* ``0`` - no shadow
|
||||
* non-zero - use shadow
|
||||
|
||||
``ShadowColor``
|
||||
Color for the shadow
|
||||
|
||||
``Outline``
|
||||
The outline to apply to the main font
|
||||
- 0 - no outline
|
||||
- non-zero - use outline
|
||||
|
||||
* ``0`` - no outline
|
||||
* non-zero - use outline
|
||||
|
||||
``OutlineColor``
|
||||
Color for the outline (or None if Outline is 0)
|
||||
|
||||
``HorizontalAlign``
|
||||
The horizontal alignment to apply to text. Valid alignments are:
|
||||
- 0 - left align
|
||||
- 1 - right align
|
||||
- 2 - centre align
|
||||
|
||||
* ``0`` - left align
|
||||
* ``1`` - right align
|
||||
* ``2`` - centre align
|
||||
|
||||
``VerticalAlign``
|
||||
The vertical alignment to apply to the text. Valid alignments are:
|
||||
- 0 - top align
|
||||
- 1 - bottom align
|
||||
- 2 - centre align
|
||||
|
||||
* ``0`` - top align
|
||||
* ``1`` - bottom align
|
||||
* ``2`` - centre align
|
||||
|
||||
``WrapStyle``
|
||||
The wrap style to apply to the text. Valid styles are:
|
||||
- 0 - normal
|
||||
- 1 - lyrics
|
||||
|
||||
* ``0`` - normal
|
||||
* ``1`` - lyrics
|
||||
"""
|
||||
def __init__(self, xml):
|
||||
"""
|
||||
@ -184,7 +199,6 @@ class Theme(object):
|
||||
if element.tag != u'Theme':
|
||||
element_text = element.text
|
||||
val = 0
|
||||
# easy!
|
||||
if element_text is None:
|
||||
val = element_text
|
||||
# strings need special handling to sort the colours out
|
||||
|
@ -28,7 +28,7 @@ The :mod:`ui` module provides the core user interface for OpenLP
|
||||
"""
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from openlp.core.lib import translate, Receiver
|
||||
from openlp.core.lib import translate
|
||||
|
||||
class HideMode(object):
|
||||
"""
|
||||
@ -51,36 +51,9 @@ class HideMode(object):
|
||||
Theme = 2
|
||||
Screen = 3
|
||||
|
||||
|
||||
def criticalErrorMessageBox(title=None, message=None, parent=None,
|
||||
question=False):
|
||||
"""
|
||||
Provides a standard critical message box for errors that OpenLP displays
|
||||
to users.
|
||||
|
||||
``title``
|
||||
The title for the message box.
|
||||
|
||||
``message``
|
||||
The message to display to the user.
|
||||
|
||||
``parent``
|
||||
The parent UI element to attach the dialog to.
|
||||
|
||||
``question``
|
||||
Should this message box question the user.
|
||||
"""
|
||||
error = translate('OpenLP.Ui', 'Error')
|
||||
if question:
|
||||
return QtGui.QMessageBox.critical(parent, error, message,
|
||||
QtGui.QMessageBox.StandardButtons(
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
||||
data = {u'message': message}
|
||||
data[u'title'] = title if title else error
|
||||
return Receiver.send_message(u'openlp_error_message', data)
|
||||
|
||||
from themeform import ThemeForm
|
||||
from filerenameform import FileRenameForm
|
||||
from starttimeform import StartTimeForm
|
||||
from maindisplay import MainDisplay
|
||||
from servicenoteform import ServiceNoteForm
|
||||
from serviceitemeditform import ServiceItemEditForm
|
||||
@ -99,6 +72,6 @@ from mediadockmanager import MediaDockManager
|
||||
from servicemanager import ServiceManager
|
||||
from thememanager import ThemeManager
|
||||
|
||||
__all__ = ['criticalErrorMessageBox', 'SplashScreen', 'AboutForm',
|
||||
'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager',
|
||||
'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm']
|
||||
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay',
|
||||
'SlideController', 'ServiceManager', 'ThemeManager', 'MediaDockManager',
|
||||
'ServiceItemEditForm']
|
||||
|
@ -164,9 +164,10 @@ class Ui_AboutDialog(object):
|
||||
self.licenseTextEdit.setPlainText(translate('OpenLP.AboutForm',
|
||||
'Copyright \xa9 2004-2011 Raoul Snyman\n'
|
||||
'Portions copyright \xa9 2004-2011 '
|
||||
'Tim Bentley, Jonathan Corwin, Michael Gorven, Scott Guerrieri, '
|
||||
'Christian Richter, Maikel Stuivenberg, Martin Thompson, Jon '
|
||||
'Tibble, Carsten Tinggaard\n'
|
||||
'Tim Bentley, Jonathan Corwin, Michael Gorven, Scott Guerrieri,\n'
|
||||
'Meinert Jordan, Andreas Preikschat, Christian Richter, Philip\n'
|
||||
'Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Carstenn'
|
||||
'Tinggaard, Frode Woldsund\n'
|
||||
'\n'
|
||||
'This program is free software; you can redistribute it and/or '
|
||||
'modify it under the terms of the GNU General Public License as '
|
||||
|
@ -29,6 +29,7 @@ The :mod:`advancedtab` provides an advanced settings facility.
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import SettingsTab, translate
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
||||
class AdvancedTab(SettingsTab):
|
||||
"""
|
||||
@ -112,7 +113,7 @@ class AdvancedTab(SettingsTab):
|
||||
"""
|
||||
Setup the interface translation strings.
|
||||
"""
|
||||
self.tabTitleVisible = translate('OpenLP.AdvancedTab', 'Advanced')
|
||||
self.tabTitleVisible = UiStrings.Advanced
|
||||
self.uiGroupBox.setTitle(translate('OpenLP.AdvancedTab', 'UI Settings'))
|
||||
self.recentLabel.setText(
|
||||
translate('OpenLP.AdvancedTab',
|
||||
|
@ -23,27 +23,27 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
'''
|
||||
"""
|
||||
The :mod:`DisplayTagTab` provides an Tag Edit facility. The Base set are
|
||||
protected and included each time loaded. Custom tags can be defined and saved.
|
||||
The Custom Tag arrays are saved in a pickle so QSettings works on them. Base
|
||||
Tags cannot be changed.
|
||||
|
||||
'''
|
||||
"""
|
||||
import cPickle
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import SettingsTab, translate, DisplayTags
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
|
||||
class DisplayTagTab(SettingsTab):
|
||||
'''
|
||||
"""
|
||||
The :class:`DisplayTagTab` manages the settings tab .
|
||||
'''
|
||||
"""
|
||||
def __init__(self):
|
||||
'''
|
||||
"""
|
||||
Initialise the settings tab
|
||||
'''
|
||||
"""
|
||||
SettingsTab.__init__(self, u'Display Tags')
|
||||
|
||||
def resizeEvent(self, event=None):
|
||||
@ -67,9 +67,9 @@ class DisplayTagTab(SettingsTab):
|
||||
self.selected = -1
|
||||
|
||||
def setupUi(self):
|
||||
'''
|
||||
"""
|
||||
Configure the UI elements for the tab.
|
||||
'''
|
||||
"""
|
||||
self.setObjectName(u'DisplayTagTab')
|
||||
self.tabTitleVisible = \
|
||||
translate(u'OpenLP.DisplayTagTab', 'Display Tags')
|
||||
@ -164,8 +164,7 @@ class DisplayTagTab(SettingsTab):
|
||||
self.startTagLabel.setText(
|
||||
translate('OpenLP.DisplayTagTab', 'Start tag'))
|
||||
self.endTagLabel.setText(translate('OpenLP.DisplayTagTab', 'End tag'))
|
||||
self.deletePushButton.setText(
|
||||
translate('OpenLP.DisplayTagTab', 'Delete'))
|
||||
self.deletePushButton.setText(UiStrings.Delete)
|
||||
self.defaultPushButton.setText(
|
||||
translate('OpenLP.DisplayTagTab', 'Default'))
|
||||
self.newPushButton.setText(translate('OpenLP.DisplayTagTab', 'New'))
|
||||
@ -276,7 +275,7 @@ class DisplayTagTab(SettingsTab):
|
||||
"""
|
||||
for html in DisplayTags.get_html_tags():
|
||||
if self._strip(html[u'start tag']) == u'n':
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
||||
translate('OpenLP.DisplayTagTab',
|
||||
'Tag "n" already defined.'))
|
||||
@ -317,7 +316,7 @@ class DisplayTagTab(SettingsTab):
|
||||
for linenumber, html1 in enumerate(html_expands):
|
||||
if self._strip(html1[u'start tag']) == tag and \
|
||||
linenumber != self.selected:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
||||
unicode(translate('OpenLP.DisplayTagTab',
|
||||
'Tag %s already defined.')) % tag)
|
||||
|
@ -46,6 +46,15 @@ class Ui_ExceptionDialog(object):
|
||||
self.messageLabel.setObjectName(u'messageLabel')
|
||||
self.messageLayout.addWidget(self.messageLabel)
|
||||
self.exceptionLayout.addLayout(self.messageLayout)
|
||||
self.descriptionExplanation = QtGui.QLabel(exceptionDialog)
|
||||
self.descriptionExplanation.setObjectName(u'descriptionExplanation')
|
||||
self.exceptionLayout.addWidget(self.descriptionExplanation)
|
||||
self.descriptionTextEdit = QtGui.QPlainTextEdit(exceptionDialog)
|
||||
self.descriptionTextEdit.setObjectName(u'descriptionTextEdit')
|
||||
self.exceptionLayout.addWidget(self.descriptionTextEdit)
|
||||
self.descriptionWordCount = QtGui.QLabel(exceptionDialog)
|
||||
self.descriptionWordCount.setObjectName(u'descriptionWordCount')
|
||||
self.exceptionLayout.addWidget(self.descriptionWordCount)
|
||||
self.exceptionTextEdit = QtGui.QPlainTextEdit(exceptionDialog)
|
||||
self.exceptionTextEdit.setReadOnly(True)
|
||||
self.exceptionTextEdit.setObjectName(u'exceptionTextEdit')
|
||||
@ -65,19 +74,31 @@ class Ui_ExceptionDialog(object):
|
||||
self.saveReportButton.setObjectName(u'saveReportButton')
|
||||
self.exceptionButtonBox.addButton(self.saveReportButton,
|
||||
QtGui.QDialogButtonBox.ActionRole)
|
||||
self.attachFileButton = QtGui.QPushButton(exceptionDialog)
|
||||
self.attachFileButton.setIcon(build_icon(u':/general/general_open.png'))
|
||||
self.attachFileButton.setObjectName(u'attachFileButton')
|
||||
self.exceptionButtonBox.addButton(self.attachFileButton,
|
||||
QtGui.QDialogButtonBox.ActionRole)
|
||||
|
||||
self.retranslateUi(exceptionDialog)
|
||||
QtCore.QObject.connect(self.descriptionTextEdit,
|
||||
QtCore.SIGNAL(u'textChanged()'), self.onDescriptionUpdated)
|
||||
QtCore.QObject.connect(self.exceptionButtonBox,
|
||||
QtCore.SIGNAL(u'rejected()'), exceptionDialog.reject)
|
||||
QtCore.QObject.connect(self.sendReportButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onSendReportButtonPressed)
|
||||
QtCore.QObject.connect(self.saveReportButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onSaveReportButtonPressed)
|
||||
QtCore.QObject.connect(self.attachFileButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onAttachFileButtonPressed)
|
||||
QtCore.QMetaObject.connectSlotsByName(exceptionDialog)
|
||||
|
||||
def retranslateUi(self, exceptionDialog):
|
||||
exceptionDialog.setWindowTitle(
|
||||
translate('OpenLP.ExceptionDialog', 'Error Occurred'))
|
||||
self.descriptionExplanation.setText(translate('OpenLP.ExceptionDialog',
|
||||
'Please enter a description of what you were doing to cause this '
|
||||
'error \n(Minimum 20 characters)'))
|
||||
self.messageLabel.setText(translate('OpenLP.ExceptionDialog', 'Oops! '
|
||||
'OpenLP hit a problem, and couldn\'t recover. The text in the box '
|
||||
'below contains information that might be helpful to the OpenLP '
|
||||
@ -88,3 +109,5 @@ class Ui_ExceptionDialog(object):
|
||||
'Send E-Mail'))
|
||||
self.saveReportButton.setText(translate('OpenLP.ExceptionDialog',
|
||||
'Save to File'))
|
||||
self.attachFileButton.setText(translate('OpenLP.ExceptionDialog',
|
||||
'Attach File'))
|
||||
|
@ -56,6 +56,7 @@ except ImportError:
|
||||
|
||||
from openlp.core.lib import translate, SettingsManager
|
||||
from openlp.core.lib.mailto import mailto
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
||||
from exceptiondialog import Ui_ExceptionDialog
|
||||
|
||||
@ -70,8 +71,15 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
||||
self.setupUi(self)
|
||||
self.settingsSection = u'crashreport'
|
||||
|
||||
def exec_(self):
|
||||
self.descriptionTextEdit.setPlainText(u'')
|
||||
self.onDescriptionUpdated()
|
||||
self.fileAttachment = None
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def _createReport(self):
|
||||
openlp_version = self.parent().applicationVersion[u'full']
|
||||
description = unicode(self.descriptionTextEdit.toPlainText())
|
||||
traceback = unicode(self.exceptionTextEdit.toPlainText())
|
||||
system = unicode(translate('OpenLP.ExceptionForm',
|
||||
'Platform: %s\n')) % platform.platform()
|
||||
@ -90,7 +98,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
||||
system = system + u'Desktop: KDE SC\n'
|
||||
elif os.environ.get(u'GNOME_DESKTOP_SESSION_ID'):
|
||||
system = system + u'Desktop: GNOME\n'
|
||||
return (openlp_version, traceback, system, libraries)
|
||||
return (openlp_version, description, traceback, system, libraries)
|
||||
|
||||
def onSaveReportButtonPressed(self):
|
||||
"""
|
||||
@ -99,6 +107,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
||||
report = unicode(translate('OpenLP.ExceptionForm',
|
||||
'**OpenLP Bug Report**\n'
|
||||
'Version: %s\n\n'
|
||||
'--- Details of the Exception. ---\n\n%s\n\n '
|
||||
'--- Exception Traceback ---\n%s\n'
|
||||
'--- System information ---\n%s\n'
|
||||
'--- Library Versions ---\n%s\n'))
|
||||
@ -132,18 +141,47 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
||||
body = unicode(translate('OpenLP.ExceptionForm',
|
||||
'*OpenLP Bug Report*\n'
|
||||
'Version: %s\n\n'
|
||||
'--- Please enter the report below this line. ---\n\n\n'
|
||||
'--- Details of the Exception. ---\n\n%s\n\n '
|
||||
'--- Exception Traceback ---\n%s\n'
|
||||
'--- System information ---\n%s\n'
|
||||
'--- Library Versions ---\n%s\n',
|
||||
'Please add the information that bug reports are favoured written '
|
||||
'in English.'))
|
||||
content = self._createReport()
|
||||
for line in content[1].split(u'\n'):
|
||||
for line in content[2].split(u'\n'):
|
||||
if re.search(r'[/\\]openlp[/\\]', line):
|
||||
source = re.sub(r'.*[/\\]openlp[/\\](.*)".*', r'\1', line)
|
||||
if u':' in line:
|
||||
exception = line.split(u'\n')[-1].split(u':')[0]
|
||||
subject = u'Bug report: %s in %s' % (exception, source)
|
||||
mailto(address=u'bugs@openlp.org', subject=subject,
|
||||
body=body % content)
|
||||
if self.fileAttachment:
|
||||
mailto(address=u'bugs@openlp.org', subject=subject,
|
||||
body=body % content, attach=self.fileAttachment)
|
||||
else:
|
||||
mailto(address=u'bugs@openlp.org', subject=subject,
|
||||
body=body % content)
|
||||
|
||||
def onDescriptionUpdated(self):
|
||||
count = int(20 - len(self.descriptionTextEdit.toPlainText()))
|
||||
if count < 0:
|
||||
count = 0
|
||||
self.__buttonState(True)
|
||||
else:
|
||||
self.__buttonState(False)
|
||||
self.descriptionWordCount.setText(
|
||||
unicode(translate('OpenLP.ExceptionDialog',
|
||||
'Description characters to enter : %s')) % count )
|
||||
|
||||
def onAttachFileButtonPressed(self):
|
||||
files = QtGui.QFileDialog.getOpenFileName(
|
||||
self,translate('ImagePlugin.ExceptionDialog',
|
||||
'Select Attachment'),
|
||||
SettingsManager.get_last_dir(u'exceptions'),
|
||||
u'%s (*.*) (*)' % UiStrings.AllFiles)
|
||||
log.info(u'New files(s) %s', unicode(files))
|
||||
if files:
|
||||
self.fileAttachment = unicode(files)
|
||||
|
||||
def __buttonState(self, state):
|
||||
self.saveReportButton.setEnabled(state)
|
||||
self.sendReportButton.setEnabled(state)
|
||||
|
@ -27,30 +27,28 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import create_accept_reject_button_box
|
||||
|
||||
class Ui_FileRenameDialog(object):
|
||||
def setupUi(self, FileRenameDialog):
|
||||
FileRenameDialog.setObjectName(u'FileRenameDialog')
|
||||
FileRenameDialog.resize(300, 10)
|
||||
self.dialogLayout = QtGui.QGridLayout(FileRenameDialog)
|
||||
def setupUi(self, fileRenameDialog):
|
||||
fileRenameDialog.setObjectName(u'fileRenameDialog')
|
||||
fileRenameDialog.resize(300, 10)
|
||||
self.dialogLayout = QtGui.QGridLayout(fileRenameDialog)
|
||||
self.dialogLayout.setObjectName(u'dialogLayout')
|
||||
self.fileNameLabel = QtGui.QLabel(FileRenameDialog)
|
||||
self.fileNameLabel = QtGui.QLabel(fileRenameDialog)
|
||||
self.fileNameLabel.setObjectName(u'fileNameLabel')
|
||||
self.dialogLayout.addWidget(self.fileNameLabel, 0, 0)
|
||||
self.fileNameEdit = QtGui.QLineEdit(FileRenameDialog)
|
||||
self.fileNameEdit = QtGui.QLineEdit(fileRenameDialog)
|
||||
self.fileNameEdit.setValidator(QtGui.QRegExpValidator(
|
||||
QtCore.QRegExp(r'[^/\\?*|<>\[\]":<>+%]+'), self))
|
||||
self.fileNameEdit.setObjectName(u'fileNameEdit')
|
||||
self.dialogLayout.addWidget(self.fileNameEdit, 0, 1)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(FileRenameDialog)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
|
||||
QtGui.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.buttonBox = create_accept_reject_button_box(fileRenameDialog, True)
|
||||
self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2)
|
||||
self.retranslateUi(FileRenameDialog)
|
||||
self.retranslateUi(fileRenameDialog)
|
||||
self.setMaximumHeight(self.sizeHint().height())
|
||||
QtCore.QMetaObject.connectSlotsByName(FileRenameDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(fileRenameDialog)
|
||||
|
||||
def retranslateUi(self, FileRenameDialog):
|
||||
def retranslateUi(self, fileRenameDialog):
|
||||
self.fileNameLabel.setText(translate('OpenLP.FileRenameForm',
|
||||
'New File Name:'))
|
||||
|
@ -24,7 +24,7 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt4 import QtGui
|
||||
|
||||
from filerenamedialog import Ui_FileRenameDialog
|
||||
|
||||
@ -37,10 +37,6 @@ class FileRenameForm(QtGui.QDialog, Ui_FileRenameDialog):
|
||||
def __init__(self, parent):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
|
||||
self.accept)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
|
||||
self.reject)
|
||||
|
||||
def exec_(self, copy=False):
|
||||
"""
|
||||
@ -51,5 +47,5 @@ class FileRenameForm(QtGui.QDialog, Ui_FileRenameDialog):
|
||||
'File Copy'))
|
||||
else:
|
||||
self.setWindowTitle(translate('OpenLP.FileRenameForm',
|
||||
'File Rename'))
|
||||
'File Rename'))
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
@ -51,6 +51,7 @@ class ValidEdit(QtGui.QLineEdit):
|
||||
else:
|
||||
return self.text()
|
||||
|
||||
|
||||
class GeneralTab(SettingsTab):
|
||||
"""
|
||||
GeneralTab is the general settings tab in the settings dialog.
|
||||
@ -113,6 +114,9 @@ class GeneralTab(SettingsTab):
|
||||
self.showSplashCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
||||
self.showSplashCheckBox.setObjectName(u'showSplashCheckBox')
|
||||
self.startupLayout.addWidget(self.showSplashCheckBox)
|
||||
self.checkForUpdatesCheckBox = QtGui.QCheckBox(self.startupGroupBox)
|
||||
self.checkForUpdatesCheckBox.setObjectName(u'checkForUpdatesCheckBox')
|
||||
self.startupLayout.addWidget(self.checkForUpdatesCheckBox)
|
||||
self.leftLayout.addWidget(self.startupGroupBox)
|
||||
self.settingsGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.settingsGroupBox.setObjectName(u'settingsGroupBox')
|
||||
@ -249,6 +253,8 @@ class GeneralTab(SettingsTab):
|
||||
'Automatically open the last service'))
|
||||
self.showSplashCheckBox.setText(
|
||||
translate('OpenLP.GeneralTab', 'Show the splash screen'))
|
||||
self.checkForUpdatesCheckBox.setText(
|
||||
translate('OpenLP.GeneralTab', 'Check for updates to OpenLP'))
|
||||
self.settingsGroupBox.setTitle(
|
||||
translate('OpenLP.GeneralTab', 'Application Settings'))
|
||||
self.saveCheckServiceCheckBox.setText(translate('OpenLP.GeneralTab',
|
||||
@ -317,6 +323,8 @@ class GeneralTab(SettingsTab):
|
||||
QtCore.QVariant(False)).toBool())
|
||||
self.showSplashCheckBox.setChecked(settings.value(u'show splash',
|
||||
QtCore.QVariant(True)).toBool())
|
||||
self.checkForUpdatesCheckBox.setChecked(settings.value(u'update check',
|
||||
QtCore.QVariant(True)).toBool())
|
||||
self.autoPreviewCheckBox.setChecked(settings.value(u'auto preview',
|
||||
QtCore.QVariant(False)).toBool())
|
||||
self.timeoutSpinBox.setValue(settings.value(u'loop delay',
|
||||
@ -363,6 +371,8 @@ class GeneralTab(SettingsTab):
|
||||
QtCore.QVariant(self.autoOpenCheckBox.isChecked()))
|
||||
settings.setValue(u'show splash',
|
||||
QtCore.QVariant(self.showSplashCheckBox.isChecked()))
|
||||
settings.setValue(u'update check',
|
||||
QtCore.QVariant(self.checkForUpdatesCheckBox.isChecked()))
|
||||
settings.setValue(u'save prompt',
|
||||
QtCore.QVariant(self.saveCheckServiceCheckBox.isChecked()))
|
||||
settings.setValue(u'auto preview',
|
||||
|
@ -67,11 +67,12 @@ class MainDisplay(DisplayWidget):
|
||||
self.isLive = live
|
||||
self.alertTab = None
|
||||
self.hideMode = None
|
||||
self.override = {}
|
||||
mainIcon = build_icon(u':/icon/openlp-logo-16x16.png')
|
||||
self.setWindowIcon(mainIcon)
|
||||
self.retranslateUi()
|
||||
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
|
||||
self.setWindowFlags(QtCore.Qt.FramelessWindowHint |
|
||||
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
|
||||
QtCore.Qt.WindowStaysOnTopHint)
|
||||
if self.isLive:
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
@ -105,13 +106,16 @@ class MainDisplay(DisplayWidget):
|
||||
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
|
||||
Phonon.createPath(self.mediaObject, self.videoWidget)
|
||||
Phonon.createPath(self.mediaObject, self.audio)
|
||||
QtCore.QObject.connect(self.mediaObject,
|
||||
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
|
||||
self.videoStart)
|
||||
self.webView = QtWebKit.QWebView(self)
|
||||
self.webView.setGeometry(0, 0,
|
||||
self.screen[u'size'].width(), self.screen[u'size'].height())
|
||||
self.page = self.webView.page()
|
||||
self.frame = self.page.mainFrame()
|
||||
QtCore.QObject.connect(self.webView,
|
||||
QtCore.SIGNAL(u'loadFinished(bool)'), self.isLoaded)
|
||||
QtCore.SIGNAL(u'loadFinished(bool)'), self.isWebLoaded)
|
||||
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical,
|
||||
@ -137,14 +141,14 @@ class MainDisplay(DisplayWidget):
|
||||
painter_image.begin(initialFrame)
|
||||
painter_image.fillRect(initialFrame.rect(), QtCore.Qt.white)
|
||||
painter_image.drawImage(
|
||||
(self.screens.current[u'size'].width() -
|
||||
(self.screens.current[u'size'].width() -
|
||||
splash_image.width()) / 2,
|
||||
(self.screens.current[u'size'].height()
|
||||
- splash_image.height()) / 2, splash_image)
|
||||
serviceItem = ServiceItem()
|
||||
serviceItem.bg_image_bytes = image_to_byte(initialFrame)
|
||||
self.webView.setHtml(build_html(serviceItem, self.screen,
|
||||
self.parent.alertTab, self.isLive))
|
||||
self.alertTab, self.isLive, None))
|
||||
self.initialFrame = True
|
||||
# To display or not to display?
|
||||
if not self.screen[u'primary']:
|
||||
@ -162,7 +166,7 @@ class MainDisplay(DisplayWidget):
|
||||
"""
|
||||
log.debug(u'text to display')
|
||||
# Wait for the webview to update before displaying text.
|
||||
while not self.loaded:
|
||||
while not self.webLoaded:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.frame.evaluateJavaScript(u'show_text("%s")' % \
|
||||
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
||||
@ -204,14 +208,17 @@ class MainDisplay(DisplayWidget):
|
||||
"""
|
||||
self.imageManager.add_image(name, path)
|
||||
self.image(name)
|
||||
if hasattr(self, u'serviceItem'):
|
||||
self.override[u'image'] = name
|
||||
self.override[u'theme'] = self.serviceItem.themedata.theme_name
|
||||
|
||||
def image(self, name):
|
||||
"""
|
||||
Add an image as the background. The image is converted to a bytestream
|
||||
on route.
|
||||
Add an image as the background. The image has already been added
|
||||
to the cache.
|
||||
|
||||
`Image`
|
||||
The Image to be displayed can be QImage or QPixmap
|
||||
The name of the image to be displayed
|
||||
"""
|
||||
log.debug(u'image to display')
|
||||
image = self.imageManager.get_image_bytes(name)
|
||||
@ -244,6 +251,7 @@ class MainDisplay(DisplayWidget):
|
||||
self.displayImage(self.serviceItem.bg_image_bytes)
|
||||
else:
|
||||
self.displayImage(None)
|
||||
self.override = {}
|
||||
# Update the preview frame.
|
||||
Receiver.send_message(u'maindisplay_active')
|
||||
|
||||
@ -260,6 +268,7 @@ class MainDisplay(DisplayWidget):
|
||||
self.phononActive = False
|
||||
else:
|
||||
self.frame.evaluateJavaScript(u'show_video("close");')
|
||||
self.override = {}
|
||||
# Update the preview frame.
|
||||
Receiver.send_message(u'maindisplay_active')
|
||||
|
||||
@ -313,12 +322,14 @@ class MainDisplay(DisplayWidget):
|
||||
Loads and starts a video to run with the option of sound
|
||||
"""
|
||||
log.debug(u'video')
|
||||
self.loaded = True
|
||||
self.webLoaded = True
|
||||
# We are running a background theme
|
||||
self.override[u'theme'] = u''
|
||||
self.override[u'video'] = True
|
||||
vol = float(volume)/float(10)
|
||||
if isBackground or not self.usePhonon:
|
||||
js = u'show_video("init", "%s", %s, true); show_video("play");' % \
|
||||
(videoPath.replace(u'\\', u'\\\\'), \
|
||||
str(vol))
|
||||
(videoPath.replace(u'\\', u'\\\\'), str(vol))
|
||||
self.frame.evaluateJavaScript(js)
|
||||
else:
|
||||
self.phononActive = True
|
||||
@ -333,12 +344,19 @@ class MainDisplay(DisplayWidget):
|
||||
Receiver.send_message(u'maindisplay_active')
|
||||
return self.preview()
|
||||
|
||||
def isLoaded(self):
|
||||
def videoStart(self, newState, oldState):
|
||||
"""
|
||||
Start the video at a predetermined point.
|
||||
"""
|
||||
if newState == Phonon.PlayingState:
|
||||
self.mediaObject.seek(self.serviceItem.start_time * 1000)
|
||||
|
||||
def isWebLoaded(self):
|
||||
"""
|
||||
Called by webView event to show display is fully loaded
|
||||
"""
|
||||
log.debug(u'loaded')
|
||||
self.loaded = True
|
||||
log.debug(u'Webloaded')
|
||||
self.webLoaded = True
|
||||
|
||||
def preview(self):
|
||||
"""
|
||||
@ -357,7 +375,7 @@ class MainDisplay(DisplayWidget):
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
# Wait for the webview to update before geting the preview.
|
||||
# Important otherwise first preview will miss the background !
|
||||
while not self.loaded:
|
||||
while not self.webLoaded:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
# if was hidden keep it hidden
|
||||
if self.isLive:
|
||||
@ -379,18 +397,31 @@ class MainDisplay(DisplayWidget):
|
||||
HTML to the display
|
||||
"""
|
||||
log.debug(u'buildHtml')
|
||||
self.loaded = False
|
||||
self.webLoaded = False
|
||||
self.initialFrame = False
|
||||
self.serviceItem = serviceItem
|
||||
background = None
|
||||
# We have an image override so keep the image till the theme changes
|
||||
if self.override:
|
||||
# We have an video override so allow it to be stopped
|
||||
if u'video' in self.override:
|
||||
Receiver.send_message(u'video_background_replaced')
|
||||
self.override = {}
|
||||
elif self.override[u'theme'] != serviceItem.themedata.theme_name:
|
||||
Receiver.send_message(u'live_theme_changed')
|
||||
self.override = {}
|
||||
else:
|
||||
background = self.imageManager. \
|
||||
get_image_bytes(self.override[u'image'])
|
||||
if self.serviceItem.themedata.background_filename:
|
||||
self.serviceItem.bg_image_bytes = self.imageManager. \
|
||||
get_image_bytes(self.serviceItem.themedata.theme_name)
|
||||
html = build_html(self.serviceItem, self.screen, self.parent.alertTab,
|
||||
self.isLive)
|
||||
html = build_html(self.serviceItem, self.screen, self.alertTab,
|
||||
self.isLive, background)
|
||||
log.debug(u'buildHtml - pre setHtml')
|
||||
self.webView.setHtml(html)
|
||||
log.debug(u'buildHtml - post setHtml')
|
||||
if serviceItem.foot_text and serviceItem.foot_text:
|
||||
if serviceItem.foot_text:
|
||||
self.footer(serviceItem.foot_text)
|
||||
# if was hidden keep it hidden
|
||||
if self.hideMode and self.isLive:
|
||||
|
@ -28,11 +28,13 @@ import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
|
||||
SettingsManager, PluginManager, Receiver, translate
|
||||
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
|
||||
icon_action
|
||||
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
|
||||
ThemeManager, SlideController, PluginForm, MediaDockManager, \
|
||||
ShortcutListForm
|
||||
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
|
||||
SettingsManager, PluginManager, Receiver, translate
|
||||
from openlp.core.utils import AppLocation, add_actions, LanguageManager, \
|
||||
ActionList
|
||||
|
||||
@ -76,10 +78,10 @@ class Ui_MainWindow(object):
|
||||
self.MainContentLayout.setMargin(0)
|
||||
self.MainContentLayout.setObjectName(u'MainContentLayout')
|
||||
mainWindow.setCentralWidget(self.MainContent)
|
||||
self.ControlSplitter = QtGui.QSplitter(self.MainContent)
|
||||
self.ControlSplitter.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.ControlSplitter.setObjectName(u'ControlSplitter')
|
||||
self.MainContentLayout.addWidget(self.ControlSplitter)
|
||||
self.controlSplitter = QtGui.QSplitter(self.MainContent)
|
||||
self.controlSplitter.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.controlSplitter.setObjectName(u'controlSplitter')
|
||||
self.MainContentLayout.addWidget(self.controlSplitter)
|
||||
# Create slide controllers
|
||||
self.previewController = SlideController(self, self.settingsmanager,
|
||||
self.screens)
|
||||
@ -87,10 +89,10 @@ class Ui_MainWindow(object):
|
||||
self.screens, True)
|
||||
previewVisible = QtCore.QSettings().value(
|
||||
u'user interface/preview panel', QtCore.QVariant(True)).toBool()
|
||||
self.previewController.Panel.setVisible(previewVisible)
|
||||
self.previewController.panel.setVisible(previewVisible)
|
||||
liveVisible = QtCore.QSettings().value(u'user interface/live panel',
|
||||
QtCore.QVariant(True)).toBool()
|
||||
self.liveController.Panel.setVisible(liveVisible)
|
||||
self.liveController.panel.setVisible(liveVisible)
|
||||
# Create menu
|
||||
self.MenuBar = QtGui.QMenuBar(mainWindow)
|
||||
self.MenuBar.setObjectName(u'MenuBar')
|
||||
@ -101,9 +103,9 @@ class Ui_MainWindow(object):
|
||||
self.FileExportMenu = QtGui.QMenu(self.FileMenu)
|
||||
self.FileExportMenu.setObjectName(u'FileExportMenu')
|
||||
# View Menu
|
||||
self.ViewMenu = QtGui.QMenu(self.MenuBar)
|
||||
self.ViewMenu.setObjectName(u'ViewMenu')
|
||||
self.ViewModeMenu = QtGui.QMenu(self.ViewMenu)
|
||||
self.viewMenu = QtGui.QMenu(self.MenuBar)
|
||||
self.viewMenu.setObjectName(u'viewMenu')
|
||||
self.ViewModeMenu = QtGui.QMenu(self.viewMenu)
|
||||
self.ViewModeMenu.setObjectName(u'ViewModeMenu')
|
||||
# Tools Menu
|
||||
self.ToolsMenu = QtGui.QMenu(self.MenuBar)
|
||||
@ -124,135 +126,106 @@ class Ui_MainWindow(object):
|
||||
self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel')
|
||||
self.StatusBar.addPermanentWidget(self.DefaultThemeLabel)
|
||||
# Create the MediaManager
|
||||
self.MediaManagerDock = OpenLPDockWidget(
|
||||
mainWindow, u'MediaManagerDock',
|
||||
build_icon(u':/system/system_mediamanager.png'))
|
||||
self.MediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE)
|
||||
self.MediaManagerDock.setMinimumWidth(
|
||||
self.mediaManagerDock = OpenLPDockWidget(mainWindow,
|
||||
u'mediaManagerDock', u':/system/system_mediamanager.png')
|
||||
self.mediaManagerDock.setStyleSheet(MEDIA_MANAGER_STYLE)
|
||||
self.mediaManagerDock.setMinimumWidth(
|
||||
self.settingsmanager.mainwindow_left)
|
||||
# Create the media toolbox
|
||||
self.MediaToolBox = QtGui.QToolBox(self.MediaManagerDock)
|
||||
self.MediaToolBox = QtGui.QToolBox(self.mediaManagerDock)
|
||||
self.MediaToolBox.setObjectName(u'MediaToolBox')
|
||||
self.MediaManagerDock.setWidget(self.MediaToolBox)
|
||||
self.mediaManagerDock.setWidget(self.MediaToolBox)
|
||||
mainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea,
|
||||
self.MediaManagerDock)
|
||||
self.mediaManagerDock)
|
||||
# Create the service manager
|
||||
self.ServiceManagerDock = OpenLPDockWidget(
|
||||
mainWindow, u'ServiceManagerDock',
|
||||
build_icon(u':/system/system_servicemanager.png'))
|
||||
self.ServiceManagerDock.setMinimumWidth(
|
||||
self.serviceManagerDock = OpenLPDockWidget(mainWindow,
|
||||
u'serviceManagerDock', u':/system/system_servicemanager.png')
|
||||
self.serviceManagerDock.setMinimumWidth(
|
||||
self.settingsmanager.mainwindow_right)
|
||||
self.ServiceManagerContents = ServiceManager(mainWindow,
|
||||
self.ServiceManagerDock)
|
||||
self.ServiceManagerDock.setWidget(self.ServiceManagerContents)
|
||||
self.serviceManagerDock)
|
||||
self.serviceManagerDock.setWidget(self.ServiceManagerContents)
|
||||
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
|
||||
self.ServiceManagerDock)
|
||||
self.serviceManagerDock)
|
||||
# Create the theme manager
|
||||
self.ThemeManagerDock = OpenLPDockWidget(
|
||||
mainWindow, u'ThemeManagerDock',
|
||||
build_icon(u':/system/system_thememanager.png'))
|
||||
self.ThemeManagerDock.setMinimumWidth(
|
||||
self.themeManagerDock = OpenLPDockWidget(mainWindow,
|
||||
u'themeManagerDock', u':/system/system_thememanager.png')
|
||||
self.themeManagerDock.setMinimumWidth(
|
||||
self.settingsmanager.mainwindow_right)
|
||||
self.ThemeManagerContents = ThemeManager(mainWindow,
|
||||
self.ThemeManagerDock)
|
||||
self.themeManagerDock)
|
||||
self.ThemeManagerContents.setObjectName(u'ThemeManagerContents')
|
||||
self.ThemeManagerDock.setWidget(self.ThemeManagerContents)
|
||||
self.themeManagerDock.setWidget(self.ThemeManagerContents)
|
||||
mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea,
|
||||
self.ThemeManagerDock)
|
||||
self.themeManagerDock)
|
||||
# Create the menu items
|
||||
self.FileNewItem = QtGui.QAction(mainWindow)
|
||||
self.FileNewItem.setIcon(build_icon(u':/general/general_new.png'))
|
||||
self.FileNewItem.setObjectName(u'FileNewItem')
|
||||
self.FileNewItem = icon_action(mainWindow, u'FileNewItem',
|
||||
u':/general/general_new.png')
|
||||
mainWindow.actionList.add_action(self.FileNewItem, u'File')
|
||||
self.FileOpenItem = QtGui.QAction(mainWindow)
|
||||
self.FileOpenItem.setIcon(build_icon(u':/general/general_open.png'))
|
||||
self.FileOpenItem.setObjectName(u'FileOpenItem')
|
||||
self.FileOpenItem = icon_action(mainWindow, u'FileOpenItem',
|
||||
u':/general/general_open.png')
|
||||
mainWindow.actionList.add_action(self.FileOpenItem, u'File')
|
||||
self.FileSaveItem = QtGui.QAction(mainWindow)
|
||||
self.FileSaveItem.setIcon(build_icon(u':/general/general_save.png'))
|
||||
self.FileSaveItem.setObjectName(u'FileSaveItem')
|
||||
self.FileSaveItem = icon_action(mainWindow, u'FileSaveItem',
|
||||
u':/general/general_save.png')
|
||||
mainWindow.actionList.add_action(self.FileSaveItem, u'File')
|
||||
self.FileSaveAsItem = QtGui.QAction(mainWindow)
|
||||
self.FileSaveAsItem.setObjectName(u'FileSaveAsItem')
|
||||
self.FileSaveAsItem = base_action(mainWindow, u'FileSaveAsItem')
|
||||
mainWindow.actionList.add_action(self.FileSaveAsItem, u'File')
|
||||
self.FileExitItem = QtGui.QAction(mainWindow)
|
||||
self.FileExitItem.setIcon(build_icon(u':/system/system_exit.png'))
|
||||
self.FileExitItem.setObjectName(u'FileExitItem')
|
||||
self.printServiceOrderItem = base_action(
|
||||
mainWindow, u'printServiceItem')
|
||||
mainWindow.actionList.add_action(
|
||||
self.printServiceOrderItem, u'Print Service Order')
|
||||
self.FileExitItem = icon_action(mainWindow, u'FileExitItem',
|
||||
u':/system/system_exit.png')
|
||||
mainWindow.actionList.add_action(self.FileExitItem, u'File')
|
||||
self.ImportThemeItem = QtGui.QAction(mainWindow)
|
||||
self.ImportThemeItem.setObjectName(u'ImportThemeItem')
|
||||
self.ImportThemeItem = base_action(mainWindow, u'ImportThemeItem')
|
||||
mainWindow.actionList.add_action(self.ImportThemeItem, u'Import')
|
||||
self.ImportLanguageItem = QtGui.QAction(mainWindow)
|
||||
self.ImportLanguageItem.setObjectName(u'ImportLanguageItem')
|
||||
self.ImportLanguageItem = base_action(mainWindow, u'ImportLanguageItem')
|
||||
mainWindow.actionList.add_action(self.ImportLanguageItem, u'Import')
|
||||
self.ExportThemeItem = QtGui.QAction(mainWindow)
|
||||
self.ExportThemeItem.setObjectName(u'ExportThemeItem')
|
||||
self.ExportThemeItem = base_action(mainWindow, u'ExportThemeItem')
|
||||
mainWindow.actionList.add_action(self.ExportThemeItem, u'Export')
|
||||
self.ExportLanguageItem = QtGui.QAction(mainWindow)
|
||||
self.ExportLanguageItem.setObjectName(u'ExportLanguageItem')
|
||||
self.ExportLanguageItem = base_action(mainWindow, u'ExportLanguageItem')
|
||||
mainWindow.actionList.add_action(self.ExportLanguageItem, u'Export')
|
||||
self.ViewMediaManagerItem = QtGui.QAction(mainWindow)
|
||||
self.ViewMediaManagerItem.setCheckable(True)
|
||||
self.ViewMediaManagerItem.setChecked(self.MediaManagerDock.isVisible())
|
||||
self.ViewMediaManagerItem.setIcon(
|
||||
build_icon(u':/system/system_mediamanager.png'))
|
||||
self.ViewMediaManagerItem.setObjectName(u'ViewMediaManagerItem')
|
||||
self.ViewThemeManagerItem = QtGui.QAction(mainWindow)
|
||||
self.ViewThemeManagerItem.setCheckable(True)
|
||||
self.ViewThemeManagerItem.setChecked(self.ThemeManagerDock.isVisible())
|
||||
self.ViewThemeManagerItem.setIcon(
|
||||
build_icon(u':/system/system_thememanager.png'))
|
||||
self.ViewThemeManagerItem.setObjectName(u'ViewThemeManagerItem')
|
||||
self.ViewMediaManagerItem = icon_action(mainWindow,
|
||||
u'ViewMediaManagerItem', u':/system/system_mediamanager.png',
|
||||
self.mediaManagerDock.isVisible())
|
||||
self.ViewThemeManagerItem = icon_action(mainWindow,
|
||||
u'ViewThemeManagerItem', u':/system/system_thememanager.png',
|
||||
self.themeManagerDock.isVisible())
|
||||
mainWindow.actionList.add_action(self.ViewMediaManagerItem, u'View')
|
||||
self.ViewServiceManagerItem = QtGui.QAction(mainWindow)
|
||||
self.ViewServiceManagerItem.setCheckable(True)
|
||||
self.ViewServiceManagerItem.setChecked(
|
||||
self.ServiceManagerDock.isVisible())
|
||||
self.ViewServiceManagerItem.setIcon(
|
||||
build_icon(u':/system/system_servicemanager.png'))
|
||||
self.ViewServiceManagerItem.setObjectName(u'ViewServiceManagerItem')
|
||||
self.ViewServiceManagerItem = icon_action(mainWindow,
|
||||
u'ViewServiceManagerItem', u':/system/system_servicemanager.png',
|
||||
self.serviceManagerDock.isVisible())
|
||||
mainWindow.actionList.add_action(self.ViewServiceManagerItem, u'View')
|
||||
self.ViewPreviewPanel = QtGui.QAction(mainWindow)
|
||||
self.ViewPreviewPanel.setCheckable(True)
|
||||
self.ViewPreviewPanel.setChecked(previewVisible)
|
||||
self.ViewPreviewPanel.setObjectName(u'ViewPreviewPanel')
|
||||
self.ViewPreviewPanel = checkable_action(mainWindow,
|
||||
u'ViewPreviewPanel', previewVisible)
|
||||
mainWindow.actionList.add_action(self.ViewPreviewPanel, u'View')
|
||||
self.ViewLivePanel = QtGui.QAction(mainWindow)
|
||||
self.ViewLivePanel.setCheckable(True)
|
||||
self.ViewLivePanel.setChecked(liveVisible)
|
||||
self.ViewLivePanel.setObjectName(u'ViewLivePanel')
|
||||
self.ViewLivePanel = checkable_action(mainWindow, u'ViewLivePanel',
|
||||
liveVisible)
|
||||
mainWindow.actionList.add_action(self.ViewLivePanel, u'View')
|
||||
self.ModeDefaultItem = QtGui.QAction(mainWindow)
|
||||
self.ModeDefaultItem.setCheckable(True)
|
||||
self.ModeDefaultItem.setObjectName(u'ModeDefaultItem')
|
||||
self.ModeDefaultItem = checkable_action(mainWindow, u'ModeDefaultItem')
|
||||
mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode')
|
||||
self.ModeSetupItem = QtGui.QAction(mainWindow)
|
||||
self.ModeSetupItem.setCheckable(True)
|
||||
self.ModeSetupItem.setObjectName(u'ModeLiveItem')
|
||||
self.ModeSetupItem = checkable_action(mainWindow, u'ModeLiveItem')
|
||||
mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode')
|
||||
self.ModeLiveItem = QtGui.QAction(mainWindow)
|
||||
self.ModeLiveItem.setCheckable(True)
|
||||
self.ModeLiveItem.setObjectName(u'ModeLiveItem')
|
||||
self.ModeLiveItem = checkable_action(mainWindow, u'ModeLiveItem')
|
||||
mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode')
|
||||
self.ModeGroup = QtGui.QActionGroup(mainWindow)
|
||||
self.ModeGroup.addAction(self.ModeDefaultItem)
|
||||
self.ModeGroup.addAction(self.ModeSetupItem)
|
||||
self.ModeGroup.addAction(self.ModeLiveItem)
|
||||
self.ModeDefaultItem.setChecked(True)
|
||||
self.ToolsAddToolItem = QtGui.QAction(mainWindow)
|
||||
self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png'))
|
||||
self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem')
|
||||
self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
|
||||
u':/tools/tools_add.png')
|
||||
mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools')
|
||||
self.SettingsPluginListItem = QtGui.QAction(mainWindow)
|
||||
self.SettingsPluginListItem.setIcon(
|
||||
build_icon(u':/system/settings_plugin_list.png'))
|
||||
self.SettingsPluginListItem.setObjectName(u'SettingsPluginListItem')
|
||||
mainWindow.actionList.add_action(self.SettingsPluginListItem,
|
||||
self.ToolsOpenDataFolder = icon_action(mainWindow,
|
||||
u'ToolsOpenDataFolder', u':/general/general_open.png')
|
||||
mainWindow.actionList.add_action(self.ToolsOpenDataFolder, u'Tools')
|
||||
self.settingsPluginListItem = icon_action(mainWindow,
|
||||
u'settingsPluginListItem', u':/system/settings_plugin_list.png')
|
||||
mainWindow.actionList.add_action(self.settingsPluginListItem,
|
||||
u'Settings')
|
||||
# i18n Language Items
|
||||
self.AutoLanguageItem = QtGui.QAction(mainWindow)
|
||||
self.AutoLanguageItem.setObjectName(u'AutoLanguageItem')
|
||||
self.AutoLanguageItem.setCheckable(True)
|
||||
self.AutoLanguageItem = checkable_action(mainWindow,
|
||||
u'AutoLanguageItem')
|
||||
mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings')
|
||||
self.LanguageGroup = QtGui.QActionGroup(mainWindow)
|
||||
self.LanguageGroup.setExclusive(True)
|
||||
@ -262,39 +235,28 @@ class Ui_MainWindow(object):
|
||||
qmList = LanguageManager.get_qm_list()
|
||||
savedLanguage = LanguageManager.get_language()
|
||||
for key in sorted(qmList.keys()):
|
||||
languageItem = QtGui.QAction(mainWindow)
|
||||
languageItem.setObjectName(key)
|
||||
languageItem.setCheckable(True)
|
||||
languageItem = checkable_action(mainWindow, key)
|
||||
if qmList[key] == savedLanguage:
|
||||
languageItem.setChecked(True)
|
||||
add_actions(self.LanguageGroup, [languageItem])
|
||||
self.SettingsShortcutsItem = QtGui.QAction(mainWindow)
|
||||
self.SettingsShortcutsItem.setIcon(
|
||||
build_icon(u':/system/system_configure_shortcuts.png'))
|
||||
self.SettingsShortcutsItem.setObjectName(u'SettingsShortcutsItem')
|
||||
self.SettingsConfigureItem = QtGui.QAction(mainWindow)
|
||||
self.SettingsConfigureItem.setIcon(
|
||||
build_icon(u':/system/system_settings.png'))
|
||||
self.SettingsConfigureItem.setObjectName(u'SettingsConfigureItem')
|
||||
self.SettingsShortcutsItem = icon_action(mainWindow,
|
||||
u'SettingsShortcutsItem',
|
||||
u':/system/system_configure_shortcuts.png')
|
||||
self.SettingsConfigureItem = icon_action(mainWindow,
|
||||
u'SettingsConfigureItem', u':/system/system_settings.png')
|
||||
mainWindow.actionList.add_action(self.SettingsShortcutsItem,
|
||||
u'Settings')
|
||||
self.HelpDocumentationItem = QtGui.QAction(mainWindow)
|
||||
self.HelpDocumentationItem.setIcon(
|
||||
build_icon(u':/system/system_help_contents.png'))
|
||||
self.HelpDocumentationItem.setObjectName(u'HelpDocumentationItem')
|
||||
self.HelpDocumentationItem = icon_action(mainWindow,
|
||||
u'HelpDocumentationItem', u':/system/system_help_contents.png')
|
||||
self.HelpDocumentationItem.setEnabled(False)
|
||||
mainWindow.actionList.add_action(self.HelpDocumentationItem, u'Help')
|
||||
self.HelpAboutItem = QtGui.QAction(mainWindow)
|
||||
self.HelpAboutItem.setIcon(
|
||||
build_icon(u':/system/system_about.png'))
|
||||
self.HelpAboutItem.setObjectName(u'HelpAboutItem')
|
||||
self.HelpAboutItem = icon_action(mainWindow, u'HelpAboutItem',
|
||||
u':/system/system_about.png')
|
||||
mainWindow.actionList.add_action(self.HelpAboutItem, u'Help')
|
||||
self.HelpOnlineHelpItem = QtGui.QAction(mainWindow)
|
||||
self.HelpOnlineHelpItem.setObjectName(u'HelpOnlineHelpItem')
|
||||
self.HelpOnlineHelpItem = base_action(mainWindow, u'HelpOnlineHelpItem')
|
||||
self.HelpOnlineHelpItem.setEnabled(False)
|
||||
mainWindow.actionList.add_action(self.HelpOnlineHelpItem, u'Help')
|
||||
self.HelpWebSiteItem = QtGui.QAction(mainWindow)
|
||||
self.HelpWebSiteItem.setObjectName(u'HelpWebSiteItem')
|
||||
self.HelpWebSiteItem = base_action(mainWindow, u'HelpWebSiteItem')
|
||||
mainWindow.actionList.add_action(self.HelpWebSiteItem, u'Help')
|
||||
add_actions(self.FileImportMenu,
|
||||
(self.ImportThemeItem, self.ImportLanguageItem))
|
||||
@ -302,26 +264,27 @@ class Ui_MainWindow(object):
|
||||
(self.ExportThemeItem, self.ExportLanguageItem))
|
||||
self.FileMenuActions = (self.FileNewItem, self.FileOpenItem,
|
||||
self.FileSaveItem, self.FileSaveAsItem, None,
|
||||
self.FileImportMenu.menuAction(), self.FileExportMenu.menuAction(),
|
||||
self.FileExitItem)
|
||||
self.printServiceOrderItem, None, self.FileImportMenu.menuAction(),
|
||||
self.FileExportMenu.menuAction(), self.FileExitItem)
|
||||
add_actions(self.ViewModeMenu, (self.ModeDefaultItem,
|
||||
self.ModeSetupItem, self.ModeLiveItem))
|
||||
add_actions(self.ViewMenu, (self.ViewModeMenu.menuAction(),
|
||||
add_actions(self.viewMenu, (self.ViewModeMenu.menuAction(),
|
||||
None, self.ViewMediaManagerItem, self.ViewServiceManagerItem,
|
||||
self.ViewThemeManagerItem, None, self.ViewPreviewPanel,
|
||||
self.ViewLivePanel))
|
||||
# i18n add Language Actions
|
||||
add_actions(self.SettingsLanguageMenu, (self.AutoLanguageItem, None))
|
||||
add_actions(self.SettingsLanguageMenu, self.LanguageGroup.actions())
|
||||
add_actions(self.SettingsMenu, (self.SettingsPluginListItem,
|
||||
add_actions(self.SettingsMenu, (self.settingsPluginListItem,
|
||||
self.SettingsLanguageMenu.menuAction(), None,
|
||||
self.SettingsShortcutsItem, self.SettingsConfigureItem))
|
||||
add_actions(self.ToolsMenu, (self.ToolsAddToolItem, None))
|
||||
add_actions(self.ToolsMenu, (self.ToolsOpenDataFolder, None))
|
||||
add_actions(self.HelpMenu, (self.HelpDocumentationItem,
|
||||
self.HelpOnlineHelpItem, None, self.HelpWebSiteItem,
|
||||
self.HelpAboutItem))
|
||||
add_actions(self.MenuBar, (self.FileMenu.menuAction(),
|
||||
self.ViewMenu.menuAction(), self.ToolsMenu.menuAction(),
|
||||
self.viewMenu.menuAction(), self.ToolsMenu.menuAction(),
|
||||
self.SettingsMenu.menuAction(), self.HelpMenu.menuAction()))
|
||||
# Initialise the translation
|
||||
self.retranslateUi(mainWindow)
|
||||
@ -337,39 +300,35 @@ class Ui_MainWindow(object):
|
||||
"""
|
||||
Set up the translation system
|
||||
"""
|
||||
mainWindow.mainTitle = translate('OpenLP.MainWindow', 'OpenLP 2.0')
|
||||
mainWindow.mainTitle = UiStrings.OLPV2
|
||||
mainWindow.setWindowTitle(mainWindow.mainTitle)
|
||||
self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
|
||||
self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
|
||||
self.FileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export'))
|
||||
self.ViewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
|
||||
self.viewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
|
||||
self.ViewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
|
||||
self.ToolsMenu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
|
||||
self.SettingsMenu.setTitle(translate('OpenLP.MainWindow', '&Settings'))
|
||||
self.SettingsLanguageMenu.setTitle(translate('OpenLP.MainWindow',
|
||||
'&Language'))
|
||||
self.HelpMenu.setTitle(translate('OpenLP.MainWindow', '&Help'))
|
||||
self.MediaManagerDock.setWindowTitle(
|
||||
self.mediaManagerDock.setWindowTitle(
|
||||
translate('OpenLP.MainWindow', 'Media Manager'))
|
||||
self.ServiceManagerDock.setWindowTitle(
|
||||
self.serviceManagerDock.setWindowTitle(
|
||||
translate('OpenLP.MainWindow', 'Service Manager'))
|
||||
self.ThemeManagerDock.setWindowTitle(
|
||||
self.themeManagerDock.setWindowTitle(
|
||||
translate('OpenLP.MainWindow', 'Theme Manager'))
|
||||
self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New'))
|
||||
self.FileNewItem.setToolTip(
|
||||
translate('OpenLP.MainWindow', 'New Service'))
|
||||
self.FileNewItem.setStatusTip(
|
||||
translate('OpenLP.MainWindow', 'Create a new service.'))
|
||||
self.FileNewItem.setToolTip(UiStrings.NewService)
|
||||
self.FileNewItem.setStatusTip(UiStrings.CreateService)
|
||||
self.FileNewItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+N'))
|
||||
self.FileOpenItem.setText(translate('OpenLP.MainWindow', '&Open'))
|
||||
self.FileOpenItem.setToolTip(
|
||||
translate('OpenLP.MainWindow', 'Open Service'))
|
||||
self.FileOpenItem.setToolTip(UiStrings.OpenService)
|
||||
self.FileOpenItem.setStatusTip(
|
||||
translate('OpenLP.MainWindow', 'Open an existing service.'))
|
||||
self.FileOpenItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+O'))
|
||||
self.FileSaveItem.setText(translate('OpenLP.MainWindow', '&Save'))
|
||||
self.FileSaveItem.setToolTip(
|
||||
translate('OpenLP.MainWindow', 'Save Service'))
|
||||
self.FileSaveItem.setToolTip(UiStrings.SaveService)
|
||||
self.FileSaveItem.setStatusTip(
|
||||
translate('OpenLP.MainWindow', 'Save the current service to disk.'))
|
||||
self.FileSaveItem.setShortcut(translate('OpenLP.MainWindow', 'Ctrl+S'))
|
||||
@ -381,6 +340,12 @@ class Ui_MainWindow(object):
|
||||
'Save the current service under a new name.'))
|
||||
self.FileSaveAsItem.setShortcut(
|
||||
translate('OpenLP.MainWindow', 'Ctrl+Shift+S'))
|
||||
self.printServiceOrderItem.setText(
|
||||
translate('OpenLP.MainWindow', 'Print Service Order'))
|
||||
self.printServiceOrderItem.setStatusTip(translate('OpenLP.MainWindow',
|
||||
'Print the current Service Order.'))
|
||||
self.printServiceOrderItem.setShortcut(
|
||||
translate('OpenLP.MainWindow', 'Ctrl+P'))
|
||||
self.FileExitItem.setText(
|
||||
translate('OpenLP.MainWindow', 'E&xit'))
|
||||
self.FileExitItem.setStatusTip(
|
||||
@ -439,11 +404,11 @@ class Ui_MainWindow(object):
|
||||
'Toggle the visibility of the live panel.'))
|
||||
self.ViewLivePanel.setShortcut(
|
||||
translate('OpenLP.MainWindow', 'F12'))
|
||||
self.SettingsPluginListItem.setText(translate('OpenLP.MainWindow',
|
||||
self.settingsPluginListItem.setText(translate('OpenLP.MainWindow',
|
||||
'&Plugin List'))
|
||||
self.SettingsPluginListItem.setStatusTip(
|
||||
self.settingsPluginListItem.setStatusTip(
|
||||
translate('OpenLP.MainWindow', 'List the Plugins'))
|
||||
self.SettingsPluginListItem.setShortcut(
|
||||
self.settingsPluginListItem.setShortcut(
|
||||
translate('OpenLP.MainWindow', 'Alt+F7'))
|
||||
self.HelpDocumentationItem.setText(
|
||||
translate('OpenLP.MainWindow', '&User Guide'))
|
||||
@ -468,6 +433,10 @@ class Ui_MainWindow(object):
|
||||
translate('OpenLP.MainWindow', 'Add &Tool...'))
|
||||
self.ToolsAddToolItem.setStatusTip(translate('OpenLP.MainWindow',
|
||||
'Add an application to the list of tools.'))
|
||||
self.ToolsOpenDataFolder.setText(
|
||||
translate('OpenLP.MainWindow', 'Open &Data Folder...'))
|
||||
self.ToolsOpenDataFolder.setStatusTip(translate('OpenLP.MainWindow',
|
||||
'Open the folder where songs, bibles and other data resides.'))
|
||||
self.ModeDefaultItem.setText(
|
||||
translate('OpenLP.MainWindow', '&Default'))
|
||||
self.ModeDefaultItem.setStatusTip(translate('OpenLP.MainWindow',
|
||||
@ -537,20 +506,22 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
QtCore.SIGNAL(u'toggled(bool)'), self.setPreviewPanelVisibility)
|
||||
QtCore.QObject.connect(self.ViewLivePanel,
|
||||
QtCore.SIGNAL(u'toggled(bool)'), self.setLivePanelVisibility)
|
||||
QtCore.QObject.connect(self.MediaManagerDock,
|
||||
QtCore.QObject.connect(self.mediaManagerDock,
|
||||
QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
||||
self.ViewMediaManagerItem.setChecked)
|
||||
QtCore.QObject.connect(self.ServiceManagerDock,
|
||||
QtCore.QObject.connect(self.serviceManagerDock,
|
||||
QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
||||
self.ViewServiceManagerItem.setChecked)
|
||||
QtCore.QObject.connect(self.ThemeManagerDock,
|
||||
QtCore.QObject.connect(self.themeManagerDock,
|
||||
QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
||||
self.ViewThemeManagerItem.setChecked)
|
||||
QtCore.QObject.connect(self.HelpWebSiteItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
|
||||
QtCore.QObject.connect(self.HelpAboutItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onHelpAboutItemClicked)
|
||||
QtCore.QObject.connect(self.SettingsPluginListItem,
|
||||
QtCore.QObject.connect(self.ToolsOpenDataFolder,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked)
|
||||
QtCore.QObject.connect(self.settingsPluginListItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onPluginItemClicked)
|
||||
QtCore.QObject.connect(self.SettingsConfigureItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
|
||||
@ -563,10 +534,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.ServiceManagerContents.onLoadServiceClicked)
|
||||
QtCore.QObject.connect(self.FileSaveItem,
|
||||
QtCore.SIGNAL(u'triggered()'),
|
||||
self.ServiceManagerContents.onSaveServiceClicked)
|
||||
self.ServiceManagerContents.saveFile)
|
||||
QtCore.QObject.connect(self.FileSaveAsItem,
|
||||
QtCore.SIGNAL(u'triggered()'),
|
||||
self.ServiceManagerContents.onSaveServiceAsClicked)
|
||||
self.ServiceManagerContents.saveFileAs)
|
||||
QtCore.QObject.connect(self.printServiceOrderItem,
|
||||
QtCore.SIGNAL(u'triggered()'),
|
||||
self.ServiceManagerContents.printServiceOrder)
|
||||
# i18n set signals for languages
|
||||
QtCore.QObject.connect(self.AutoLanguageItem,
|
||||
QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage)
|
||||
@ -735,6 +709,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.pluginForm.load()
|
||||
self.pluginForm.exec_()
|
||||
|
||||
def onToolsOpenDataFolderClicked(self):
|
||||
"""
|
||||
Open data folder
|
||||
"""
|
||||
path = AppLocation.get_data_path()
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + path))
|
||||
|
||||
def onSettingsConfigureItemClicked(self):
|
||||
"""
|
||||
Show the Settings dialog
|
||||
@ -758,37 +739,32 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
"""
|
||||
Put OpenLP into "Default" view mode.
|
||||
"""
|
||||
settings = QtCore.QSettings()
|
||||
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
|
||||
u'default')
|
||||
self.setViewMode(True, True, True, True, True)
|
||||
self.setViewMode(True, True, True, True, True, u'default')
|
||||
|
||||
def onModeSetupItemClicked(self):
|
||||
"""
|
||||
Put OpenLP into "Setup" view mode.
|
||||
"""
|
||||
settings = QtCore.QSettings()
|
||||
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
|
||||
u'setup')
|
||||
self.setViewMode(True, True, False, True, False)
|
||||
self.setViewMode(True, True, False, True, False, u'setup')
|
||||
|
||||
def onModeLiveItemClicked(self):
|
||||
"""
|
||||
Put OpenLP into "Live" view mode.
|
||||
"""
|
||||
settings = QtCore.QSettings()
|
||||
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
|
||||
u'live')
|
||||
self.setViewMode(False, True, False, False, True)
|
||||
self.setViewMode(False, True, False, False, True, u'live')
|
||||
|
||||
def setViewMode(self, media=True, service=True, theme=True, preview=True,
|
||||
live=True):
|
||||
live=True, mode=u''):
|
||||
"""
|
||||
Set OpenLP to a different view mode.
|
||||
"""
|
||||
self.MediaManagerDock.setVisible(media)
|
||||
self.ServiceManagerDock.setVisible(service)
|
||||
self.ThemeManagerDock.setVisible(theme)
|
||||
if mode:
|
||||
settings = QtCore.QSettings()
|
||||
settings.setValue(u'%s/view mode' % self.generalSettingsSection,
|
||||
mode)
|
||||
self.mediaManagerDock.setVisible(media)
|
||||
self.serviceManagerDock.setVisible(service)
|
||||
self.themeManagerDock.setVisible(theme)
|
||||
self.setPreviewPanelVisibility(preview)
|
||||
self.setLivePanelVisibility(live)
|
||||
|
||||
@ -807,15 +783,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
Hook to close the main window and display windows on exit
|
||||
"""
|
||||
if self.ServiceManagerContents.isModified():
|
||||
ret = QtGui.QMessageBox.question(self,
|
||||
translate('OpenLP.MainWindow', 'Save Changes to Service?'),
|
||||
translate('OpenLP.MainWindow', 'Your service has changed. '
|
||||
'Do you want to save those changes?'),
|
||||
QtGui.QMessageBox.StandardButtons(
|
||||
QtGui.QMessageBox.Cancel |
|
||||
QtGui.QMessageBox.Discard |
|
||||
QtGui.QMessageBox.Save),
|
||||
QtGui.QMessageBox.Save)
|
||||
ret = self.ServiceManagerContents.saveModifiedService()
|
||||
if ret == QtGui.QMessageBox.Save:
|
||||
if self.ServiceManagerContents.saveFile():
|
||||
self.cleanUp()
|
||||
@ -847,7 +815,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.cleanUp()
|
||||
event.accept()
|
||||
|
||||
|
||||
def cleanUp(self):
|
||||
"""
|
||||
Runs all the cleanup code before OpenLP shuts down
|
||||
@ -914,16 +881,16 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
theme)
|
||||
|
||||
def toggleMediaManager(self, visible):
|
||||
if self.MediaManagerDock.isVisible() != visible:
|
||||
self.MediaManagerDock.setVisible(visible)
|
||||
if self.mediaManagerDock.isVisible() != visible:
|
||||
self.mediaManagerDock.setVisible(visible)
|
||||
|
||||
def toggleServiceManager(self, visible):
|
||||
if self.ServiceManagerDock.isVisible() != visible:
|
||||
self.ServiceManagerDock.setVisible(visible)
|
||||
if self.serviceManagerDock.isVisible() != visible:
|
||||
self.serviceManagerDock.setVisible(visible)
|
||||
|
||||
def toggleThemeManager(self, visible):
|
||||
if self.ThemeManagerDock.isVisible() != visible:
|
||||
self.ThemeManagerDock.setVisible(visible)
|
||||
if self.themeManagerDock.isVisible() != visible:
|
||||
self.themeManagerDock.setVisible(visible)
|
||||
|
||||
def setPreviewPanelVisibility(self, visible):
|
||||
"""
|
||||
@ -935,7 +902,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
True - Visible
|
||||
False - Hidden
|
||||
"""
|
||||
self.previewController.Panel.setVisible(visible)
|
||||
self.previewController.panel.setVisible(visible)
|
||||
QtCore.QSettings().setValue(u'user interface/preview panel',
|
||||
QtCore.QVariant(visible))
|
||||
self.ViewPreviewPanel.setChecked(visible)
|
||||
@ -950,7 +917,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
True - Visible
|
||||
False - Hidden
|
||||
"""
|
||||
self.liveController.Panel.setVisible(visible)
|
||||
self.liveController.panel.setVisible(visible)
|
||||
QtCore.QSettings().setValue(u'user interface/live panel',
|
||||
QtCore.QVariant(visible))
|
||||
self.ViewLivePanel.setChecked(visible)
|
||||
@ -1000,8 +967,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
|
||||
self.FileMenu.clear()
|
||||
add_actions(self.FileMenu, self.FileMenuActions[:-1])
|
||||
existingRecentFiles = [file for file in self.recentFiles
|
||||
if QtCore.QFile.exists(file)]
|
||||
existingRecentFiles = [recentFile for recentFile in self.recentFiles
|
||||
if QtCore.QFile.exists(recentFile)]
|
||||
recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
|
||||
if recentFilesToDisplay:
|
||||
self.FileMenu.addSeparator()
|
||||
|
@ -28,13 +28,15 @@ import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import PluginStatus, StringContent, translate
|
||||
from openlp.core.lib import PluginStatus, Receiver, StringContent, translate
|
||||
from plugindialog import Ui_PluginViewDialog
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
|
||||
"""
|
||||
The plugin form provides user control over the plugins OpenLP uses.
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.parent = parent
|
||||
@ -129,7 +131,9 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
|
||||
if self.programaticChange:
|
||||
return
|
||||
if status == 0:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self.activePlugin.toggleStatus(PluginStatus.Active)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
else:
|
||||
self.activePlugin.toggleStatus(PluginStatus.Inactive)
|
||||
status_text = unicode(
|
||||
|
137
openlp/core/ui/printserviceorderdialog.py
Normal file
137
openlp/core/ui/printserviceorderdialog.py
Normal file
@ -0,0 +1,137 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||
# Carsten Tinggaard, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, translate, SpellTextEdit
|
||||
|
||||
class Ui_PrintServiceOrderDialog(object):
|
||||
def setupUi(self, printServiceOrderDialog):
|
||||
printServiceOrderDialog.setObjectName(u'printServiceOrderDialog')
|
||||
self.dialogLayout = QtGui.QGridLayout(printServiceOrderDialog)
|
||||
self.dialogLayout.setObjectName(u'dialogLayout')
|
||||
self.perviewLayout = QtGui.QVBoxLayout()
|
||||
self.perviewLayout.setObjectName(u'perviewLayout')
|
||||
self.previewLabel = QtGui.QLabel(printServiceOrderDialog)
|
||||
self.previewLabel.setSizePolicy(
|
||||
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
|
||||
self.previewLabel.setObjectName(u'previewLabel')
|
||||
self.perviewLayout.addWidget(self.previewLabel)
|
||||
self.previewWidget = QtGui.QPrintPreviewWidget(
|
||||
self.printer, self, QtCore.Qt.Widget)
|
||||
self.previewWidget.setEnabled(True)
|
||||
self.previewWidget.setSizePolicy(
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding)
|
||||
self.previewWidget.setObjectName(u'previewWidget')
|
||||
# Give the previewWidget a fixed size, to prevent resizing when clicking
|
||||
# the zoom buttons.
|
||||
self.previewWidget.setFixedWidth(350)
|
||||
self.perviewLayout.addWidget(self.previewWidget)
|
||||
self.dialogLayout.addLayout(self.perviewLayout, 0, 0, 1, 1)
|
||||
self.settingsLayout = QtGui.QVBoxLayout()
|
||||
self.settingsLayout.setObjectName(u'settingsLayout')
|
||||
self.serviceTitleLayout = QtGui.QGridLayout()
|
||||
self.serviceTitleLayout.setObjectName(u'serviceTitleLayout')
|
||||
self.serviceTitleLineEdit = QtGui.QLineEdit(printServiceOrderDialog)
|
||||
self.serviceTitleLineEdit.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
|
||||
self.serviceTitleLineEdit.setObjectName(u'serviceTitleLineEdit')
|
||||
self.serviceTitleLayout.addWidget(self.serviceTitleLineEdit, 1, 1, 1, 1)
|
||||
self.serviceTitleLabel = QtGui.QLabel(printServiceOrderDialog)
|
||||
self.serviceTitleLabel.setSizePolicy(
|
||||
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
|
||||
self.serviceTitleLabel.setObjectName(u'serviceTitleLabel')
|
||||
self.serviceTitleLayout.addWidget(self.serviceTitleLabel, 1, 0, 1, 1)
|
||||
self.settingsLayout.addLayout(self.serviceTitleLayout)
|
||||
self.printSlideTextCheckBox = QtGui.QCheckBox(printServiceOrderDialog)
|
||||
self.printSlideTextCheckBox.setObjectName(u'printSlideTextCheckBox')
|
||||
self.settingsLayout.addWidget(self.printSlideTextCheckBox)
|
||||
self.printNotesCheckBox = QtGui.QCheckBox(printServiceOrderDialog)
|
||||
self.printNotesCheckBox.setObjectName(u'printNotesCheckBox')
|
||||
self.settingsLayout.addWidget(self.printNotesCheckBox)
|
||||
self.printMetaDataCheckBox = QtGui.QCheckBox(printServiceOrderDialog)
|
||||
self.printMetaDataCheckBox.setObjectName(u'printMetaDataCheckBox')
|
||||
self.settingsLayout.addWidget(self.printMetaDataCheckBox)
|
||||
spacerItem = QtGui.QSpacerItem(20, 40,
|
||||
QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
|
||||
self.settingsLayout.addItem(spacerItem)
|
||||
self.customNotesLabel = QtGui.QLabel(self)
|
||||
self.customNotesLabel.setObjectName(u'customNotesLabel')
|
||||
self.settingsLayout.addWidget(self.customNotesLabel)
|
||||
self.customNoteEdit = SpellTextEdit(self)
|
||||
self.customNoteEdit.setObjectName(u'customNoteEdit')
|
||||
self.settingsLayout.addWidget(self.customNoteEdit)
|
||||
self.dialogLayout.addLayout(self.settingsLayout, 0, 3, 1, 1)
|
||||
self.buttonLayout = QtGui.QHBoxLayout()
|
||||
self.buttonLayout.setObjectName(u'buttonLayout')
|
||||
spacerItem = QtGui.QSpacerItem(40, 20,
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.buttonLayout.addItem(spacerItem)
|
||||
self.cancelButton = QtGui.QPushButton(printServiceOrderDialog)
|
||||
self.cancelButton.setObjectName(u'cancelButton')
|
||||
self.buttonLayout.addWidget(self.cancelButton)
|
||||
self.printButton = QtGui.QPushButton(printServiceOrderDialog)
|
||||
self.printButton.setObjectName(u'printButton')
|
||||
self.buttonLayout.addWidget(self.printButton)
|
||||
self.dialogLayout.addLayout(self.buttonLayout, 1, 3, 1, 1)
|
||||
self.zoomButtonLayout = QtGui.QHBoxLayout()
|
||||
self.zoomButtonLayout.setObjectName(u'zoomButtonLayout')
|
||||
spacerItem = QtGui.QSpacerItem(40, 20,
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.zoomButtonLayout.addItem(spacerItem)
|
||||
self.zoomOutButton = QtGui.QToolButton(printServiceOrderDialog)
|
||||
self.zoomOutButton.setIcon(
|
||||
build_icon(u':/general/general_zoom_out.png'))
|
||||
self.zoomOutButton.setObjectName(u'zoomOutButton')
|
||||
self.zoomButtonLayout.addWidget(self.zoomOutButton)
|
||||
self.zoomInButton = QtGui.QToolButton(printServiceOrderDialog)
|
||||
self.zoomInButton.setIcon(build_icon(u':/general/general_zoom_in.png'))
|
||||
self.zoomInButton.setObjectName(u'zoomInButton')
|
||||
self.zoomButtonLayout.addWidget(self.zoomInButton)
|
||||
self.dialogLayout.addLayout(self.zoomButtonLayout, 1, 0, 1, 1)
|
||||
self.retranslateUi(printServiceOrderDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(printServiceOrderDialog)
|
||||
|
||||
def retranslateUi(self, printServiceOrderDialog):
|
||||
printServiceOrderDialog.setWindowTitle(
|
||||
translate('OpenLP.PrintServiceOrderForm', 'Print Service Order'))
|
||||
self.previewLabel.setText(
|
||||
translate('OpenLP.ServiceManager', '<b>Preview:</b>'))
|
||||
self.printSlideTextCheckBox.setText(translate(
|
||||
'OpenLP.PrintServiceOrderForm', 'Include slide text if available'))
|
||||
self.printNotesCheckBox.setText(translate(
|
||||
'OpenLP.PrintServiceOrderForm', 'Include service item notes'))
|
||||
self.printMetaDataCheckBox.setText(
|
||||
translate('OpenLP.PrintServiceOrderForm',
|
||||
'Include play length of media items'))
|
||||
self.serviceTitleLabel.setText(translate(
|
||||
'OpenLP.PrintServiceOrderForm', 'Title:'))
|
||||
self.serviceTitleLineEdit.setText(translate('OpenLP.ServiceManager',
|
||||
'Service Order Sheet'))
|
||||
self.printButton.setText(translate('OpenLP.ServiceManager', 'Print'))
|
||||
self.cancelButton.setText(translate('OpenLP.ServiceManager', 'Cancel'))
|
||||
self.customNotesLabel.setText(
|
||||
translate('OpenLP.ServiceManager', '<b>Custom Service Notes:</b>'))
|
175
openlp/core/ui/printserviceorderform.py
Normal file
175
openlp/core/ui/printserviceorderform.py
Normal file
@ -0,0 +1,175 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||
# Carsten Tinggaard, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
import datetime
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.ui.printserviceorderdialog import Ui_PrintServiceOrderDialog
|
||||
|
||||
class PrintServiceOrderForm(QtGui.QDialog, Ui_PrintServiceOrderDialog):
|
||||
def __init__(self, parent, serviceManager):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.serviceManager = serviceManager
|
||||
self.printer = QtGui.QPrinter()
|
||||
self.printDialog = QtGui.QPrintDialog(self.printer, self)
|
||||
self.document = QtGui.QTextDocument()
|
||||
self.setupUi(self)
|
||||
# Load the settings for the dialog.
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(u'advanced')
|
||||
self.printSlideTextCheckBox.setChecked(settings.value(
|
||||
u'print slide text', QtCore.QVariant(False)).toBool())
|
||||
self.printMetaDataCheckBox.setChecked(settings.value(
|
||||
u'print file meta data', QtCore.QVariant(False)).toBool())
|
||||
self.printNotesCheckBox.setChecked(settings.value(
|
||||
u'print notes', QtCore.QVariant(False)).toBool())
|
||||
settings.endGroup()
|
||||
# Signals
|
||||
QtCore.QObject.connect(self.printButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.printServiceOrder)
|
||||
QtCore.QObject.connect(self.zoomOutButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.zoomOut)
|
||||
QtCore.QObject.connect(self.zoomInButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.zoomIn)
|
||||
QtCore.QObject.connect(self.previewWidget,
|
||||
QtCore.SIGNAL(u'paintRequested(QPrinter *)'), self.paintRequested)
|
||||
QtCore.QObject.connect(self.serviceTitleLineEdit,
|
||||
QtCore.SIGNAL(u'textChanged(const QString)'),
|
||||
self.updatePreviewText)
|
||||
QtCore.QObject.connect(self.printSlideTextCheckBox,
|
||||
QtCore.SIGNAL(u'stateChanged(int)'), self.updatePreviewText)
|
||||
QtCore.QObject.connect(self.printNotesCheckBox,
|
||||
QtCore.SIGNAL(u'stateChanged(int)'), self.updatePreviewText)
|
||||
QtCore.QObject.connect(self.printMetaDataCheckBox,
|
||||
QtCore.SIGNAL(u'stateChanged(int)'), self.updatePreviewText)
|
||||
QtCore.QObject.connect(self.customNoteEdit,
|
||||
QtCore.SIGNAL(u'textChanged()'), self.updatePreviewText)
|
||||
QtCore.QObject.connect(self.cancelButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.reject)
|
||||
self.updatePreviewText()
|
||||
|
||||
def updatePreviewText(self):
|
||||
"""
|
||||
Creates the html text and updates the html of *self.document*.
|
||||
"""
|
||||
text = u''
|
||||
if self.serviceTitleLineEdit.text():
|
||||
text += u'<h2>%s</h2>' % unicode(self.serviceTitleLineEdit.text())
|
||||
for item in self.serviceManager.serviceItems:
|
||||
item = item[u'service_item']
|
||||
# Add the title of the service item.
|
||||
text += u'<h4><img src="%s" /> %s</h4>' % (item.icon,
|
||||
item.get_display_title())
|
||||
# Add slide text of the service item.
|
||||
if self.printSlideTextCheckBox.isChecked():
|
||||
if item.is_text():
|
||||
# Add the text of the service item.
|
||||
for slide in item.get_frames():
|
||||
text += u'<p>' + slide[u'text'] + u'</p>'
|
||||
elif item.is_image():
|
||||
# Add the image names of the service item.
|
||||
text += u'<ol>'
|
||||
for slide in range(len(item.get_frames())):
|
||||
text += u'<li><p>%s</p></li>' % \
|
||||
item.get_frame_title(slide)
|
||||
text += u'</ol>'
|
||||
if item.foot_text:
|
||||
# add footer
|
||||
text += u'<p>%s</p>' % item.foot_text
|
||||
# Add service items' notes.
|
||||
if self.printNotesCheckBox.isChecked():
|
||||
if item.notes:
|
||||
text += u'<p><b>%s</b></p>%s' % (translate(
|
||||
'OpenLP.ServiceManager', 'Notes:'),
|
||||
item.notes.replace(u'\n', u'<br />'))
|
||||
# Add play length of media files.
|
||||
if item.is_media() and self.printMetaDataCheckBox.isChecked():
|
||||
text += u'<p><b>%s</b> %s</p>' % (translate(
|
||||
'OpenLP.ServiceManager', u'Playing time:'),
|
||||
unicode(datetime.timedelta(seconds=item.media_length)))
|
||||
if self.customNoteEdit.toPlainText():
|
||||
text += u'<h4>%s</h4>%s' % (translate('OpenLP.ServiceManager',
|
||||
u'Custom Service Notes:'), self.customNoteEdit.toPlainText())
|
||||
self.document.setHtml(text)
|
||||
self.previewWidget.updatePreview()
|
||||
|
||||
def paintRequested(self, printer):
|
||||
"""
|
||||
Paint the preview of the *self.document*.
|
||||
|
||||
``printer``
|
||||
A *QPrinter* object.
|
||||
"""
|
||||
self.document.print_(printer)
|
||||
|
||||
def printServiceOrder(self):
|
||||
"""
|
||||
Called, when the *printButton* is clicked. Opens the *printDialog*.
|
||||
"""
|
||||
if not self.printDialog.exec_():
|
||||
return
|
||||
# Print the document.
|
||||
self.document.print_(self.printer)
|
||||
self.accept()
|
||||
|
||||
def zoomIn(self):
|
||||
"""
|
||||
Called when *zoomInButton* is clicked.
|
||||
"""
|
||||
self.previewWidget.zoomIn()
|
||||
|
||||
def zoomOut(self):
|
||||
"""
|
||||
Called when *zoomOutButton* is clicked.
|
||||
"""
|
||||
self.previewWidget.zoomOut()
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
Save the settings and close the dialog.
|
||||
"""
|
||||
# Save the settings for this dialog.
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(u'advanced')
|
||||
settings.setValue(u'print slide text',
|
||||
QtCore.QVariant(self.printSlideTextCheckBox.isChecked()))
|
||||
settings.setValue(u'print file meta data',
|
||||
QtCore.QVariant(self.printMetaDataCheckBox.isChecked()))
|
||||
settings.setValue(u'print notes',
|
||||
QtCore.QVariant(self.printNotesCheckBox.isChecked()))
|
||||
settings.endGroup()
|
||||
# Close the dialog.
|
||||
return QtGui.QDialog.accept(self)
|
||||
|
||||
def reject(self):
|
||||
"""
|
||||
Close the dialog, do not print the service and do not save the settings.
|
||||
"""
|
||||
return QtGui.QDialog.reject(self)
|
@ -26,7 +26,9 @@
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, build_icon
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import create_accept_reject_button_box, \
|
||||
create_delete_push_button, create_up_down_push_button_set
|
||||
|
||||
class Ui_ServiceItemEditDialog(object):
|
||||
def setupUi(self, serviceItemEditDialog):
|
||||
@ -39,30 +41,19 @@ class Ui_ServiceItemEditDialog(object):
|
||||
self.dialogLayout.addWidget(self.listWidget, 0, 0)
|
||||
self.buttonLayout = QtGui.QVBoxLayout()
|
||||
self.buttonLayout.setObjectName(u'buttonLayout')
|
||||
self.deleteButton = QtGui.QPushButton(serviceItemEditDialog)
|
||||
self.deleteButton.setObjectName(u'deleteButton')
|
||||
self.deleteButton = create_delete_push_button(serviceItemEditDialog)
|
||||
self.buttonLayout.addWidget(self.deleteButton)
|
||||
self.buttonLayout.addStretch()
|
||||
self.upButton = QtGui.QPushButton(serviceItemEditDialog)
|
||||
self.upButton.setIcon(build_icon(u':/services/service_up.png'))
|
||||
self.upButton.setObjectName(u'upButton')
|
||||
self.upButton, self.downButton = create_up_down_push_button_set(
|
||||
serviceItemEditDialog)
|
||||
self.buttonLayout.addWidget(self.upButton)
|
||||
self.downButton = QtGui.QPushButton(serviceItemEditDialog)
|
||||
self.downButton.setIcon(build_icon(u':/services/service_down.png'))
|
||||
self.downButton.setObjectName(u'downButton')
|
||||
self.buttonLayout.addWidget(self.downButton)
|
||||
self.dialogLayout.addLayout(self.buttonLayout, 0, 1)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(serviceItemEditDialog)
|
||||
self.buttonBox.setStandardButtons(
|
||||
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Save)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.dialogLayout.addWidget(self.buttonBox, 1, 0, 1, 2)
|
||||
|
||||
self.dialogLayout.addWidget(
|
||||
create_accept_reject_button_box(serviceItemEditDialog), 1, 0, 1, 2)
|
||||
self.retranslateUi(serviceItemEditDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(serviceItemEditDialog)
|
||||
|
||||
def retranslateUi(self, serviceItemEditDialog):
|
||||
serviceItemEditDialog.setWindowTitle(
|
||||
translate('OpenLP.ServiceItemEditForm', 'Reorder Service Item'))
|
||||
self.deleteButton.setText(translate('OpenLP.ServiceItemEditForm',
|
||||
'Delete'))
|
||||
|
@ -39,17 +39,6 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
self.itemList = []
|
||||
# enable drop
|
||||
QtCore.QObject.connect(self.upButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onItemUp)
|
||||
QtCore.QObject.connect(self.downButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onItemDown)
|
||||
QtCore.QObject.connect(self.deleteButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onItemDelete)
|
||||
QtCore.QObject.connect(self.buttonBox,
|
||||
QtCore.SIGNAL(u'accepted()'), self.accept)
|
||||
QtCore.QObject.connect(self.buttonBox,
|
||||
QtCore.SIGNAL(u'rejected()'), self.reject)
|
||||
QtCore.QObject.connect(self.listWidget,
|
||||
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
|
||||
|
||||
@ -81,7 +70,7 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||
item_name = QtGui.QListWidgetItem(frame[u'title'])
|
||||
self.listWidget.addItem(item_name)
|
||||
|
||||
def onItemDelete(self):
|
||||
def onDeleteButtonClicked(self):
|
||||
"""
|
||||
Delete the current row.
|
||||
"""
|
||||
@ -96,33 +85,37 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||
else:
|
||||
self.listWidget.setCurrentRow(row)
|
||||
|
||||
def onItemUp(self):
|
||||
def onUpButtonClicked(self):
|
||||
"""
|
||||
Move the current row up in the list.
|
||||
"""
|
||||
item = self.listWidget.currentItem()
|
||||
if not item:
|
||||
return
|
||||
row = self.listWidget.row(item)
|
||||
temp = self.itemList[row]
|
||||
self.itemList.remove(self.itemList[row])
|
||||
self.itemList.insert(row - 1, temp)
|
||||
self.loadData()
|
||||
self.listWidget.setCurrentRow(row - 1)
|
||||
self.__moveItem(u'up')
|
||||
|
||||
def onItemDown(self):
|
||||
def onDownButtonClicked(self):
|
||||
"""
|
||||
Move the current row down in the list
|
||||
"""
|
||||
self.__moveItem(u'down')
|
||||
|
||||
def __moveItem(self, direction=u''):
|
||||
"""
|
||||
Move the current item.
|
||||
"""
|
||||
if not direction:
|
||||
return
|
||||
item = self.listWidget.currentItem()
|
||||
if not item:
|
||||
return
|
||||
row = self.listWidget.row(item)
|
||||
temp = self.itemList[row]
|
||||
self.itemList.remove(self.itemList[row])
|
||||
self.itemList.insert(row + 1, temp)
|
||||
if direction == u'up':
|
||||
row -= 1
|
||||
else:
|
||||
row += 1
|
||||
self.itemList.insert(row, temp)
|
||||
self.loadData()
|
||||
self.listWidget.setCurrentRow(row + 1)
|
||||
self.listWidget.setCurrentRow(row)
|
||||
|
||||
def onCurrentRowChanged(self, row):
|
||||
"""
|
||||
|
@ -23,10 +23,9 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
import os
|
||||
import logging
|
||||
import cPickle
|
||||
import logging
|
||||
import os
|
||||
import zipfile
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -36,8 +35,9 @@ from PyQt4 import QtCore, QtGui
|
||||
from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \
|
||||
Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \
|
||||
ThemeLevel
|
||||
from openlp.core.ui import criticalErrorMessageBox, ServiceNoteForm, \
|
||||
ServiceItemEditForm
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
|
||||
from openlp.core.ui.printserviceorderform import PrintServiceOrderForm
|
||||
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
||||
split_filename
|
||||
|
||||
@ -67,8 +67,8 @@ class ServiceManagerList(QtGui.QTreeWidget):
|
||||
|
||||
class ServiceManager(QtGui.QWidget):
|
||||
"""
|
||||
Manages the services. This involves taking text strings from plugins and
|
||||
adding them to the service. This service can then be zipped up with all
|
||||
Manages the services. This involves taking text strings from plugins and
|
||||
adding them to the service. This service can then be zipped up with all
|
||||
the resources used into one OSZ file for use on any OpenLP v2 installation.
|
||||
Also handles the UI tasks of moving things up and down etc.
|
||||
"""
|
||||
@ -88,6 +88,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self._fileName = u''
|
||||
self.serviceNoteForm = ServiceNoteForm(self.mainwindow)
|
||||
self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow)
|
||||
self.startTimeForm = StartTimeForm(self.mainwindow)
|
||||
# start with the layout
|
||||
self.layout = QtGui.QVBoxLayout(self)
|
||||
self.layout.setSpacing(0)
|
||||
@ -95,20 +96,16 @@ class ServiceManager(QtGui.QWidget):
|
||||
# Create the top toolbar
|
||||
self.toolbar = OpenLPToolbar(self)
|
||||
self.toolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', 'New Service'),
|
||||
u':/general/general_new.png',
|
||||
translate('OpenLP.ServiceManager', 'Create a new service'),
|
||||
self.onNewServiceClicked)
|
||||
UiStrings.NewService, u':/general/general_new.png',
|
||||
UiStrings.CreateService, self.onNewServiceClicked)
|
||||
self.toolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', 'Open Service'),
|
||||
u':/general/general_open.png',
|
||||
UiStrings.OpenService, u':/general/general_open.png',
|
||||
translate('OpenLP.ServiceManager', 'Load an existing service'),
|
||||
self.onLoadServiceClicked)
|
||||
self.toolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', 'Save Service'),
|
||||
u':/general/general_save.png',
|
||||
UiStrings.SaveService, u':/general/general_save.png',
|
||||
translate('OpenLP.ServiceManager', 'Save this service'),
|
||||
self.onSaveServiceClicked)
|
||||
self.saveFile)
|
||||
self.toolbar.addSeparator()
|
||||
self.themeLabel = QtGui.QLabel(translate('OpenLP.ServiceManager',
|
||||
'Theme:'), self)
|
||||
@ -178,8 +175,8 @@ class ServiceManager(QtGui.QWidget):
|
||||
translate('OpenLP.ServiceManager', 'Move &down'),
|
||||
None,
|
||||
translate('OpenLP.ServiceManager',
|
||||
'Moves the selection up the window.'),
|
||||
self.onMoveSelectionDown, shortcut=QtCore.Qt.Key_Up)
|
||||
'Moves the selection down the window.'),
|
||||
self.onMoveSelectionDown, shortcut=QtCore.Qt.Key_Down)
|
||||
self.serviceManagerList.down.setVisible(False)
|
||||
self.serviceManagerList.up = self.orderToolbar.addToolbarButton(
|
||||
translate('OpenLP.ServiceManager', 'Move up'),
|
||||
@ -270,16 +267,19 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.notesAction = self.menu.addAction(
|
||||
translate('OpenLP.ServiceManager', '&Notes'))
|
||||
self.notesAction.setIcon(build_icon(u':/services/service_notes.png'))
|
||||
self.timeAction = self.menu.addAction(
|
||||
translate('OpenLP.ServiceManager', '&Start Time'))
|
||||
self.timeAction.setIcon(build_icon(u':/media/media_time.png'))
|
||||
self.deleteAction = self.menu.addAction(
|
||||
translate('OpenLP.ServiceManager', '&Delete From Service'))
|
||||
self.deleteAction.setIcon(build_icon(u':/general/general_delete.png'))
|
||||
self.sep1 = self.menu.addAction(u'')
|
||||
self.sep1.setSeparator(True)
|
||||
self.previewAction = self.menu.addAction(
|
||||
translate('OpenLP.ServiceManager', '&Preview Verse'))
|
||||
translate('OpenLP.ServiceManager', 'Show &Preview'))
|
||||
self.previewAction.setIcon(build_icon(u':/general/general_preview.png'))
|
||||
self.liveAction = self.menu.addAction(
|
||||
translate('OpenLP.ServiceManager', '&Live Verse'))
|
||||
translate('OpenLP.ServiceManager', 'Show &Live'))
|
||||
self.liveAction.setIcon(build_icon(u':/general/general_live.png'))
|
||||
self.sep2 = self.menu.addAction(u'')
|
||||
self.sep2.setSeparator(True)
|
||||
@ -361,12 +361,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
Create a new service.
|
||||
"""
|
||||
if self.isModified():
|
||||
result = QtGui.QMessageBox.question(self.mainwindow,
|
||||
translate('OpenLP.ServiceManager', 'Save Changes'),
|
||||
translate('OpenLP.ServiceManager', 'The current service has '
|
||||
'been modified, would you like to save it?'),
|
||||
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
|
||||
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
|
||||
result = self.saveModifiedService()
|
||||
if result == QtGui.QMessageBox.Cancel:
|
||||
return False
|
||||
elif result == QtGui.QMessageBox.Save:
|
||||
@ -376,12 +371,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def onLoadServiceClicked(self):
|
||||
if self.isModified():
|
||||
result = QtGui.QMessageBox.question(self.mainwindow,
|
||||
translate('OpenLP.ServiceManager', 'Save Changes'),
|
||||
translate('OpenLP.ServiceManager', 'The current service has '
|
||||
'been modified, would you like to save it?'),
|
||||
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
|
||||
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
|
||||
result = self.saveModifiedService()
|
||||
if result == QtGui.QMessageBox.Cancel:
|
||||
return False
|
||||
elif result == QtGui.QMessageBox.Save:
|
||||
@ -397,11 +387,13 @@ class ServiceManager(QtGui.QWidget):
|
||||
split_filename(fileName)[0])
|
||||
self.loadFile(fileName)
|
||||
|
||||
def onSaveServiceClicked(self):
|
||||
self.saveFile()
|
||||
|
||||
def onSaveServiceAsClicked(self):
|
||||
self.saveFileAs()
|
||||
def saveModifiedService(self):
|
||||
return QtGui.QMessageBox.question(self.mainwindow,
|
||||
translate('OpenLP.ServiceManager', 'Modified Service'),
|
||||
translate('OpenLP.ServiceManager', 'The current service has '
|
||||
'been modified. Would you like to save this service?'),
|
||||
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
|
||||
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
|
||||
|
||||
def onRecentServiceClicked(self):
|
||||
sender = self.sender()
|
||||
@ -469,11 +461,11 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def saveFileAs(self):
|
||||
"""
|
||||
Get a file name and then call :function:`ServiceManager.saveFile` to
|
||||
Get a file name and then call :func:`ServiceManager.saveFile` to
|
||||
save the file.
|
||||
"""
|
||||
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
|
||||
translate('OpenLP.ServiceManager', 'Save Service'),
|
||||
UiStrings.SaveService,
|
||||
SettingsManager.get_last_dir(
|
||||
self.mainwindow.serviceSettingsSection),
|
||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
||||
@ -499,7 +491,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
for file in zip.namelist():
|
||||
ucsfile = file_is_unicode(file)
|
||||
if not ucsfile:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
message=translate('OpenLP.ServiceManager',
|
||||
'File is not a valid service.\n'
|
||||
'The content encoding is not UTF-8.'))
|
||||
@ -514,6 +506,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
if filePath.endswith(u'osd'):
|
||||
p_file = filePath
|
||||
if 'p_file' in locals():
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
fileTo = open(p_file, u'r')
|
||||
items = cPickle.load(fileTo)
|
||||
fileTo.close()
|
||||
@ -528,13 +521,14 @@ class ServiceManager(QtGui.QWidget):
|
||||
Receiver.send_message(u'%s_service_load' %
|
||||
serviceItem.name.lower(), serviceItem)
|
||||
delete_file(p_file)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
else:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
message=translate('OpenLP.ServiceManager',
|
||||
'File is not a valid service.'))
|
||||
log.exception(u'File contains no service data')
|
||||
except (IOError, NameError):
|
||||
log.exception(u'Problem loading a service file')
|
||||
log.exception(u'Problem loading service file %s' % fileName)
|
||||
finally:
|
||||
if fileTo:
|
||||
fileTo.close()
|
||||
@ -544,9 +538,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.mainwindow.addRecentFile(fileName)
|
||||
self.setModified(False)
|
||||
QtCore.QSettings(). \
|
||||
setValue(u'service/last file',QtCore.QVariant(fileName))
|
||||
# Refresh Plugin lists
|
||||
Receiver.send_message(u'plugin_list_refresh')
|
||||
setValue(u'service/last file', QtCore.QVariant(fileName))
|
||||
|
||||
def loadLastFile(self):
|
||||
"""
|
||||
@ -571,6 +563,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.editAction.setVisible(False)
|
||||
self.maintainAction.setVisible(False)
|
||||
self.notesAction.setVisible(False)
|
||||
self.timeAction.setVisible(False)
|
||||
if serviceItem[u'service_item'].is_capable(ItemCapabilities.AllowsEdit)\
|
||||
and serviceItem[u'service_item'].edit_id:
|
||||
self.editAction.setVisible(True)
|
||||
@ -579,6 +572,9 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.maintainAction.setVisible(True)
|
||||
if item.parent() is None:
|
||||
self.notesAction.setVisible(True)
|
||||
if serviceItem[u'service_item']\
|
||||
.is_capable(ItemCapabilities.AllowsVarableStartTime):
|
||||
self.timeAction.setVisible(True)
|
||||
self.themeMenu.menuAction().setVisible(False)
|
||||
if serviceItem[u'service_item'].is_text():
|
||||
self.themeMenu.menuAction().setVisible(True)
|
||||
@ -591,6 +587,8 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.onDeleteFromService()
|
||||
if action == self.notesAction:
|
||||
self.onServiceItemNoteForm()
|
||||
if action == self.timeAction:
|
||||
self.onStartTimeForm()
|
||||
if action == self.previewAction:
|
||||
self.makePreview()
|
||||
if action == self.liveAction:
|
||||
@ -603,7 +601,17 @@ class ServiceManager(QtGui.QWidget):
|
||||
if self.serviceNoteForm.exec_():
|
||||
self.serviceItems[item][u'service_item'].notes = \
|
||||
self.serviceNoteForm.textEdit.toPlainText()
|
||||
self.repaintServiceList(item, 0)
|
||||
self.repaintServiceList(item, -1)
|
||||
|
||||
def onStartTimeForm(self):
|
||||
item = self.findServiceItem()[0]
|
||||
self.startTimeForm.item = self.serviceItems[item]
|
||||
if self.startTimeForm.exec_():
|
||||
self.serviceItems[item][u'service_item'].start_time = \
|
||||
self.startTimeForm.hourSpinBox.value() * 3600 + \
|
||||
self.startTimeForm.minuteSpinBox.value() * 60 + \
|
||||
self.startTimeForm.secondSpinBox.value()
|
||||
self.repaintServiceList(item, -1)
|
||||
|
||||
def onServiceItemEditForm(self):
|
||||
item = self.findServiceItem()[0]
|
||||
@ -615,8 +623,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def nextItem(self):
|
||||
"""
|
||||
Called by the SlideController to select the
|
||||
next service item
|
||||
Called by the SlideController to select the next service item.
|
||||
"""
|
||||
if len(self.serviceManagerList.selectedItems()) == 0:
|
||||
return
|
||||
@ -634,8 +641,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def previousItem(self):
|
||||
"""
|
||||
Called by the SlideController to select the
|
||||
previous service item
|
||||
Called by the SlideController to select the previous service item.
|
||||
"""
|
||||
if len(self.serviceManagerList.selectedItems()) == 0:
|
||||
return
|
||||
@ -654,13 +660,13 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def onSetItem(self, message):
|
||||
"""
|
||||
Called by a signal to select a specific item
|
||||
Called by a signal to select a specific item.
|
||||
"""
|
||||
self.setItem(int(message[0]))
|
||||
|
||||
def setItem(self, index):
|
||||
"""
|
||||
Makes a specific item in the service live
|
||||
Makes a specific item in the service live.
|
||||
"""
|
||||
if index >= 0 and index < self.serviceManagerList.topLevelItemCount:
|
||||
item = self.serviceManagerList.topLevelItem(index)
|
||||
@ -669,8 +675,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def onMoveSelectionUp(self):
|
||||
"""
|
||||
Moves the selection up the window
|
||||
Called by the up arrow
|
||||
Moves the selection up the window. Called by the up arrow.
|
||||
"""
|
||||
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
|
||||
tempItem = None
|
||||
@ -695,8 +700,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def onMoveSelectionDown(self):
|
||||
"""
|
||||
Moves the selection down the window
|
||||
Called by the down arrow
|
||||
Moves the selection down the window. Called by the down arrow.
|
||||
"""
|
||||
serviceIterator = QtGui.QTreeWidgetItemIterator(self.serviceManagerList)
|
||||
firstItem = None
|
||||
@ -718,7 +722,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def onCollapseAll(self):
|
||||
"""
|
||||
Collapse all the service items
|
||||
Collapse all the service items.
|
||||
"""
|
||||
for item in self.serviceItems:
|
||||
item[u'expanded'] = False
|
||||
@ -726,15 +730,15 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def collapsed(self, item):
|
||||
"""
|
||||
Record if an item is collapsed
|
||||
Used when repainting the list to get the correct state
|
||||
Record if an item is collapsed. Used when repainting the list to get the
|
||||
correct state.
|
||||
"""
|
||||
pos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
self.serviceItems[pos -1 ][u'expanded'] = False
|
||||
|
||||
def onExpandAll(self):
|
||||
"""
|
||||
Collapse all the service items
|
||||
Collapse all the service items.
|
||||
"""
|
||||
for item in self.serviceItems:
|
||||
item[u'expanded'] = True
|
||||
@ -742,70 +746,68 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def expanded(self, item):
|
||||
"""
|
||||
Record if an item is collapsed
|
||||
Used when repainting the list to get the correct state
|
||||
Record if an item is collapsed. Used when repainting the list to get the
|
||||
correct state.
|
||||
"""
|
||||
pos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
self.serviceItems[pos -1 ][u'expanded'] = True
|
||||
|
||||
def onServiceTop(self):
|
||||
"""
|
||||
Move the current ServiceItem to the top of the list
|
||||
Move the current ServiceItem to the top of the list.
|
||||
"""
|
||||
item, count = self.findServiceItem()
|
||||
item, child = self.findServiceItem()
|
||||
if item < len(self.serviceItems) and item is not -1:
|
||||
temp = self.serviceItems[item]
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.serviceItems.insert(0, temp)
|
||||
self.repaintServiceList(0, count)
|
||||
self.repaintServiceList(0, child)
|
||||
self.setModified(True)
|
||||
|
||||
def onServiceUp(self):
|
||||
"""
|
||||
Move the current ServiceItem up in the list
|
||||
Note move up means move to top of area ie 0.
|
||||
Move the current ServiceItem one position up in the list.
|
||||
"""
|
||||
item, count = self.findServiceItem()
|
||||
item, child = self.findServiceItem()
|
||||
if item > 0:
|
||||
temp = self.serviceItems[item]
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.serviceItems.insert(item - 1, temp)
|
||||
self.repaintServiceList(item - 1, count)
|
||||
self.repaintServiceList(item - 1, child)
|
||||
self.setModified(True)
|
||||
|
||||
def onServiceDown(self):
|
||||
"""
|
||||
Move the current ServiceItem down in the list
|
||||
Note move down means move to bottom of area i.e len().
|
||||
Move the current ServiceItem one position down in the list.
|
||||
"""
|
||||
item, count = self.findServiceItem()
|
||||
item, child = self.findServiceItem()
|
||||
if item < len(self.serviceItems) and item is not -1:
|
||||
temp = self.serviceItems[item]
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.serviceItems.insert(item + 1, temp)
|
||||
self.repaintServiceList(item + 1, count)
|
||||
self.repaintServiceList(item + 1, child)
|
||||
self.setModified(True)
|
||||
|
||||
def onServiceEnd(self):
|
||||
"""
|
||||
Move the current ServiceItem to the bottom of the list
|
||||
Move the current ServiceItem to the bottom of the list.
|
||||
"""
|
||||
item, count = self.findServiceItem()
|
||||
item, child = self.findServiceItem()
|
||||
if item < len(self.serviceItems) and item is not -1:
|
||||
temp = self.serviceItems[item]
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.serviceItems.insert(len(self.serviceItems), temp)
|
||||
self.repaintServiceList(len(self.serviceItems) - 1, count)
|
||||
self.repaintServiceList(len(self.serviceItems) - 1, child)
|
||||
self.setModified(True)
|
||||
|
||||
def onDeleteFromService(self):
|
||||
"""
|
||||
Remove the current ServiceItem from the list
|
||||
Remove the current ServiceItem from the list.
|
||||
"""
|
||||
item = self.findServiceItem()[0]
|
||||
if item is not -1:
|
||||
if item != -1:
|
||||
self.serviceItems.remove(self.serviceItems[item])
|
||||
self.repaintServiceList(0, 0)
|
||||
self.repaintServiceList(item - 1, -1)
|
||||
self.setModified(True)
|
||||
|
||||
def repaintServiceList(self, serviceItem, serviceItemChild):
|
||||
@ -847,7 +849,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
else:
|
||||
treewidgetitem.setIcon(0,
|
||||
build_icon(u':/general/general_delete.png'))
|
||||
treewidgetitem.setText(0, serviceitem.title)
|
||||
treewidgetitem.setText(0, serviceitem.get_display_title())
|
||||
treewidgetitem.setToolTip(0, serviceitem.notes)
|
||||
treewidgetitem.setData(0, QtCore.Qt.UserRole,
|
||||
QtCore.QVariant(item[u'order']))
|
||||
@ -857,6 +859,11 @@ class ServiceManager(QtGui.QWidget):
|
||||
text = frame[u'title'].replace(u'\n', u' ')
|
||||
child.setText(0, text[:40])
|
||||
child.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(count))
|
||||
if item[u'service_item'] \
|
||||
.is_capable(ItemCapabilities.AllowsVarableStartTime):
|
||||
tip = item[u'service_item'].get_media_time()
|
||||
if tip:
|
||||
child.setToolTip(0, tip)
|
||||
if serviceItem == itemcount:
|
||||
if item[u'expanded'] and serviceItemChild == count:
|
||||
self.serviceManagerList.setCurrentItem(child)
|
||||
@ -867,16 +874,16 @@ class ServiceManager(QtGui.QWidget):
|
||||
def validateItem(self, serviceItem):
|
||||
"""
|
||||
Validates the service item and if the suffix matches an accepted
|
||||
one it allows the item to be displayed
|
||||
one it allows the item to be displayed.
|
||||
"""
|
||||
if serviceItem.is_command():
|
||||
type = serviceItem._raw_frames[0][u'title'].split(u'.')[1]
|
||||
type = serviceItem._raw_frames[0][u'title'].split(u'.')[-1]
|
||||
if type not in self.suffixes:
|
||||
serviceItem.is_valid = False
|
||||
|
||||
def cleanUp(self):
|
||||
"""
|
||||
Empties the servicePath of temporary files
|
||||
Empties the servicePath of temporary files.
|
||||
"""
|
||||
for file in os.listdir(self.servicePath):
|
||||
file_path = os.path.join(self.servicePath, file)
|
||||
@ -884,7 +891,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def onThemeComboBoxSelected(self, currentIndex):
|
||||
"""
|
||||
Set the theme for the current service
|
||||
Set the theme for the current service.
|
||||
"""
|
||||
log.debug(u'onThemeComboBoxSelected')
|
||||
self.service_theme = unicode(self.themeComboBox.currentText())
|
||||
@ -967,12 +974,12 @@ class ServiceManager(QtGui.QWidget):
|
||||
# if not passed set to config value
|
||||
if expand is None:
|
||||
expand = self.expandTabs
|
||||
sitem = self.findServiceItem()[0]
|
||||
item.render()
|
||||
if replace:
|
||||
sitem, child = self.findServiceItem()
|
||||
item.merge(self.serviceItems[sitem][u'service_item'])
|
||||
self.serviceItems[sitem][u'service_item'] = item
|
||||
self.repaintServiceList(sitem, 0)
|
||||
self.repaintServiceList(sitem, child)
|
||||
self.mainwindow.liveController.replaceServiceManagerItem(item)
|
||||
else:
|
||||
# nothing selected for dnd
|
||||
@ -981,17 +988,17 @@ class ServiceManager(QtGui.QWidget):
|
||||
for inditem in item:
|
||||
self.serviceItems.append({u'service_item': inditem,
|
||||
u'order': len(self.serviceItems) + 1,
|
||||
u'expanded':expand})
|
||||
u'expanded': expand})
|
||||
else:
|
||||
self.serviceItems.append({u'service_item': item,
|
||||
u'order': len(self.serviceItems) + 1,
|
||||
u'expanded':expand})
|
||||
self.repaintServiceList(len(self.serviceItems) + 1, 0)
|
||||
u'expanded': expand})
|
||||
self.repaintServiceList(len(self.serviceItems) - 1, -1)
|
||||
else:
|
||||
self.serviceItems.insert(self.dropPosition,
|
||||
{u'service_item': item, u'order': self.dropPosition,
|
||||
u'expanded':expand})
|
||||
self.repaintServiceList(self.dropPosition, 0)
|
||||
u'expanded': expand})
|
||||
self.repaintServiceList(self.dropPosition, -1)
|
||||
# if rebuilding list make sure live is fixed.
|
||||
if rebuild:
|
||||
self.mainwindow.liveController.replaceServiceManagerItem(item)
|
||||
@ -1002,15 +1009,15 @@ class ServiceManager(QtGui.QWidget):
|
||||
"""
|
||||
Send the current item to the Preview slide controller
|
||||
"""
|
||||
item, count = self.findServiceItem()
|
||||
item, child = self.findServiceItem()
|
||||
if self.serviceItems[item][u'service_item'].is_valid:
|
||||
self.mainwindow.previewController.addServiceManagerItem(
|
||||
self.serviceItems[item][u'service_item'], count)
|
||||
self.serviceItems[item][u'service_item'], child)
|
||||
else:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
||||
translate('OpenLP.ServiceManager', 'Your item cannot be '
|
||||
'displayed as there is no handler to display it'))
|
||||
'displayed as there is no handler to display it'))
|
||||
|
||||
def getServiceItem(self):
|
||||
"""
|
||||
@ -1026,10 +1033,10 @@ class ServiceManager(QtGui.QWidget):
|
||||
"""
|
||||
Send the current item to the Live slide controller
|
||||
"""
|
||||
item, count = self.findServiceItem()
|
||||
item, child = self.findServiceItem()
|
||||
if self.serviceItems[item][u'service_item'].is_valid:
|
||||
self.mainwindow.liveController.addServiceManagerItem(
|
||||
self.serviceItems[item][u'service_item'], count)
|
||||
self.serviceItems[item][u'service_item'], child)
|
||||
if QtCore.QSettings().value(
|
||||
self.mainwindow.generalSettingsSection + u'/auto preview',
|
||||
QtCore.QVariant(False)).toBool():
|
||||
@ -1041,7 +1048,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.serviceItems[item][u'service_item'], 0)
|
||||
self.mainwindow.liveController.previewListWidget.setFocus()
|
||||
else:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ServiceManager', 'Missing Display Handler'),
|
||||
translate('OpenLP.ServiceManager', 'Your item cannot be '
|
||||
'displayed as the plugin required to display it is missing '
|
||||
@ -1060,26 +1067,26 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def findServiceItem(self):
|
||||
"""
|
||||
Finds a ServiceItem in the list and returns the position of the
|
||||
serviceitem and its selected child item. For example, if the third child
|
||||
item (in the Slidecontroller known as slide) in the second service item
|
||||
is selected this will return::
|
||||
Finds the selected ServiceItem in the list and returns the position of
|
||||
the serviceitem and its selected child item. For example, if the third
|
||||
child item (in the Slidecontroller known as slide) in the second service
|
||||
item is selected this will return::
|
||||
|
||||
(1, 2)
|
||||
"""
|
||||
items = self.serviceManagerList.selectedItems()
|
||||
pos = 0
|
||||
count = -1
|
||||
serviceItem = 0
|
||||
serviceItemChild = -1
|
||||
for item in items:
|
||||
parentitem = item.parent()
|
||||
if parentitem is None:
|
||||
pos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
serviceItem = item.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
else:
|
||||
pos = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
count = item.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
# adjust for zero based arrays
|
||||
pos = pos - 1
|
||||
return pos, count
|
||||
serviceItem = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
serviceItemChild = item.data(0, QtCore.Qt.UserRole).toInt()[0]
|
||||
# Adjust for zero based arrays.
|
||||
serviceItem -= 1
|
||||
return serviceItem, serviceItemChild
|
||||
|
||||
def dragEnterEvent(self, event):
|
||||
"""
|
||||
@ -1105,7 +1112,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
item = self.serviceManagerList.itemAt(event.pos())
|
||||
# ServiceManager started the drag and drop
|
||||
if plugin == u'ServiceManager':
|
||||
startpos, startCount = self.findServiceItem()
|
||||
startpos, child = self.findServiceItem()
|
||||
# If no items selected
|
||||
if startpos == -1:
|
||||
return
|
||||
@ -1116,7 +1123,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
serviceItem = self.serviceItems[startpos]
|
||||
self.serviceItems.remove(serviceItem)
|
||||
self.serviceItems.insert(endpos, serviceItem)
|
||||
self.repaintServiceList(endpos, startCount)
|
||||
self.repaintServiceList(endpos, child)
|
||||
else:
|
||||
# we are not over anything so drop
|
||||
replace = False
|
||||
@ -1182,17 +1189,24 @@ class ServiceManager(QtGui.QWidget):
|
||||
|
||||
def listRequest(self, message=None):
|
||||
data = []
|
||||
curindex = self.findServiceItem()[0]
|
||||
if curindex >= 0 and curindex < len(self.serviceItems):
|
||||
curitem = self.serviceItems[curindex]
|
||||
item = self.findServiceItem()[0]
|
||||
if item >= 0 and item < len(self.serviceItems):
|
||||
curitem = self.serviceItems[item]
|
||||
else:
|
||||
curitem = None
|
||||
for item in self.serviceItems:
|
||||
service_item = item[u'service_item']
|
||||
data_item = {}
|
||||
data_item[u'title'] = unicode(service_item.title)
|
||||
data_item[u'title'] = unicode(service_item.get_display_title())
|
||||
data_item[u'plugin'] = unicode(service_item.name)
|
||||
data_item[u'notes'] = unicode(service_item.notes)
|
||||
data_item[u'selected'] = (item == curitem)
|
||||
data.append(data_item)
|
||||
Receiver.send_message(u'servicemanager_list_response', data)
|
||||
|
||||
def printServiceOrder(self):
|
||||
"""
|
||||
Print a Service Order Sheet.
|
||||
"""
|
||||
settingDialog = PrintServiceOrderForm(self.mainwindow, self)
|
||||
settingDialog.exec_()
|
||||
|
@ -26,9 +26,10 @@
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from servicenotedialog import Ui_ServiceNoteEdit
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import create_accept_reject_button_box
|
||||
|
||||
class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit):
|
||||
class ServiceNoteForm(QtGui.QDialog):
|
||||
"""
|
||||
This is the form that is used to edit the verses of the song.
|
||||
"""
|
||||
@ -37,8 +38,19 @@ class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit):
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
|
||||
self.accept)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
|
||||
self.reject)
|
||||
self.setupUi()
|
||||
self.retranslateUi()
|
||||
|
||||
def setupUi(self):
|
||||
self.setObjectName(u'serviceNoteEdit')
|
||||
self.dialogLayout = QtGui.QVBoxLayout(self)
|
||||
self.dialogLayout.setObjectName(u'verticalLayout')
|
||||
self.textEdit = QtGui.QTextEdit(self)
|
||||
self.textEdit.setObjectName(u'textEdit')
|
||||
self.dialogLayout.addWidget(self.textEdit)
|
||||
self.dialogLayout.addWidget(create_accept_reject_button_box(self))
|
||||
QtCore.QMetaObject.connectSlotsByName(self)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.setWindowTitle(
|
||||
translate('OpenLP.ServiceNoteForm', 'Service Item Notes'))
|
||||
|
@ -27,6 +27,7 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, build_icon
|
||||
from openlp.core.lib.ui import create_accept_reject_button_box
|
||||
|
||||
class Ui_SettingsDialog(object):
|
||||
def setupUi(self, settingsDialog):
|
||||
@ -35,21 +36,13 @@ class Ui_SettingsDialog(object):
|
||||
settingsDialog.setWindowIcon(
|
||||
build_icon(u':/system/system_settings.png'))
|
||||
self.settingsLayout = QtGui.QVBoxLayout(settingsDialog)
|
||||
margins = self.settingsLayout.contentsMargins()
|
||||
self.settingsLayout.setObjectName(u'settingsLayout')
|
||||
self.settingsTabWidget = QtGui.QTabWidget(settingsDialog)
|
||||
self.settingsTabWidget.setObjectName(u'settingsTabWidget')
|
||||
self.settingsLayout.addWidget(self.settingsTabWidget)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(settingsDialog)
|
||||
self.buttonBox.setStandardButtons(
|
||||
QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.buttonBox = create_accept_reject_button_box(settingsDialog, True)
|
||||
self.settingsLayout.addWidget(self.buttonBox)
|
||||
self.retranslateUi(settingsDialog)
|
||||
QtCore.QObject.connect(self.buttonBox,
|
||||
QtCore.SIGNAL(u'accepted()'), settingsDialog.accept)
|
||||
QtCore.QObject.connect(self.buttonBox,
|
||||
QtCore.SIGNAL(u'rejected()'), settingsDialog.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(settingsDialog)
|
||||
|
||||
def retranslateUi(self, settingsDialog):
|
||||
|
@ -36,7 +36,7 @@ class Ui_ShortcutListDialog(object):
|
||||
self.treeWidget = QtGui.QTreeWidget(shortcutListDialog)
|
||||
self.treeWidget.setAlternatingRowColors(True)
|
||||
self.treeWidget.setObjectName(u'treeWidget')
|
||||
self.treeWidget.setColumnCount(2)
|
||||
self.treeWidget.setColumnCount(3)
|
||||
self.dialogLayout.addWidget(self.treeWidget)
|
||||
self.defaultButton = QtGui.QRadioButton(shortcutListDialog)
|
||||
self.defaultButton.setChecked(True)
|
||||
@ -78,7 +78,8 @@ class Ui_ShortcutListDialog(object):
|
||||
translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts'))
|
||||
self.treeWidget.setHeaderLabels([
|
||||
translate('OpenLP.ShortcutListDialog', 'Action'),
|
||||
translate('OpenLP.ShortcutListDialog', 'Shortcut')])
|
||||
translate('OpenLP.ShortcutListDialog', 'Shortcut'),
|
||||
translate('OpenLP.ShortcutListDialog', 'Alternate')])
|
||||
self.defaultButton.setText(
|
||||
translate('OpenLP.ShortcutListDialog', 'Default: %s'))
|
||||
self.customButton.setText(
|
||||
|
@ -95,8 +95,13 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
||||
item = QtGui.QTreeWidgetItem([category.name])
|
||||
for action in category.actions:
|
||||
actionText = REMOVE_AMPERSAND.sub('', unicode(action.text()))
|
||||
shortcutText = action.shortcut().toString()
|
||||
actionItem = QtGui.QTreeWidgetItem([actionText, shortcutText])
|
||||
if (len(action.shortcuts()) == 2):
|
||||
shortcutText = action.shortcuts()[0].toString()
|
||||
alternateText = action.shortcuts()[1].toString()
|
||||
else:
|
||||
shortcutText = action.shortcut().toString()
|
||||
alternateText = u''
|
||||
actionItem = QtGui.QTreeWidgetItem([actionText, shortcutText, alternateText])
|
||||
actionItem.setIcon(0, action.icon())
|
||||
item.addChild(actionItem)
|
||||
item.setExpanded(True)
|
||||
|
@ -30,9 +30,10 @@ import os
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt4.phonon import Phonon
|
||||
|
||||
from openlp.core.ui import HideMode, MainDisplay
|
||||
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
|
||||
ItemCapabilities, translate
|
||||
from openlp.core.lib.ui import UiStrings, shortcut_action
|
||||
from openlp.core.ui import HideMode, MainDisplay
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -77,28 +78,27 @@ class SlideController(QtGui.QWidget):
|
||||
self.selectedRow = 0
|
||||
self.serviceItem = None
|
||||
self.alertTab = None
|
||||
self.Panel = QtGui.QWidget(parent.ControlSplitter)
|
||||
self.panel = QtGui.QWidget(parent.controlSplitter)
|
||||
self.slideList = {}
|
||||
# Layout for holding panel
|
||||
self.panelLayout = QtGui.QVBoxLayout(self.Panel)
|
||||
self.panelLayout = QtGui.QVBoxLayout(self.panel)
|
||||
self.panelLayout.setSpacing(0)
|
||||
self.panelLayout.setMargin(0)
|
||||
# Type label for the top of the slide controller
|
||||
self.typeLabel = QtGui.QLabel(self.Panel)
|
||||
self.typeLabel = QtGui.QLabel(self.panel)
|
||||
if self.isLive:
|
||||
self.typeLabel.setText(translate('OpenLP.SlideController', 'Live'))
|
||||
self.typeLabel.setText(UiStrings.Live)
|
||||
self.split = 1
|
||||
self.typePrefix = u'live'
|
||||
else:
|
||||
self.typeLabel.setText(translate('OpenLP.SlideController',
|
||||
'Preview'))
|
||||
self.typeLabel.setText(UiStrings.Preview)
|
||||
self.split = 0
|
||||
self.typePrefix = u'preview'
|
||||
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
|
||||
self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.panelLayout.addWidget(self.typeLabel)
|
||||
# Splitter
|
||||
self.splitter = QtGui.QSplitter(self.Panel)
|
||||
self.splitter = QtGui.QSplitter(self.panel)
|
||||
self.splitter.setOrientation(QtCore.Qt.Vertical)
|
||||
self.panelLayout.addWidget(self.splitter)
|
||||
# Actual controller section
|
||||
@ -119,6 +119,8 @@ class SlideController(QtGui.QWidget):
|
||||
self.previewListWidget.isLive = self.isLive
|
||||
self.previewListWidget.setObjectName(u'PreviewListWidget')
|
||||
self.previewListWidget.setSelectionBehavior(1)
|
||||
self.previewListWidget.setSelectionMode(
|
||||
QtGui.QAbstractItemView.SingleSelection)
|
||||
self.previewListWidget.setEditTriggers(
|
||||
QtGui.QAbstractItemView.NoEditTriggers)
|
||||
self.previewListWidget.setHorizontalScrollBarPolicy(
|
||||
@ -176,29 +178,33 @@ class SlideController(QtGui.QWidget):
|
||||
QtCore.SIGNAL(u'triggered(bool)'), self.onHideDisplay)
|
||||
self.toolbar.addToolbarSeparator(u'Loop Separator')
|
||||
self.toolbar.addToolbarButton(
|
||||
# Does not need translating - control string.
|
||||
u'Start Loop', u':/media/media_time.png',
|
||||
translate('OpenLP.SlideController', 'Start continuous loop'),
|
||||
self.onStartLoop)
|
||||
self.toolbar.addToolbarButton(
|
||||
# Does not need translating - control string.
|
||||
u'Stop Loop', u':/media/media_stop.png',
|
||||
translate('OpenLP.SlideController', 'Stop continuous loop'),
|
||||
self.onStopLoop)
|
||||
self.DelaySpinBox = QtGui.QSpinBox()
|
||||
self.DelaySpinBox.setMinimum(1)
|
||||
self.DelaySpinBox.setMaximum(180)
|
||||
self.toolbar.addToolbarWidget(u'Image SpinBox', self.DelaySpinBox)
|
||||
self.DelaySpinBox.setSuffix(translate('OpenLP.SlideController',
|
||||
self.delaySpinBox = QtGui.QSpinBox()
|
||||
self.delaySpinBox.setMinimum(1)
|
||||
self.delaySpinBox.setMaximum(180)
|
||||
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
|
||||
self.delaySpinBox.setSuffix(translate('OpenLP.SlideController',
|
||||
's'))
|
||||
self.DelaySpinBox.setToolTip(translate('OpenLP.SlideController',
|
||||
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
|
||||
'Delay between slides in seconds'))
|
||||
else:
|
||||
self.toolbar.addToolbarSeparator(u'Close Separator')
|
||||
self.toolbar.addToolbarButton(
|
||||
# Does not need translating - control string.
|
||||
u'Go Live', u':/general/general_live.png',
|
||||
translate('OpenLP.SlideController', 'Move to live'),
|
||||
self.onGoLive)
|
||||
self.toolbar.addToolbarSeparator(u'Close Separator')
|
||||
self.toolbar.addToolbarButton(
|
||||
# Does not need translating - control string.
|
||||
u'Edit Song', u':/general/general_edit.png',
|
||||
translate('OpenLP.SlideController',
|
||||
'Edit and reload song preview'),
|
||||
@ -315,18 +321,8 @@ class SlideController(QtGui.QWidget):
|
||||
self.mediabar.setVisible(False)
|
||||
if self.isLive:
|
||||
self.setLiveHotkeys(self)
|
||||
self.previewListWidget.addActions(
|
||||
[self.previousItem,
|
||||
self.nextItem,
|
||||
self.previousService,
|
||||
self.nextService,
|
||||
self.escapeItem])
|
||||
self.display.addActions(
|
||||
[self.previousItem,
|
||||
self.nextItem,
|
||||
self.previousService,
|
||||
self.nextService,
|
||||
self.escapeItem])
|
||||
self.__addActionsToWidget(self.previewListWidget)
|
||||
self.__addActionsToWidget(self.display)
|
||||
else:
|
||||
self.setPreviewHotkeys()
|
||||
self.previewListWidget.addActions(
|
||||
@ -384,32 +380,21 @@ class SlideController(QtGui.QWidget):
|
||||
self.previousItem.setShortcuts([QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp])
|
||||
self.previousItem.setShortcutContext(
|
||||
QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
actionList.add_action(self.nextItem, u'Live')
|
||||
actionList.add_action(self.previousItem, u'Live')
|
||||
self.nextItem.setShortcuts([QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown])
|
||||
self.nextItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
actionList.add_action(self.nextItem, u'Live')
|
||||
self.previousService = QtGui.QAction(translate(
|
||||
'OpenLP.SlideController', 'Previous Service'), parent)
|
||||
self.previousService.setShortcuts([QtCore.Qt.Key_Left, 0])
|
||||
self.previousService.setShortcutContext(
|
||||
QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
QtCore.QObject.connect(self.previousService,
|
||||
QtCore.SIGNAL(u'triggered()'), self.servicePrevious)
|
||||
self.previousService = shortcut_action(parent,
|
||||
translate('OpenLP.SlideController', 'Previous Service'),
|
||||
[QtCore.Qt.Key_Left, 0], self.servicePrevious)
|
||||
actionList.add_action(self.previousService, u'Live')
|
||||
self.nextService = QtGui.QAction(translate(
|
||||
'OpenLP.SlideController', 'Next Service'), parent)
|
||||
self.nextService.setShortcuts([QtCore.Qt.Key_Right, 0])
|
||||
self.nextService.setShortcutContext(
|
||||
QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
QtCore.QObject.connect(self.nextService,
|
||||
QtCore.SIGNAL(u'triggered()'), self.serviceNext)
|
||||
self.nextService = shortcut_action(parent,
|
||||
translate('OpenLP.SlideController', 'Next Service'),
|
||||
[QtCore.Qt.Key_Right, 0], self.serviceNext)
|
||||
actionList.add_action(self.nextService, u'Live')
|
||||
self.escapeItem = QtGui.QAction(translate(
|
||||
'OpenLP.SlideController', 'Escape Item'), parent)
|
||||
self.escapeItem.setShortcuts([QtCore.Qt.Key_Escape, 0])
|
||||
self.escapeItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
|
||||
QtCore.QObject.connect(self.escapeItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.liveEscape)
|
||||
self.escapeItem = shortcut_action(parent,
|
||||
translate('OpenLP.SlideController', 'Escape Item'),
|
||||
[QtCore.Qt.Key_Escape, 0], self.liveEscape)
|
||||
actionList.add_action(self.escapeItem, u'Live')
|
||||
|
||||
def liveEscape(self):
|
||||
@ -433,12 +418,7 @@ class SlideController(QtGui.QWidget):
|
||||
self.display.alertTab = self.alertTab
|
||||
self.display.setup()
|
||||
if self.isLive:
|
||||
self.display.addActions(
|
||||
[self.previousItem,
|
||||
self.nextItem,
|
||||
self.previousService,
|
||||
self.nextService,
|
||||
self.escapeItem])
|
||||
self.__addActionsToWidget(self.display)
|
||||
# The SlidePreview's ratio.
|
||||
self.ratio = float(self.screens.current[u'size'].width()) / \
|
||||
float(self.screens.current[u'size'].height())
|
||||
@ -446,6 +426,12 @@ class SlideController(QtGui.QWidget):
|
||||
if self.serviceItem:
|
||||
self.refreshServiceItem()
|
||||
|
||||
def __addActionsToWidget(self, widget):
|
||||
widget.addActions([
|
||||
self.previousItem, self.nextItem,
|
||||
self.previousService, self.nextService,
|
||||
self.escapeItem])
|
||||
|
||||
def previewSizeChanged(self):
|
||||
"""
|
||||
Takes care of the SlidePreview's size. Is called when one of the the
|
||||
@ -472,7 +458,7 @@ class SlideController(QtGui.QWidget):
|
||||
self.previewListWidget.resizeRowsToContents()
|
||||
else:
|
||||
# Sort out image heights.
|
||||
width = self.parent.ControlSplitter.sizes()[self.split]
|
||||
width = self.parent.controlSplitter.sizes()[self.split]
|
||||
for framenumber in range(len(self.serviceItem.get_frames())):
|
||||
self.previewListWidget.setRowHeight(
|
||||
framenumber, width / self.ratio)
|
||||
@ -480,18 +466,11 @@ class SlideController(QtGui.QWidget):
|
||||
def onSongBarHandler(self):
|
||||
request = unicode(self.sender().text())
|
||||
slideno = self.slideList[request]
|
||||
if slideno > self.previewListWidget.rowCount():
|
||||
self.previewListWidget.selectRow(
|
||||
self.previewListWidget.rowCount() - 1)
|
||||
else:
|
||||
if slideno + 1 < self.previewListWidget.rowCount():
|
||||
self.previewListWidget.scrollToItem(
|
||||
self.previewListWidget.item(slideno + 1, 0))
|
||||
self.previewListWidget.selectRow(slideno)
|
||||
self.__updatePreviewSelection(slideno)
|
||||
self.onSlideSelected()
|
||||
|
||||
def receiveSpinDelay(self, value):
|
||||
self.DelaySpinBox.setValue(int(value))
|
||||
self.delaySpinBox.setValue(int(value))
|
||||
|
||||
def enableToolBar(self, item):
|
||||
"""
|
||||
@ -580,10 +559,7 @@ class SlideController(QtGui.QWidget):
|
||||
slideno = 0
|
||||
# If service item is the same as the current on only change slide
|
||||
if item.__eq__(self.serviceItem):
|
||||
if slideno + 1 < self.previewListWidget.rowCount():
|
||||
self.previewListWidget.scrollToItem(
|
||||
self.previewListWidget.item(slideno + 1, 0))
|
||||
self.previewListWidget.selectRow(slideno)
|
||||
self.__checkUpdateSelectedSlide(slideno)
|
||||
self.onSlideSelected()
|
||||
return
|
||||
self._processItem(item, slideno)
|
||||
@ -611,7 +587,7 @@ class SlideController(QtGui.QWidget):
|
||||
Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
|
||||
[serviceItem, self.isLive, blanked, slideno])
|
||||
self.slideList = {}
|
||||
width = self.parent.ControlSplitter.sizes()[self.split]
|
||||
width = self.parent.controlSplitter.sizes()[self.split]
|
||||
self.serviceItem = serviceItem
|
||||
self.previewListWidget.clear()
|
||||
self.previewListWidget.setRowCount(0)
|
||||
@ -663,14 +639,7 @@ class SlideController(QtGui.QWidget):
|
||||
self.previewListWidget.resizeRowsToContents()
|
||||
self.previewListWidget.setColumnWidth(0,
|
||||
self.previewListWidget.viewport().size().width())
|
||||
if slideno > self.previewListWidget.rowCount():
|
||||
self.previewListWidget.selectRow(
|
||||
self.previewListWidget.rowCount() - 1)
|
||||
else:
|
||||
if slideno + 1 < self.previewListWidget.rowCount():
|
||||
self.previewListWidget.scrollToItem(
|
||||
self.previewListWidget.item(slideno + 1, 0))
|
||||
self.previewListWidget.selectRow(slideno)
|
||||
self.__updatePreviewSelection(slideno)
|
||||
self.enableToolBar(serviceItem)
|
||||
# Pass to display for viewing
|
||||
self.display.buildHtml(self.serviceItem)
|
||||
@ -681,6 +650,16 @@ class SlideController(QtGui.QWidget):
|
||||
Receiver.send_message(u'slidecontroller_%s_started' % self.typePrefix,
|
||||
[serviceItem])
|
||||
|
||||
def __updatePreviewSelection(self, slideno):
|
||||
"""
|
||||
Utility method to update the selected slide in the list.
|
||||
"""
|
||||
if slideno > self.previewListWidget.rowCount():
|
||||
self.previewListWidget.selectRow(
|
||||
self.previewListWidget.rowCount() - 1)
|
||||
else:
|
||||
self.__checkUpdateSelectedSlide(slideno)
|
||||
|
||||
def onTextRequest(self):
|
||||
"""
|
||||
Return the text for the current item in controller
|
||||
@ -728,10 +707,7 @@ class SlideController(QtGui.QWidget):
|
||||
[self.serviceItem, self.isLive, index])
|
||||
self.updatePreview()
|
||||
else:
|
||||
if index + 1 < self.previewListWidget.rowCount():
|
||||
self.previewListWidget.scrollToItem(
|
||||
self.previewListWidget.item(index + 1, 0))
|
||||
self.previewListWidget.selectRow(index)
|
||||
self.__checkUpdateSelectedSlide(index)
|
||||
self.onSlideSelected()
|
||||
|
||||
def mainDisplaySetBackground(self):
|
||||
@ -890,10 +866,7 @@ class SlideController(QtGui.QWidget):
|
||||
"""
|
||||
The slide has been changed. Update the slidecontroller accordingly
|
||||
"""
|
||||
if row + 1 < self.previewListWidget.rowCount():
|
||||
self.previewListWidget.scrollToItem(
|
||||
self.previewListWidget.item(row + 1, 0))
|
||||
self.previewListWidget.selectRow(row)
|
||||
self.__checkUpdateSelectedSlide(row)
|
||||
self.updatePreview()
|
||||
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
|
||||
row)
|
||||
@ -904,7 +877,8 @@ class SlideController(QtGui.QWidget):
|
||||
using *Blank to Theme*.
|
||||
"""
|
||||
log.debug(u'updatePreview %s ' % self.screens.current[u'primary'])
|
||||
if not self.screens.current[u'primary']:
|
||||
if not self.screens.current[u'primary'] and self.serviceItem and \
|
||||
self.serviceItem.is_capable(ItemCapabilities.ProvidesOwnDisplay):
|
||||
# Grab now, but try again in a couple of seconds if slide change
|
||||
# is slow
|
||||
QtCore.QTimer.singleShot(0.5, self.grabMainDisplay)
|
||||
@ -944,10 +918,7 @@ class SlideController(QtGui.QWidget):
|
||||
else:
|
||||
Receiver.send_message('servicemanager_next_item')
|
||||
return
|
||||
if row + 1 < self.previewListWidget.rowCount():
|
||||
self.previewListWidget.scrollToItem(
|
||||
self.previewListWidget.item(row + 1, 0))
|
||||
self.previewListWidget.selectRow(row)
|
||||
self.__checkUpdateSelectedSlide(row)
|
||||
self.onSlideSelected()
|
||||
|
||||
def onSlideSelectedPreviousNoloop(self):
|
||||
@ -970,12 +941,15 @@ class SlideController(QtGui.QWidget):
|
||||
row = self.previewListWidget.rowCount() - 1
|
||||
else:
|
||||
row = 0
|
||||
if row + 1 < self.previewListWidget.rowCount():
|
||||
self.previewListWidget.scrollToItem(
|
||||
self.previewListWidget.item(row + 1, 0))
|
||||
self.previewListWidget.selectRow(row)
|
||||
self.__checkUpdateSelectedSlide(row)
|
||||
self.onSlideSelected()
|
||||
|
||||
def __checkUpdateSelectedSlide(self, row):
|
||||
if row + 1 < self.previewListWidget.rowCount():
|
||||
self.previewListWidget.scrollToItem(
|
||||
self.previewListWidget.item(row + 1, 0))
|
||||
self.previewListWidget.selectRow(row)
|
||||
|
||||
def onSlideSelectedLast(self):
|
||||
"""
|
||||
Go to the last slide.
|
||||
@ -997,7 +971,7 @@ class SlideController(QtGui.QWidget):
|
||||
"""
|
||||
if self.previewListWidget.rowCount() > 1:
|
||||
self.timer_id = self.startTimer(
|
||||
int(self.DelaySpinBox.value()) * 1000)
|
||||
int(self.delaySpinBox.value()) * 1000)
|
||||
self.toolbar.actions[u'Stop Loop'].setVisible(True)
|
||||
self.toolbar.actions[u'Start Loop'].setVisible(False)
|
||||
|
||||
|
70
openlp/core/ui/starttimedialog.py
Normal file
70
openlp/core/ui/starttimedialog.py
Normal file
@ -0,0 +1,70 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2011 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
||||
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
||||
# Carsten Tinggaard, Frode Woldsund #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import create_accept_reject_button_box
|
||||
|
||||
class Ui_StartTimeDialog(object):
|
||||
def setupUi(self, StartTimeDialog):
|
||||
StartTimeDialog.setObjectName(u'StartTimeDialog')
|
||||
StartTimeDialog.resize(300, 10)
|
||||
self.dialogLayout = QtGui.QGridLayout(StartTimeDialog)
|
||||
self.dialogLayout.setObjectName(u'dialogLayout')
|
||||
self.hourLabel = QtGui.QLabel(StartTimeDialog)
|
||||
self.hourLabel.setObjectName("hourLabel")
|
||||
self.dialogLayout.addWidget(self.hourLabel, 0, 0, 1, 1)
|
||||
self.hourSpinBox = QtGui.QSpinBox(StartTimeDialog)
|
||||
self.hourSpinBox.setObjectName("hourSpinBox")
|
||||
self.dialogLayout.addWidget(self.hourSpinBox, 0, 1, 1, 1)
|
||||
self.minuteLabel = QtGui.QLabel(StartTimeDialog)
|
||||
self.minuteLabel.setObjectName("minuteLabel")
|
||||
self.dialogLayout.addWidget(self.minuteLabel, 1, 0, 1, 1)
|
||||
self.minuteSpinBox = QtGui.QSpinBox(StartTimeDialog)
|
||||
self.minuteSpinBox.setObjectName("minuteSpinBox")
|
||||
self.dialogLayout.addWidget(self.minuteSpinBox, 1, 1, 1, 1)
|
||||
self.secondLabel = QtGui.QLabel(StartTimeDialog)
|
||||
self.secondLabel.setObjectName("secondLabel")
|
||||
self.dialogLayout.addWidget(self.secondLabel, 2, 0, 1, 1)
|
||||
self.secondSpinBox = QtGui.QSpinBox(StartTimeDialog)
|
||||
self.secondSpinBox.setObjectName("secondSpinBox")
|
||||
self.dialogLayout.addWidget(self.secondSpinBox, 2, 1, 1, 1)
|
||||
self.buttonBox = create_accept_reject_button_box(StartTimeDialog, True)
|
||||
self.dialogLayout.addWidget(self.buttonBox, 4, 0, 1, 2)
|
||||
self.retranslateUi(StartTimeDialog)
|
||||
self.setMaximumHeight(self.sizeHint().height())
|
||||
QtCore.QMetaObject.connectSlotsByName(StartTimeDialog)
|
||||
|
||||
def retranslateUi(self, StartTimeDialog):
|
||||
self.setWindowTitle(translate('OpenLP.StartTimeForm',
|
||||
'Item Start Time'))
|
||||
self.hourLabel.setText(translate('OpenLP.StartTimeForm', 'Hours:'))
|
||||
self.hourSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'h'))
|
||||
self.minuteSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'm'))
|
||||
self.secondSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 's'))
|
||||
self.minuteLabel.setText(translate('OpenLP.StartTimeForm', 'Minutes:'))
|
||||
self.secondLabel.setText(translate('OpenLP.StartTimeForm', 'Seconds:'))
|
@ -24,25 +24,29 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from openlp.core.lib import translate
|
||||
from PyQt4 import QtGui
|
||||
|
||||
class Ui_ServiceNoteEdit(object):
|
||||
def setupUi(self, serviceNoteEdit):
|
||||
serviceNoteEdit.setObjectName(u'serviceNoteEdit')
|
||||
self.dialogLayout = QtGui.QVBoxLayout(serviceNoteEdit)
|
||||
self.dialogLayout.setObjectName(u'verticalLayout')
|
||||
self.textEdit = QtGui.QTextEdit(serviceNoteEdit)
|
||||
self.textEdit.setObjectName(u'textEdit')
|
||||
self.dialogLayout.addWidget(self.textEdit)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(serviceNoteEdit)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
|
||||
QtGui.QDialogButtonBox.Save)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.dialogLayout.addWidget(self.buttonBox)
|
||||
self.retranslateUi(serviceNoteEdit)
|
||||
QtCore.QMetaObject.connectSlotsByName(serviceNoteEdit)
|
||||
from starttimedialog import Ui_StartTimeDialog
|
||||
|
||||
class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
|
||||
"""
|
||||
The exception dialog
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
|
||||
def exec_(self):
|
||||
"""
|
||||
Run the Dialog with correct heading.
|
||||
"""
|
||||
seconds = self.item[u'service_item'].start_time
|
||||
hours = seconds / 3600
|
||||
seconds -= 3600 * hours
|
||||
minutes = seconds / 60
|
||||
seconds -= 60 * minutes
|
||||
self.hourSpinBox.setValue(hours)
|
||||
self.minuteSpinBox.setValue(minutes)
|
||||
self.secondSpinBox.setValue(seconds)
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def retranslateUi(self, serviceNoteEdit):
|
||||
serviceNoteEdit.setWindowTitle(
|
||||
translate('OpenLP.ServiceNoteForm', 'Service Item Notes'))
|
@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \
|
||||
Receiver
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.core.utils import get_images_filter
|
||||
from themewizard import Ui_ThemeWizard
|
||||
|
||||
@ -55,7 +55,6 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
self.thememanager = parent
|
||||
self.setupUi(self)
|
||||
self.registerFields()
|
||||
self.accepted = False
|
||||
self.updateThemeAllowed = True
|
||||
QtCore.QObject.connect(self.backgroundComboBox,
|
||||
QtCore.SIGNAL(u'currentIndexChanged(int)'),
|
||||
@ -120,14 +119,12 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
QtCore.QObject.connect(self.mainFontComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'),
|
||||
self.calculateLines)
|
||||
QtCore.QObject.connect(self, QtCore.SIGNAL(u'accepted()'), self.accept)
|
||||
|
||||
def setDefaults(self):
|
||||
"""
|
||||
Set up display at start of theme edit.
|
||||
"""
|
||||
self.restart()
|
||||
self.accepted = False
|
||||
self.setBackgroundPageValues()
|
||||
self.setMainAreaPageValues()
|
||||
self.setFooterAreaPageValues()
|
||||
@ -250,37 +247,43 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
"""
|
||||
Change state as Outline check box changed
|
||||
"""
|
||||
if state == QtCore.Qt.Checked:
|
||||
self.theme.font_main_outline = True
|
||||
else:
|
||||
self.theme.font_main_outline = False
|
||||
self.outlineColorButton.setEnabled(self.theme.font_main_outline)
|
||||
self.outlineSizeSpinBox.setEnabled(self.theme.font_main_outline)
|
||||
self.calculateLines()
|
||||
if self.updateThemeAllowed:
|
||||
if state == QtCore.Qt.Checked:
|
||||
self.theme.font_main_outline = True
|
||||
else:
|
||||
self.theme.font_main_outline = False
|
||||
self.outlineColorButton.setEnabled(self.theme.font_main_outline)
|
||||
self.outlineSizeSpinBox.setEnabled(self.theme.font_main_outline)
|
||||
self.calculateLines()
|
||||
|
||||
def onShadowCheckCheckBoxStateChanged(self, state):
|
||||
"""
|
||||
Change state as Shadow check box changed
|
||||
"""
|
||||
if state == QtCore.Qt.Checked:
|
||||
self.theme.font_main_shadow = True
|
||||
else:
|
||||
self.theme.font_main_shadow = False
|
||||
self.shadowColorButton.setEnabled(self.theme.font_main_shadow)
|
||||
self.shadowSizeSpinBox.setEnabled(self.theme.font_main_shadow)
|
||||
self.calculateLines()
|
||||
if self.updateThemeAllowed:
|
||||
if state == QtCore.Qt.Checked:
|
||||
self.theme.font_main_shadow = True
|
||||
else:
|
||||
self.theme.font_main_shadow = False
|
||||
self.shadowColorButton.setEnabled(self.theme.font_main_shadow)
|
||||
self.shadowSizeSpinBox.setEnabled(self.theme.font_main_shadow)
|
||||
self.calculateLines()
|
||||
|
||||
def onMainPositionCheckBoxStateChanged(self, value):
|
||||
"""
|
||||
Change state as Main Area Position check box changed
|
||||
NOTE the font_main_override is the inverse of the check box value
|
||||
"""
|
||||
self.theme.font_main_override = (value == QtCore.Qt.Checked)
|
||||
if self.updateThemeAllowed:
|
||||
self.theme.font_main_override = not (value == QtCore.Qt.Checked)
|
||||
|
||||
def onFooterPositionCheckBoxStateChanged(self, value):
|
||||
"""
|
||||
Change state as Footer Area Position check box changed
|
||||
NOTE the font_footer_override is the inverse of the check box value
|
||||
"""
|
||||
self.theme.font_footer_override = (value == QtCore.Qt.Checked)
|
||||
if self.updateThemeAllowed:
|
||||
self.theme.font_footer_override = not (value == QtCore.Qt.Checked)
|
||||
|
||||
def exec_(self, edit=False):
|
||||
"""
|
||||
@ -446,9 +449,10 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
"""
|
||||
Background gradient Combo box has changed.
|
||||
"""
|
||||
self.theme.background_direction = \
|
||||
BackgroundGradientType.to_string(index)
|
||||
self.setBackgroundPageValues()
|
||||
if self.updateThemeAllowed:
|
||||
self.theme.background_direction = \
|
||||
BackgroundGradientType.to_string(index)
|
||||
self.setBackgroundPageValues()
|
||||
|
||||
def onColorButtonClicked(self):
|
||||
"""
|
||||
@ -479,8 +483,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
Background Image button pushed.
|
||||
"""
|
||||
images_filter = get_images_filter()
|
||||
images_filter = '%s;;%s (*.*) (*)' % (images_filter,
|
||||
translate('OpenLP.ThemeForm', 'All Files'))
|
||||
images_filter = u'%s;;%s (*.*) (*)' % (
|
||||
images_filter, UiStrings.AllFiles)
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self,
|
||||
translate('OpenLP.ThemeForm', 'Select Image'), u'',
|
||||
images_filter)
|
||||
@ -560,21 +564,16 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
"""
|
||||
Lets save the them as Finish has been pressed
|
||||
"""
|
||||
# Some reason getting double submission.
|
||||
# Hack to stop it for now.
|
||||
if self.accepted:
|
||||
return
|
||||
# Save the theme name
|
||||
self.theme.theme_name = \
|
||||
unicode(self.field(u'name').toString())
|
||||
self.theme.theme_name = unicode(self.field(u'name').toString())
|
||||
if not self.theme.theme_name:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeForm', 'Theme Name Missing'),
|
||||
translate('OpenLP.ThemeForm',
|
||||
'There is no name for this theme. Please enter one.'))
|
||||
return
|
||||
if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None':
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeForm', 'Theme Name Invalid'),
|
||||
translate('OpenLP.ThemeForm',
|
||||
'Invalid theme name. Please enter one.'))
|
||||
@ -590,7 +589,6 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
if not self.edit_mode and \
|
||||
not self.thememanager.checkIfThemeExists(self.theme.theme_name):
|
||||
return
|
||||
self.accepted = True
|
||||
self.thememanager.saveTheme(self.theme, saveFrom, saveTo)
|
||||
return QtGui.QDialog.accept(self)
|
||||
|
||||
|
@ -32,11 +32,13 @@ import logging
|
||||
from xml.etree.ElementTree import ElementTree, XML
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.ui import criticalErrorMessageBox, FileRenameForm, ThemeForm
|
||||
from openlp.core.theme import Theme
|
||||
from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \
|
||||
build_icon, Receiver, SettingsManager, translate, check_item_selected, \
|
||||
BackgroundType, BackgroundGradientType, check_directory_exists
|
||||
BackgroundType, BackgroundGradientType, check_directory_exists, \
|
||||
VerticalType
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.core.theme import Theme
|
||||
from openlp.core.ui import FileRenameForm, ThemeForm
|
||||
from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \
|
||||
get_filesystem_encoding
|
||||
|
||||
@ -240,7 +242,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
QtCore.QVariant(self.global_theme))
|
||||
Receiver.send_message(u'theme_update_global',
|
||||
self.global_theme)
|
||||
self.pushThemes()
|
||||
self._pushThemes()
|
||||
|
||||
def onAddTheme(self):
|
||||
"""
|
||||
@ -259,7 +261,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
'You must select a theme to rename.')),
|
||||
unicode(translate('OpenLP.ThemeManager', 'Rename Confirmation')),
|
||||
unicode(translate('OpenLP.ThemeManager', 'Rename %s theme?')),
|
||||
False):
|
||||
False, False):
|
||||
item = self.themeListWidget.currentItem()
|
||||
oldThemeName = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
self.fileRenameForm.fileNameEdit.setText(oldThemeName)
|
||||
@ -267,11 +269,12 @@ class ThemeManager(QtGui.QWidget):
|
||||
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
|
||||
if self.checkIfThemeExists(newThemeName):
|
||||
oldThemeData = self.getThemeData(oldThemeName)
|
||||
self.deleteTheme(oldThemeName)
|
||||
self.cloneThemeData(oldThemeData, newThemeName)
|
||||
self.deleteTheme(oldThemeName)
|
||||
for plugin in self.mainwindow.pluginManager.plugins:
|
||||
if plugin.usesTheme(oldThemeName):
|
||||
plugin.renameTheme(oldThemeName, newThemeName)
|
||||
self.loadThemes()
|
||||
|
||||
def onCopyTheme(self):
|
||||
"""
|
||||
@ -299,6 +302,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
os.path.split(unicode(themeData.background_filename))[1])
|
||||
saveFrom = themeData.background_filename
|
||||
themeData.theme_name = newThemeName
|
||||
themeData.extend_image_filename(self.path)
|
||||
self.saveTheme(themeData, saveFrom, saveTo)
|
||||
|
||||
def onEditTheme(self):
|
||||
@ -310,7 +314,6 @@ class ThemeManager(QtGui.QWidget):
|
||||
translate('OpenLP.ThemeManager',
|
||||
'You must select a theme to edit.')):
|
||||
item = self.themeListWidget.currentItem()
|
||||
themeName = unicode(item.text())
|
||||
theme = self.getThemeData(
|
||||
unicode(item.data(QtCore.Qt.UserRole).toString()))
|
||||
if theme.background_type == u'image':
|
||||
@ -331,6 +334,9 @@ class ThemeManager(QtGui.QWidget):
|
||||
row = self.themeListWidget.row(item)
|
||||
self.themeListWidget.takeItem(row)
|
||||
self.deleteTheme(theme)
|
||||
# As we do not reload the themes, push out the change. Reload the
|
||||
# list as the internal lists and events need to be triggered.
|
||||
self._pushThemes()
|
||||
|
||||
def deleteTheme(self, theme):
|
||||
"""
|
||||
@ -348,10 +354,6 @@ class ThemeManager(QtGui.QWidget):
|
||||
shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
|
||||
except OSError:
|
||||
log.exception(u'Error deleting theme %s', theme)
|
||||
# As we do not reload the themes push out the change
|
||||
# Reaload the list as the internal lists and events need
|
||||
# to be triggered
|
||||
self.pushThemes()
|
||||
|
||||
def onExportTheme(self):
|
||||
"""
|
||||
@ -359,7 +361,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
"""
|
||||
item = self.themeListWidget.currentItem()
|
||||
if item is None:
|
||||
criticalErrorMessageBox(message=translate('OpenLP.ThemeManager',
|
||||
critical_error_message_box(message=translate('OpenLP.ThemeManager',
|
||||
'You have not selected a theme.'))
|
||||
return
|
||||
theme = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
@ -386,7 +388,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
'Your theme has been successfully exported.'))
|
||||
except (IOError, OSError):
|
||||
log.exception(u'Export Theme Failed')
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Theme Export Failed'),
|
||||
translate('OpenLP.ThemeManager',
|
||||
'Your theme could not be exported due to an error.'))
|
||||
@ -403,8 +405,8 @@ class ThemeManager(QtGui.QWidget):
|
||||
files = QtGui.QFileDialog.getOpenFileNames(self,
|
||||
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
|
||||
SettingsManager.get_last_dir(self.settingsSection),
|
||||
translate('OpenLP.ThemeManager', 'Theme v1 (*.theme);;'
|
||||
'Theme v2 (*.otz);;All Files (*.*)'))
|
||||
unicode(translate('OpenLP.ThemeManager',
|
||||
'OpenLP Themes (*.theme *.otz)')))
|
||||
log.info(u'New Themes %s', unicode(files))
|
||||
if files:
|
||||
for file in files:
|
||||
@ -448,9 +450,9 @@ class ThemeManager(QtGui.QWidget):
|
||||
QtCore.QVariant(textName))
|
||||
self.themeListWidget.addItem(item_name)
|
||||
self.themelist.append(textName)
|
||||
self.pushThemes()
|
||||
self._pushThemes()
|
||||
|
||||
def pushThemes(self):
|
||||
def _pushThemes(self):
|
||||
"""
|
||||
Notify listeners that the theme list has been updated
|
||||
"""
|
||||
@ -496,7 +498,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
for file in zip.namelist():
|
||||
ucsfile = file_is_unicode(file)
|
||||
if not ucsfile:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
message=translate('OpenLP.ThemeManager',
|
||||
'File is not a valid theme.\n'
|
||||
'The content encoding is not UTF-8.'))
|
||||
@ -531,14 +533,14 @@ class ThemeManager(QtGui.QWidget):
|
||||
theme = self._createThemeFromXml(filexml, self.path)
|
||||
self.generateAndSaveImage(dir, themename, theme)
|
||||
else:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
translate('OpenLP.ThemeManager',
|
||||
'File is not a valid theme.'))
|
||||
log.exception(u'Theme file does not contain XML data %s' %
|
||||
filename)
|
||||
except (IOError, NameError):
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
translate('OpenLP.ThemeManager',
|
||||
'File is not a valid theme.'))
|
||||
@ -558,7 +560,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
"""
|
||||
theme_dir = os.path.join(self.path, themeName)
|
||||
if os.path.exists(theme_dir):
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||
translate('OpenLP.ThemeManager',
|
||||
'A theme with this name already exists.'))
|
||||
@ -570,6 +572,14 @@ class ThemeManager(QtGui.QWidget):
|
||||
Called by thememaintenance Dialog to save the theme
|
||||
and to trigger the reload of the theme list
|
||||
"""
|
||||
self._writeTheme(theme, imageFrom, imageTo)
|
||||
self.loadThemes()
|
||||
|
||||
def _writeTheme(self, theme, imageFrom, imageTo):
|
||||
"""
|
||||
Writes the theme to the disk and handles the background image if
|
||||
necessary
|
||||
"""
|
||||
name = theme.theme_name
|
||||
theme_pretty_xml = theme.extract_formatted_xml()
|
||||
log.debug(u'saveTheme %s %s', name, theme_pretty_xml)
|
||||
@ -597,12 +607,9 @@ class ThemeManager(QtGui.QWidget):
|
||||
except IOError:
|
||||
log.exception(u'Failed to save theme image')
|
||||
self.generateAndSaveImage(self.path, name, theme)
|
||||
self.loadThemes()
|
||||
self.pushThemes()
|
||||
|
||||
def generateAndSaveImage(self, dir, name, theme):
|
||||
log.debug(u'generateAndSaveImage %s %s', dir, name)
|
||||
theme_xml = theme.extract_xml()
|
||||
frame = self.generateImage(theme)
|
||||
samplepathname = os.path.join(self.path, name + u'.png')
|
||||
if os.path.exists(samplepathname):
|
||||
@ -668,7 +675,7 @@ class ThemeManager(QtGui.QWidget):
|
||||
return theme
|
||||
|
||||
def _validate_theme_action(self, select_text, confirm_title, confirm_text,
|
||||
testPlugin=True):
|
||||
testPlugin=True, confirm=True):
|
||||
"""
|
||||
Check to see if theme has been selected and the destructive action
|
||||
is allowed.
|
||||
@ -680,15 +687,16 @@ class ThemeManager(QtGui.QWidget):
|
||||
item = self.themeListWidget.currentItem()
|
||||
theme = unicode(item.text())
|
||||
# confirm deletion
|
||||
answer = QtGui.QMessageBox.question(self, confirm_title,
|
||||
confirm_text % theme, QtGui.QMessageBox.StandardButtons(
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
|
||||
QtGui.QMessageBox.No)
|
||||
if answer == QtGui.QMessageBox.No:
|
||||
return False
|
||||
if confirm:
|
||||
answer = QtGui.QMessageBox.question(self, confirm_title,
|
||||
confirm_text % theme, QtGui.QMessageBox.StandardButtons(
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
|
||||
QtGui.QMessageBox.No)
|
||||
if answer == QtGui.QMessageBox.No:
|
||||
return False
|
||||
# should be the same unless default
|
||||
if theme != unicode(item.data(QtCore.Qt.UserRole).toString()):
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
message=translate('OpenLP.ThemeManager',
|
||||
'You are unable to delete the default theme.'))
|
||||
return False
|
||||
@ -696,7 +704,8 @@ class ThemeManager(QtGui.QWidget):
|
||||
if testPlugin:
|
||||
for plugin in self.mainwindow.pluginManager.plugins:
|
||||
if plugin.usesTheme(theme):
|
||||
criticalErrorMessageBox(translate('OpenLP.ThemeManager',
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.ThemeManager',
|
||||
'Validation Error'),
|
||||
unicode(translate('OpenLP.ThemeManager',
|
||||
'Theme %s is used in the %s plugin.')) % \
|
||||
@ -753,11 +762,11 @@ class ThemeManager(QtGui.QWidget):
|
||||
newtheme.font_main_outline = True
|
||||
newtheme.font_main_outline_color = \
|
||||
unicode(theme.OutlineColor.name())
|
||||
vAlignCorrection = 0
|
||||
vAlignCorrection = VerticalType.Top
|
||||
if theme.VerticalAlign == 2:
|
||||
vAlignCorrection = 1
|
||||
vAlignCorrection = VerticalType.Middle
|
||||
elif theme.VerticalAlign == 1:
|
||||
vAlignCorrection = 2
|
||||
vAlignCorrection = VerticalType.Bottom
|
||||
newtheme.display_horizontal_align = theme.HorizontalAlign
|
||||
newtheme.display_vertical_align = vAlignCorrection
|
||||
return newtheme.extract_xml()
|
||||
|
@ -27,6 +27,7 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import SettingsTab, Receiver, ThemeLevel, translate
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
||||
class ThemesTab(SettingsTab):
|
||||
"""
|
||||
@ -98,7 +99,7 @@ class ThemesTab(SettingsTab):
|
||||
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.tabTitleVisible = translate('OpenLP.ThemesTab', 'Themes')
|
||||
self.tabTitleVisible = UiStrings.Themes
|
||||
self.GlobalGroupBox.setTitle(
|
||||
translate('OpenLP.ThemesTab', 'Global Theme'))
|
||||
self.LevelGroupBox.setTitle(
|
||||
@ -165,13 +166,7 @@ class ThemesTab(SettingsTab):
|
||||
self.global_theme = unicode(self.DefaultComboBox.currentText())
|
||||
self.parent.renderManager.set_global_theme(
|
||||
self.global_theme, self.theme_level)
|
||||
image = self.parent.ThemeManagerContents.getPreviewImage(
|
||||
self.global_theme)
|
||||
preview = QtGui.QPixmap(unicode(image))
|
||||
if not preview.isNull():
|
||||
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
|
||||
QtCore.Qt.SmoothTransformation)
|
||||
self.DefaultListView.setPixmap(preview)
|
||||
self.__previewGlobalTheme()
|
||||
|
||||
def updateThemeList(self, theme_list):
|
||||
"""
|
||||
@ -198,10 +193,16 @@ class ThemesTab(SettingsTab):
|
||||
self.parent.renderManager.set_global_theme(
|
||||
self.global_theme, self.theme_level)
|
||||
if self.global_theme is not u'':
|
||||
image = self.parent.ThemeManagerContents.getPreviewImage(
|
||||
self.global_theme)
|
||||
preview = QtGui.QPixmap(unicode(image))
|
||||
if not preview.isNull():
|
||||
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
|
||||
QtCore.Qt.SmoothTransformation)
|
||||
self.DefaultListView.setPixmap(preview)
|
||||
self.__previewGlobalTheme()
|
||||
|
||||
def __previewGlobalTheme(self):
|
||||
"""
|
||||
Utility method to update the global theme preview image.
|
||||
"""
|
||||
image = self.parent.ThemeManagerContents.getPreviewImage(
|
||||
self.global_theme)
|
||||
preview = QtGui.QPixmap(unicode(image))
|
||||
if not preview.isNull():
|
||||
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio,
|
||||
QtCore.Qt.SmoothTransformation)
|
||||
self.DefaultListView.setPixmap(preview)
|
||||
|
@ -27,32 +27,19 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, build_icon
|
||||
from openlp.core.lib.ui import add_welcome_page, create_valign_combo
|
||||
|
||||
class Ui_ThemeWizard(object):
|
||||
def setupUi(self, ThemeWizard):
|
||||
ThemeWizard.setObjectName(u'OpenLP.ThemeWizard')
|
||||
ThemeWizard.setModal(True)
|
||||
ThemeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
|
||||
ThemeWizard.setOptions(
|
||||
QtGui.QWizard.IndependentPages |
|
||||
def setupUi(self, themeWizard):
|
||||
themeWizard.setObjectName(u'OpenLP.ThemeWizard')
|
||||
themeWizard.setModal(True)
|
||||
themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
|
||||
themeWizard.setOptions(QtGui.QWizard.IndependentPages |
|
||||
QtGui.QWizard.NoBackButtonOnStartPage)
|
||||
self.spacer = QtGui.QSpacerItem(10, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
|
||||
# Welcome Page
|
||||
self.welcomePage = QtGui.QWizardPage()
|
||||
self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
|
||||
QtGui.QPixmap(u':/wizards/wizard_createtheme.bmp'))
|
||||
self.welcomePage.setObjectName(u'WelcomePage')
|
||||
self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
|
||||
self.welcomeLayout.setObjectName(u'WelcomeLayout')
|
||||
self.titleLabel = QtGui.QLabel(self.welcomePage)
|
||||
self.titleLabel.setObjectName(u'TitleLabel')
|
||||
self.welcomeLayout.addWidget(self.titleLabel)
|
||||
self.welcomeLayout.addSpacing(40)
|
||||
self.informationLabel = QtGui.QLabel(self.welcomePage)
|
||||
self.informationLabel.setWordWrap(True)
|
||||
self.informationLabel.setObjectName(u'InformationLabel')
|
||||
self.welcomeLayout.addWidget(self.informationLabel)
|
||||
self.welcomeLayout.addStretch()
|
||||
ThemeWizard.addPage(self.welcomePage)
|
||||
add_welcome_page(themeWizard, u':/wizards/wizard_createtheme.bmp')
|
||||
# Background Page
|
||||
self.backgroundPage = QtGui.QWizardPage()
|
||||
self.backgroundPage.setObjectName(u'BackgroundPage')
|
||||
@ -67,10 +54,8 @@ class Ui_ThemeWizard(object):
|
||||
self.backgroundComboBox.setObjectName(u'BackgroundComboBox')
|
||||
self.backgroundTypeLayout.addRow(self.backgroundLabel,
|
||||
self.backgroundComboBox)
|
||||
self.backgroundTypeSpacer = QtGui.QSpacerItem(10, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Minimum)
|
||||
self.backgroundTypeLayout.setItem(1, QtGui.QFormLayout.LabelRole,
|
||||
self.backgroundTypeSpacer)
|
||||
self.spacer)
|
||||
self.backgroundLayout.addLayout(self.backgroundTypeLayout)
|
||||
self.backgroundStack = QtGui.QStackedLayout()
|
||||
self.backgroundStack.setObjectName(u'BackgroundStack')
|
||||
@ -84,10 +69,7 @@ class Ui_ThemeWizard(object):
|
||||
self.colorButton = QtGui.QPushButton(self.colorWidget)
|
||||
self.colorButton.setObjectName(u'ColorButton')
|
||||
self.colorLayout.addRow(self.colorLabel, self.colorButton)
|
||||
self.colorSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
QtGui.QSizePolicy.Minimum)
|
||||
self.colorLayout.setItem(1, QtGui.QFormLayout.LabelRole,
|
||||
self.colorSpacer)
|
||||
self.colorLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||
self.backgroundStack.addWidget(self.colorWidget)
|
||||
self.gradientWidget = QtGui.QWidget(self.backgroundPage)
|
||||
self.gradientWidget.setObjectName(u'GradientWidget')
|
||||
@ -113,10 +95,7 @@ class Ui_ThemeWizard(object):
|
||||
self.gradientComboBox.addItems([u'', u'', u'', u'', u''])
|
||||
self.gradientLayout.addRow(self.gradientTypeLabel,
|
||||
self.gradientComboBox)
|
||||
self.gradientSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
QtGui.QSizePolicy.Minimum)
|
||||
self.gradientLayout.setItem(3, QtGui.QFormLayout.LabelRole,
|
||||
self.gradientSpacer)
|
||||
self.gradientLayout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||
self.backgroundStack.addWidget(self.gradientWidget)
|
||||
self.imageWidget = QtGui.QWidget(self.backgroundPage)
|
||||
self.imageWidget.setObjectName(u'ImageWidget')
|
||||
@ -136,13 +115,10 @@ class Ui_ThemeWizard(object):
|
||||
build_icon(u':/general/general_open.png'))
|
||||
self.imageFileLayout.addWidget(self.imageBrowseButton)
|
||||
self.imageLayout.addRow(self.imageLabel, self.imageFileLayout)
|
||||
self.imageSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
QtGui.QSizePolicy.Minimum)
|
||||
self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole,
|
||||
self.imageSpacer)
|
||||
self.imageLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||
self.backgroundStack.addWidget(self.imageWidget)
|
||||
self.backgroundLayout.addLayout(self.backgroundStack)
|
||||
ThemeWizard.addPage(self.backgroundPage)
|
||||
themeWizard.addPage(self.backgroundPage)
|
||||
# Main Area Page
|
||||
self.mainAreaPage = QtGui.QWizardPage()
|
||||
self.mainAreaPage.setObjectName(u'MainAreaPage')
|
||||
@ -225,7 +201,7 @@ class Ui_ThemeWizard(object):
|
||||
self.shadowSizeSpinBox.setObjectName(u'ShadowSizeSpinBox')
|
||||
self.shadowLayout.addWidget(self.shadowSizeSpinBox)
|
||||
self.mainAreaLayout.addRow(self.shadowCheckBox, self.shadowLayout)
|
||||
ThemeWizard.addPage(self.mainAreaPage)
|
||||
themeWizard.addPage(self.mainAreaPage)
|
||||
# Footer Area Page
|
||||
self.footerAreaPage = QtGui.QWizardPage()
|
||||
self.footerAreaPage.setObjectName(u'FooterAreaPage')
|
||||
@ -251,7 +227,9 @@ class Ui_ThemeWizard(object):
|
||||
self.footerSizeSpinBox.setObjectName(u'FooterSizeSpinBox')
|
||||
self.footerAreaLayout.addRow(self.footerSizeLabel,
|
||||
self.footerSizeSpinBox)
|
||||
ThemeWizard.addPage(self.footerAreaPage)
|
||||
self.footerAreaLayout.setItem(3, QtGui.QFormLayout.LabelRole,
|
||||
self.spacer)
|
||||
themeWizard.addPage(self.footerAreaPage)
|
||||
# Alignment Page
|
||||
self.alignmentPage = QtGui.QWizardPage()
|
||||
self.alignmentPage.setObjectName(u'AlignmentPage')
|
||||
@ -264,19 +242,17 @@ class Ui_ThemeWizard(object):
|
||||
self.horizontalComboBox.setObjectName(u'HorizontalComboBox')
|
||||
self.alignmentLayout.addRow(self.horizontalLabel,
|
||||
self.horizontalComboBox)
|
||||
self.verticalLabel = QtGui.QLabel(self.alignmentPage)
|
||||
self.verticalLabel.setObjectName(u'VerticalLabel')
|
||||
self.verticalComboBox = QtGui.QComboBox(self.alignmentPage)
|
||||
self.verticalComboBox.addItems([u'', u'', u''])
|
||||
self.verticalComboBox.setObjectName(u'VerticalComboBox')
|
||||
self.alignmentLayout.addRow(self.verticalLabel, self.verticalComboBox)
|
||||
create_valign_combo(themeWizard, self.alignmentPage,
|
||||
self.alignmentLayout)
|
||||
self.transitionsLabel = QtGui.QLabel(self.alignmentPage)
|
||||
self.transitionsLabel.setObjectName(u'TransitionsLabel')
|
||||
self.transitionsCheckBox = QtGui.QCheckBox(self.alignmentPage)
|
||||
self.transitionsCheckBox.setObjectName(u'TransitionsCheckBox')
|
||||
self.alignmentLayout.addRow(self.transitionsLabel,
|
||||
self.transitionsCheckBox)
|
||||
ThemeWizard.addPage(self.alignmentPage)
|
||||
self.alignmentLayout.setItem(3, QtGui.QFormLayout.LabelRole,
|
||||
self.spacer)
|
||||
themeWizard.addPage(self.alignmentPage)
|
||||
# Area Position Page
|
||||
self.areaPositionPage = QtGui.QWizardPage()
|
||||
self.areaPositionPage.setObjectName(u'AreaPositionPage')
|
||||
@ -352,7 +328,7 @@ class Ui_ThemeWizard(object):
|
||||
self.footerPositionLayout.addRow(self.footerHeightLabel,
|
||||
self.footerHeightSpinBox)
|
||||
self.areaPositionLayout.addWidget(self.footerPositionGroupBox)
|
||||
ThemeWizard.addPage(self.areaPositionPage)
|
||||
themeWizard.addPage(self.areaPositionPage)
|
||||
# Preview Page
|
||||
self.previewPage = QtGui.QWizardPage()
|
||||
self.previewPage.setObjectName(u'PreviewPage')
|
||||
@ -381,9 +357,8 @@ class Ui_ThemeWizard(object):
|
||||
self.previewBoxLabel.setObjectName(u'PreviewBoxLabel')
|
||||
self.previewAreaLayout.addWidget(self.previewBoxLabel)
|
||||
self.previewLayout.addWidget(self.previewArea)
|
||||
ThemeWizard.addPage(self.previewPage)
|
||||
|
||||
self.retranslateUi(ThemeWizard)
|
||||
themeWizard.addPage(self.previewPage)
|
||||
self.retranslateUi(themeWizard)
|
||||
QtCore.QObject.connect(self.backgroundComboBox,
|
||||
QtCore.SIGNAL(u'currentIndexChanged(int)'), self.backgroundStack,
|
||||
QtCore.SLOT(u'setCurrentIndex(int)'))
|
||||
@ -423,10 +398,10 @@ class Ui_ThemeWizard(object):
|
||||
QtCore.QObject.connect(self.footerPositionCheckBox,
|
||||
QtCore.SIGNAL(u'toggled(bool)'), self.footerHeightSpinBox,
|
||||
QtCore.SLOT(u'setDisabled(bool)'))
|
||||
QtCore.QMetaObject.connectSlotsByName(ThemeWizard)
|
||||
QtCore.QMetaObject.connectSlotsByName(themeWizard)
|
||||
|
||||
def retranslateUi(self, ThemeWizard):
|
||||
ThemeWizard.setWindowTitle(
|
||||
def retranslateUi(self, themeWizard):
|
||||
themeWizard.setWindowTitle(
|
||||
translate('OpenLP.ThemeWizard', 'Theme Wizard'))
|
||||
self.titleLabel.setText(
|
||||
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
|
||||
@ -471,8 +446,7 @@ class Ui_ThemeWizard(object):
|
||||
self.mainAreaPage.setSubTitle(
|
||||
translate('OpenLP.ThemeWizard', 'Define the font and display '
|
||||
'characteristics for the Display text'))
|
||||
self.mainFontLabel.setText(
|
||||
translate('OpenLP.ThemeWizard', 'Font:'))
|
||||
self.mainFontLabel.setText(translate('OpenLP.ThemeWizard', 'Font:'))
|
||||
self.mainColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
||||
self.mainSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
||||
self.mainSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
|
||||
@ -486,8 +460,7 @@ class Ui_ThemeWizard(object):
|
||||
self.shadowCheckBox.setText(translate('OpenLP.ThemeWizard', '&Shadow:'))
|
||||
self.shadowSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
||||
self.shadowSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt'))
|
||||
self.mainBoldCheckBox.setText(
|
||||
translate('OpenLP.ThemeWizard', 'Bold'))
|
||||
self.mainBoldCheckBox.setText(translate('OpenLP.ThemeWizard', 'Bold'))
|
||||
self.mainItalicsCheckBox.setText(
|
||||
translate('OpenLP.ThemeWizard', 'Italic'))
|
||||
self.footerAreaPage.setTitle(
|
||||
@ -512,14 +485,6 @@ class Ui_ThemeWizard(object):
|
||||
translate('OpenLP.ThemeWizard', 'Right'))
|
||||
self.horizontalComboBox.setItemText(2,
|
||||
translate('OpenLP.ThemeWizard', 'Center'))
|
||||
self.verticalLabel.setText(
|
||||
translate('OpenLP.ThemeWizard', 'Vertical Align:'))
|
||||
self.verticalComboBox.setItemText(0,
|
||||
translate('OpenLP.ThemeWizard', 'Top'))
|
||||
self.verticalComboBox.setItemText(1,
|
||||
translate('OpenLP.ThemeWizard', 'Middle'))
|
||||
self.verticalComboBox.setItemText(2,
|
||||
translate('OpenLP.ThemeWizard', 'Bottom'))
|
||||
self.transitionsLabel.setText(
|
||||
translate('OpenLP.ThemeWizard', 'Transitions:'))
|
||||
self.areaPositionPage.setTitle(
|
||||
@ -568,16 +533,6 @@ class Ui_ThemeWizard(object):
|
||||
translate('OpenLP.ThemeWizard', 'Theme name:'))
|
||||
# Align all QFormLayouts towards each other.
|
||||
labelWidth = max(self.backgroundLabel.minimumSizeHint().width(),
|
||||
self.colorLabel.minimumSizeHint().width(),
|
||||
self.gradientStartLabel.minimumSizeHint().width(),
|
||||
self.gradientEndLabel.minimumSizeHint().width(),
|
||||
self.gradientTypeLabel.minimumSizeHint().width(),
|
||||
self.imageLabel.minimumSizeHint().width())
|
||||
self.backgroundTypeSpacer.changeSize(labelWidth, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.colorSpacer.changeSize(labelWidth, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.gradientSpacer.changeSize(labelWidth, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.imageSpacer.changeSize(labelWidth, 0,
|
||||
self.horizontalLabel.minimumSizeHint().width())
|
||||
self.spacer.changeSize(labelWidth, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
|
@ -27,10 +27,12 @@
|
||||
The :mod:``wizard`` module provides generic wizard tools for OpenLP.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, Receiver
|
||||
from openlp.core.lib import build_icon, Receiver, SettingsManager
|
||||
from openlp.core.lib.ui import UiStrings, add_welcome_page
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -63,35 +65,17 @@ class OpenLPWizard(QtGui.QWizard):
|
||||
self.setOptions(QtGui.QWizard.IndependentPages |
|
||||
QtGui.QWizard.NoBackButtonOnStartPage |
|
||||
QtGui.QWizard.NoBackButtonOnLastPage)
|
||||
self.addWelcomePage(image)
|
||||
add_welcome_page(self, image)
|
||||
self.addCustomPages()
|
||||
self.addProgressPage()
|
||||
self.retranslateUi()
|
||||
QtCore.QMetaObject.connectSlotsByName(self)
|
||||
|
||||
def addWelcomePage(self, image):
|
||||
def registerFields(self):
|
||||
"""
|
||||
Add the opening welcome page to the wizard.
|
||||
|
||||
``image``
|
||||
A splash image for the wizard
|
||||
Hook method for wizards to register any fields they need.
|
||||
"""
|
||||
self.welcomePage = QtGui.QWizardPage()
|
||||
self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap,
|
||||
QtGui.QPixmap(image))
|
||||
self.welcomePage.setObjectName(u'WelcomePage')
|
||||
self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage)
|
||||
self.welcomeLayout.setObjectName(u'WelcomeLayout')
|
||||
self.titleLabel = QtGui.QLabel(self.welcomePage)
|
||||
self.titleLabel.setObjectName(u'TitleLabel')
|
||||
self.welcomeLayout.addWidget(self.titleLabel)
|
||||
self.welcomeLayout.addSpacing(40)
|
||||
self.informationLabel = QtGui.QLabel(self.welcomePage)
|
||||
self.informationLabel.setWordWrap(True)
|
||||
self.informationLabel.setObjectName(u'InformationLabel')
|
||||
self.welcomeLayout.addWidget(self.informationLabel)
|
||||
self.welcomeLayout.addStretch()
|
||||
self.addPage(self.welcomePage)
|
||||
pass
|
||||
|
||||
def addProgressPage(self):
|
||||
"""
|
||||
@ -169,3 +153,30 @@ class OpenLPWizard(QtGui.QWizard):
|
||||
self.finishButton.setVisible(True)
|
||||
self.cancelButton.setVisible(False)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
||||
def getFileName(self, title, editbox, filters=u''):
|
||||
"""
|
||||
Opens a QFileDialog and saves the filename to the given editbox.
|
||||
|
||||
``title``
|
||||
The title of the dialog (unicode).
|
||||
|
||||
``editbox``
|
||||
A editbox (QLineEdit).
|
||||
|
||||
``filters``
|
||||
The file extension filters. It should contain the file description
|
||||
as well as the file extension. For example::
|
||||
|
||||
u'OpenLP 2.0 Databases (*.sqlite)'
|
||||
"""
|
||||
if filters:
|
||||
filters += u';;'
|
||||
filters += u'%s (*)' % UiStrings.AllFiles
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self, title,
|
||||
os.path.dirname(SettingsManager.get_last_dir(
|
||||
self.plugin.settingsSection, 1)), filters)
|
||||
if filename:
|
||||
editbox.setText(filename)
|
||||
SettingsManager.set_last_dir(self.plugin.settingsSection,
|
||||
filename, 1)
|
||||
|
@ -24,7 +24,7 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`utils` module provides the utility libraries for OpenLP
|
||||
The :mod:`openlp.core.utils` module provides the utility libraries for OpenLP.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
@ -137,10 +137,7 @@ class AppLocation(object):
|
||||
os.path.split(openlp.__file__)[0])
|
||||
return os.path.join(app_path, u'i18n')
|
||||
else:
|
||||
return _get_os_dir_path(u'openlp',
|
||||
os.path.join(os.getenv(u'HOME'), u'Library',
|
||||
u'Application Support', u'openlp'),
|
||||
None, os.path.join(os.getenv(u'HOME'), u'.openlp'), dir_type)
|
||||
return _get_os_dir_path(dir_type)
|
||||
|
||||
@staticmethod
|
||||
def get_data_path():
|
||||
@ -163,27 +160,38 @@ class AppLocation(object):
|
||||
os.makedirs(path)
|
||||
return path
|
||||
|
||||
def _get_os_dir_path(win_option, darwin_option, base_dir_option,
|
||||
non_base_dir_option, dir_type=1):
|
||||
def _get_os_dir_path(dir_type):
|
||||
"""
|
||||
Return a path based on which OS and environment we are running in.
|
||||
"""
|
||||
encoding = sys.getfilesystemencoding()
|
||||
if sys.platform == u'win32':
|
||||
return os.path.join(os.getenv(u'APPDATA'), win_option)
|
||||
if dir_type == AppLocation.DataDir:
|
||||
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding),
|
||||
u'openlp', u'data')
|
||||
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding),
|
||||
u'openlp')
|
||||
elif sys.platform == u'darwin':
|
||||
if dir_type == AppLocation.DataDir:
|
||||
return os.path.join(darwin_option, u'Data')
|
||||
return darwin_option
|
||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
|
||||
u'Library', u'Application Support', u'openlp', u'Data')
|
||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
|
||||
u'Library', u'Application Support', u'openlp')
|
||||
else:
|
||||
if XDG_BASE_AVAILABLE:
|
||||
if dir_type == AppLocation.ConfigDir:
|
||||
return os.path.join(BaseDirectory.xdg_config_home, u'openlp')
|
||||
return os.path.join(unicode(BaseDirectory.xdg_config_home,
|
||||
encoding), u'openlp')
|
||||
elif dir_type == AppLocation.DataDir:
|
||||
return os.path.join(BaseDirectory.xdg_data_home, u'openlp')
|
||||
return os.path.join(
|
||||
unicode(BaseDirectory.xdg_data_home, encoding), u'openlp')
|
||||
elif dir_type == AppLocation.CacheDir:
|
||||
return os.path.join(BaseDirectory.xdg_cache_home, u'openlp')
|
||||
else:
|
||||
return non_base_dir_option
|
||||
return os.path.join(unicode(BaseDirectory.xdg_cache_home,
|
||||
encoding), u'openlp')
|
||||
if dir_type == AppLocation.DataDir:
|
||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
|
||||
u'.openlp', u'data')
|
||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'.openlp')
|
||||
|
||||
def _get_frozen_path(frozen_option, non_frozen_option):
|
||||
"""
|
||||
@ -191,8 +199,7 @@ def _get_frozen_path(frozen_option, non_frozen_option):
|
||||
"""
|
||||
if hasattr(sys, u'frozen') and sys.frozen == 1:
|
||||
return frozen_option
|
||||
else:
|
||||
return non_frozen_option
|
||||
return non_frozen_option
|
||||
|
||||
def check_latest_version(current_version):
|
||||
"""
|
||||
@ -375,13 +382,13 @@ def get_uno_command():
|
||||
"""
|
||||
Returns the UNO command to launch an openoffice.org instance.
|
||||
"""
|
||||
COMMAND = u'soffice'
|
||||
OPTIONS = u'-nologo -norestore -minimized -invisible -nofirststartwizard'
|
||||
if UNO_CONNECTION_TYPE == u'pipe':
|
||||
return u'openoffice.org -nologo -norestore -minimized -invisible ' \
|
||||
+ u'-nofirststartwizard -accept=pipe,name=openlp_pipe;urp;'
|
||||
CONNECTION = u'"-accept=pipe,name=openlp_pipe;urp;"'
|
||||
else:
|
||||
return u'openoffice.org -nologo -norestore -minimized ' \
|
||||
+ u'-invisible -nofirststartwizard ' \
|
||||
+ u'-accept=socket,host=localhost,port=2002;urp;'
|
||||
CONNECTION = u'"-accept=socket,host=localhost,port=2002;urp;"'
|
||||
return u'%s %s %s' % (COMMAND, OPTIONS, CONNECTION)
|
||||
|
||||
def get_uno_instance(resolver):
|
||||
"""
|
||||
|
@ -40,21 +40,13 @@ class AlertsPlugin(Plugin):
|
||||
log.info(u'Alerts Plugin loaded')
|
||||
|
||||
def __init__(self, plugin_helpers):
|
||||
Plugin.__init__(self, u'Alerts', u'1.9.4', plugin_helpers)
|
||||
Plugin.__init__(self, u'Alerts', u'1.9.4', plugin_helpers,
|
||||
settingsTabClass=AlertsTab)
|
||||
self.weight = -3
|
||||
self.icon = build_icon(u':/plugins/plugin_alerts.png')
|
||||
self.alertsmanager = AlertsManager(self)
|
||||
self.manager = Manager(u'alerts', init_schema)
|
||||
visible_name = self.getString(StringContent.VisibleName)
|
||||
self.alertForm = AlertForm(self, visible_name[u'title'])
|
||||
|
||||
def getSettingsTab(self):
|
||||
"""
|
||||
Return the settings tab for the Alerts plugin
|
||||
"""
|
||||
visible_name = self.getString(StringContent.VisibleName)
|
||||
self.alertsTab = AlertsTab(self, visible_name[u'title'])
|
||||
return self.alertsTab
|
||||
self.alertForm = AlertForm(self)
|
||||
|
||||
def addToolsMenuItem(self, tools_menu):
|
||||
"""
|
||||
@ -82,7 +74,7 @@ class AlertsPlugin(Plugin):
|
||||
log.info(u'Alerts Initialising')
|
||||
Plugin.initialise(self)
|
||||
self.toolsAlertItem.setVisible(True)
|
||||
self.liveController.alertTab = self.alertsTab
|
||||
self.liveController.alertTab = self.settings_tab
|
||||
|
||||
def finalise(self):
|
||||
"""
|
||||
|
@ -27,6 +27,7 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, translate
|
||||
from openlp.core.lib.ui import create_delete_push_button
|
||||
|
||||
class Ui_AlertDialog(object):
|
||||
def setupUi(self, alertDialog):
|
||||
@ -65,9 +66,8 @@ class Ui_AlertDialog(object):
|
||||
self.saveButton.setIcon(build_icon(u':/general/general_save.png'))
|
||||
self.saveButton.setObjectName(u'saveButton')
|
||||
self.manageButtonLayout.addWidget(self.saveButton)
|
||||
self.deleteButton = QtGui.QPushButton(alertDialog)
|
||||
self.deleteButton.setIcon(build_icon(u':/general/general_delete.png'))
|
||||
self.deleteButton.setObjectName(u'deleteButton')
|
||||
self.deleteButton = create_delete_push_button(alertDialog)
|
||||
self.deleteButton.setEnabled(False)
|
||||
self.manageButtonLayout.addWidget(self.deleteButton)
|
||||
self.manageButtonLayout.addStretch()
|
||||
self.alertDialogLayout.addLayout(self.manageButtonLayout, 1, 1)
|
||||
@ -75,11 +75,13 @@ class Ui_AlertDialog(object):
|
||||
self.buttonBox.addButton(QtGui.QDialogButtonBox.Close)
|
||||
displayIcon = build_icon(u':/general/general_live.png')
|
||||
self.displayButton = QtGui.QPushButton(alertDialog)
|
||||
self.displayButton.setEnabled(False)
|
||||
self.displayButton.setIcon(displayIcon)
|
||||
self.displayButton.setObjectName(u'displayButton')
|
||||
self.buttonBox.addButton(self.displayButton,
|
||||
QtGui.QDialogButtonBox.ActionRole)
|
||||
self.displayCloseButton = QtGui.QPushButton(alertDialog)
|
||||
self.displayCloseButton.setEnabled(False)
|
||||
self.displayCloseButton.setIcon(displayIcon)
|
||||
self.displayCloseButton.setObjectName(u'displayCloseButton')
|
||||
self.buttonBox.addButton(self.displayCloseButton,
|
||||
@ -101,8 +103,6 @@ class Ui_AlertDialog(object):
|
||||
translate('AlertsPlugin.AlertForm', '&New'))
|
||||
self.saveButton.setText(
|
||||
translate('AlertsPlugin.AlertForm', '&Save'))
|
||||
self.deleteButton.setText(
|
||||
translate('AlertsPlugin.AlertForm', '&Delete'))
|
||||
self.displayButton.setText(
|
||||
translate('AlertsPlugin.AlertForm', 'Displ&ay'))
|
||||
self.displayCloseButton.setText(
|
||||
|
@ -35,7 +35,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
"""
|
||||
Provide UI for the alert system
|
||||
"""
|
||||
def __init__(self, plugin, visible_title):
|
||||
def __init__(self, plugin):
|
||||
"""
|
||||
Initialise the alert form
|
||||
"""
|
||||
@ -44,22 +44,22 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
self.item_id = None
|
||||
QtGui.QDialog.__init__(self, plugin.formparent)
|
||||
self.setupUi(self)
|
||||
QtCore.QObject.connect(self.displayButton, QtCore.SIGNAL(u'clicked()'),
|
||||
self.onDisplayClicked)
|
||||
QtCore.QObject.connect(self.displayButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onDisplayClicked)
|
||||
QtCore.QObject.connect(self.displayCloseButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked)
|
||||
QtCore.QObject.connect(self.alertTextEdit,
|
||||
QtCore.SIGNAL(u'textChanged(const QString&)'), self.onTextChanged)
|
||||
QtCore.QObject.connect(self.newButton, QtCore.SIGNAL(u'clicked()'),
|
||||
self.onNewClick)
|
||||
QtCore.QObject.connect(self.deleteButton, QtCore.SIGNAL(u'clicked()'),
|
||||
self.onDeleteClick)
|
||||
QtCore.QObject.connect(self.saveButton, QtCore.SIGNAL(u'clicked()'),
|
||||
self.onSaveClick)
|
||||
QtCore.QObject.connect(self.newButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onNewClick)
|
||||
QtCore.QObject.connect(self.saveButton,
|
||||
QtCore.SIGNAL(u'clicked()'), self.onSaveClick)
|
||||
QtCore.QObject.connect(self.alertListWidget,
|
||||
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onDoubleClick)
|
||||
QtCore.QObject.connect(self.alertListWidget,
|
||||
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSingleClick)
|
||||
QtCore.QObject.connect(self.alertListWidget,
|
||||
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
|
||||
|
||||
def loadList(self):
|
||||
"""
|
||||
@ -72,18 +72,15 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
item_name = QtGui.QListWidgetItem(alert.text)
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
|
||||
self.alertListWidget.addItem(item_name)
|
||||
self.saveButton.setEnabled(False)
|
||||
self.deleteButton.setEnabled(False)
|
||||
|
||||
def onDisplayClicked(self):
|
||||
if self.triggerAlert(unicode(self.alertTextEdit.text())):
|
||||
self.loadList()
|
||||
self.triggerAlert(unicode(self.alertTextEdit.text()))
|
||||
|
||||
def onDisplayCloseClicked(self):
|
||||
if self.triggerAlert(unicode(self.alertTextEdit.text())):
|
||||
self.close()
|
||||
|
||||
def onDeleteClick(self):
|
||||
def onDeleteButtonClicked(self):
|
||||
"""
|
||||
Deletes the selected item.
|
||||
"""
|
||||
@ -95,8 +92,6 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
self.alertListWidget.takeItem(row)
|
||||
self.item_id = None
|
||||
self.alertTextEdit.setText(u'')
|
||||
self.saveButton.setEnabled(False)
|
||||
self.deleteButton.setEnabled(False)
|
||||
|
||||
def onNewClick(self):
|
||||
if len(self.alertTextEdit.text()) == 0:
|
||||
@ -135,30 +130,26 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
"""
|
||||
List item has been double clicked to display it
|
||||
"""
|
||||
items = self.alertListWidget.selectedIndexes()
|
||||
for item in items:
|
||||
bitem = self.alertListWidget.item(item.row())
|
||||
self.triggerAlert(unicode(bitem.text()))
|
||||
self.alertTextEdit.setText(unicode(bitem.text()))
|
||||
self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
item = self.alertListWidget.selectedIndexes()[0]
|
||||
bitem = self.alertListWidget.item(item.row())
|
||||
self.triggerAlert(unicode(bitem.text()))
|
||||
self.alertTextEdit.setText(unicode(bitem.text()))
|
||||
self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
self.saveButton.setEnabled(False)
|
||||
self.deleteButton.setEnabled(True)
|
||||
|
||||
def onSingleClick(self):
|
||||
"""
|
||||
List item has been single clicked to add it to
|
||||
the edit field so it can be changed.
|
||||
"""
|
||||
items = self.alertListWidget.selectedIndexes()
|
||||
for item in items:
|
||||
bitem = self.alertListWidget.item(item.row())
|
||||
self.alertTextEdit.setText(unicode(bitem.text()))
|
||||
self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
item = self.alertListWidget.selectedIndexes()[0]
|
||||
bitem = self.alertListWidget.item(item.row())
|
||||
self.alertTextEdit.setText(unicode(bitem.text()))
|
||||
self.item_id = (bitem.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
# If the alert does not contain '<>' we clear the ParameterEdit field.
|
||||
if unicode(self.alertTextEdit.text()).find(u'<>') == -1:
|
||||
self.parameterEdit.setText(u'')
|
||||
self.saveButton.setEnabled(False)
|
||||
self.deleteButton.setEnabled(True)
|
||||
|
||||
def triggerAlert(self, text):
|
||||
"""
|
||||
@ -167,30 +158,49 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
||||
``text``
|
||||
The alert text (unicode).
|
||||
"""
|
||||
if text:
|
||||
# We found '<>' in the alert text, but the ParameterEdit field is
|
||||
# empty.
|
||||
if text.find(u'<>') != -1 and not self.parameterEdit.text() and \
|
||||
QtGui.QMessageBox.question(self,
|
||||
translate('AlertPlugin.AlertForm', 'No Parameter found'),
|
||||
translate('AlertPlugin.AlertForm', 'You have not entered a '
|
||||
'parameter to be replaced.\nDo you want to continue anyway?'),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
||||
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No:
|
||||
self.parameterEdit.setFocus()
|
||||
return False
|
||||
# The ParameterEdit field is not empty, but we have not found '<>'
|
||||
# in the alert text.
|
||||
elif text.find(u'<>') == -1 and self.parameterEdit.text() and \
|
||||
QtGui.QMessageBox.question(self,
|
||||
translate('AlertPlugin.AlertForm', 'No Placeholder found'),
|
||||
translate('AlertPlugin.AlertForm', 'The alert text does not'
|
||||
' contain \'<>\'.\nDo want to continue anyway?'),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
||||
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No:
|
||||
self.parameterEdit.setFocus()
|
||||
return False
|
||||
text = text.replace(u'<>', unicode(self.parameterEdit.text()))
|
||||
self.parent.alertsmanager.displayAlert(text)
|
||||
return True
|
||||
return False
|
||||
if not text:
|
||||
return False
|
||||
# We found '<>' in the alert text, but the ParameterEdit field is empty.
|
||||
if text.find(u'<>') != -1 and not self.parameterEdit.text() and \
|
||||
QtGui.QMessageBox.question(self,
|
||||
translate('AlertPlugin.AlertForm', 'No Parameter found'),
|
||||
translate('AlertPlugin.AlertForm', 'You have not entered a '
|
||||
'parameter to be replaced.\nDo you want to continue anyway?'),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
||||
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No:
|
||||
self.parameterEdit.setFocus()
|
||||
return False
|
||||
# The ParameterEdit field is not empty, but we have not found '<>'
|
||||
# in the alert text.
|
||||
elif text.find(u'<>') == -1 and self.parameterEdit.text() and \
|
||||
QtGui.QMessageBox.question(self,
|
||||
translate('AlertPlugin.AlertForm', 'No Placeholder found'),
|
||||
translate('AlertPlugin.AlertForm', 'The alert text does not'
|
||||
' contain \'<>\'.\nDo want to continue anyway?'),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No |
|
||||
QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No:
|
||||
self.parameterEdit.setFocus()
|
||||
return False
|
||||
text = text.replace(u'<>', unicode(self.parameterEdit.text()))
|
||||
self.parent.alertsmanager.displayAlert(text)
|
||||
return True
|
||||
|
||||
def onCurrentRowChanged(self, row):
|
||||
"""
|
||||
Called when the *alertListWidget*'s current row has been changed. This
|
||||
enables or disables buttons which require an item to act on.
|
||||
|
||||
``row``
|
||||
The row (int). If there is no current row, the value is -1.
|
||||
"""
|
||||
if row == -1:
|
||||
self.displayButton.setEnabled(False)
|
||||
self.displayCloseButton.setEnabled(False)
|
||||
self.saveButton.setEnabled(False)
|
||||
self.deleteButton.setEnabled(False)
|
||||
else:
|
||||
self.displayButton.setEnabled(True)
|
||||
self.displayCloseButton.setEnabled(True)
|
||||
self.deleteButton.setEnabled(True)
|
||||
# We do not need to enable the save button, as it is only enabled
|
||||
# when typing text in the "alertTextEdit".
|
||||
|
@ -84,7 +84,7 @@ class AlertsManager(QtCore.QObject):
|
||||
if len(self.alertList) == 0:
|
||||
return
|
||||
text = self.alertList.pop(0)
|
||||
alertTab = self.parent.alertsTab
|
||||
alertTab = self.parent.settings_tab
|
||||
self.parent.liveController.display.alert(text)
|
||||
# Check to see if we have a timer running.
|
||||
if self.timer_id == 0:
|
||||
@ -103,4 +103,4 @@ class AlertsManager(QtCore.QObject):
|
||||
self.parent.liveController.display.alert(u'')
|
||||
self.killTimer(self.timer_id)
|
||||
self.timer_id = 0
|
||||
self.generateAlert()
|
||||
self.generateAlert()
|
||||
|
@ -27,61 +27,55 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import SettingsTab, translate
|
||||
from openlp.core.lib.ui import UiStrings, create_valign_combo
|
||||
|
||||
class AlertsTab(SettingsTab):
|
||||
"""
|
||||
AlertsTab is the alerts settings tab in the settings dialog.
|
||||
"""
|
||||
def __init__(self, parent, visible_title):
|
||||
self.parent = parent
|
||||
self.manager = parent.manager
|
||||
SettingsTab.__init__(self, parent.name, visible_title)
|
||||
def __init__(self, name, visible_title):
|
||||
SettingsTab.__init__(self, name, visible_title)
|
||||
|
||||
def setupUi(self):
|
||||
self.setObjectName(u'AlertsTab')
|
||||
SettingsTab.setupUi(self)
|
||||
self.FontGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.FontGroupBox.setObjectName(u'FontGroupBox')
|
||||
self.FontLayout = QtGui.QFormLayout(self.FontGroupBox)
|
||||
self.FontLayout.setObjectName(u'FontLayout')
|
||||
self.FontLabel = QtGui.QLabel(self.FontGroupBox)
|
||||
self.fontGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.fontGroupBox.setObjectName(u'fontGroupBox')
|
||||
self.fontLayout = QtGui.QFormLayout(self.fontGroupBox)
|
||||
self.fontLayout.setObjectName(u'fontLayout')
|
||||
self.FontLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.FontLabel.setObjectName(u'FontLabel')
|
||||
self.FontComboBox = QtGui.QFontComboBox(self.FontGroupBox)
|
||||
self.FontComboBox = QtGui.QFontComboBox(self.fontGroupBox)
|
||||
self.FontComboBox.setObjectName(u'FontComboBox')
|
||||
self.FontLayout.addRow(self.FontLabel, self.FontComboBox)
|
||||
self.FontColorLabel = QtGui.QLabel(self.FontGroupBox)
|
||||
self.fontLayout.addRow(self.FontLabel, self.FontComboBox)
|
||||
self.FontColorLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.FontColorLabel.setObjectName(u'FontColorLabel')
|
||||
self.ColorLayout = QtGui.QHBoxLayout()
|
||||
self.ColorLayout.setObjectName(u'ColorLayout')
|
||||
self.FontColorButton = QtGui.QPushButton(self.FontGroupBox)
|
||||
self.FontColorButton = QtGui.QPushButton(self.fontGroupBox)
|
||||
self.FontColorButton.setObjectName(u'FontColorButton')
|
||||
self.ColorLayout.addWidget(self.FontColorButton)
|
||||
self.ColorLayout.addSpacing(20)
|
||||
self.BackgroundColorLabel = QtGui.QLabel(self.FontGroupBox)
|
||||
self.BackgroundColorLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.BackgroundColorLabel.setObjectName(u'BackgroundColorLabel')
|
||||
self.ColorLayout.addWidget(self.BackgroundColorLabel)
|
||||
self.BackgroundColorButton = QtGui.QPushButton(self.FontGroupBox)
|
||||
self.BackgroundColorButton = QtGui.QPushButton(self.fontGroupBox)
|
||||
self.BackgroundColorButton.setObjectName(u'BackgroundColorButton')
|
||||
self.ColorLayout.addWidget(self.BackgroundColorButton)
|
||||
self.FontLayout.addRow(self.FontColorLabel, self.ColorLayout)
|
||||
self.FontSizeLabel = QtGui.QLabel(self.FontGroupBox)
|
||||
self.fontLayout.addRow(self.FontColorLabel, self.ColorLayout)
|
||||
self.FontSizeLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.FontSizeLabel.setObjectName(u'FontSizeLabel')
|
||||
self.FontSizeSpinBox = QtGui.QSpinBox(self.FontGroupBox)
|
||||
self.FontSizeSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
||||
self.FontSizeSpinBox.setObjectName(u'FontSizeSpinBox')
|
||||
self.FontLayout.addRow(self.FontSizeLabel, self.FontSizeSpinBox)
|
||||
self.TimeoutLabel = QtGui.QLabel(self.FontGroupBox)
|
||||
self.fontLayout.addRow(self.FontSizeLabel, self.FontSizeSpinBox)
|
||||
self.TimeoutLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.TimeoutLabel.setObjectName(u'TimeoutLabel')
|
||||
self.TimeoutSpinBox = QtGui.QSpinBox(self.FontGroupBox)
|
||||
self.TimeoutSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
||||
self.TimeoutSpinBox.setMaximum(180)
|
||||
self.TimeoutSpinBox.setObjectName(u'TimeoutSpinBox')
|
||||
self.FontLayout.addRow(self.TimeoutLabel, self.TimeoutSpinBox)
|
||||
self.LocationLabel = QtGui.QLabel(self.FontGroupBox)
|
||||
self.LocationLabel.setObjectName(u'LocationLabel')
|
||||
self.LocationComboBox = QtGui.QComboBox(self.FontGroupBox)
|
||||
self.LocationComboBox.addItems([u'', u'', u''])
|
||||
self.LocationComboBox.setObjectName(u'LocationComboBox')
|
||||
self.FontLayout.addRow(self.LocationLabel, self.LocationComboBox)
|
||||
self.leftLayout.addWidget(self.FontGroupBox)
|
||||
self.fontLayout.addRow(self.TimeoutLabel, self.TimeoutSpinBox)
|
||||
create_valign_combo(self, self.fontGroupBox, self.fontLayout)
|
||||
self.leftLayout.addWidget(self.fontGroupBox)
|
||||
self.leftLayout.addStretch()
|
||||
self.PreviewGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||
self.PreviewGroupBox.setObjectName(u'PreviewGroupBox')
|
||||
@ -99,15 +93,13 @@ class AlertsTab(SettingsTab):
|
||||
QtCore.SIGNAL(u'pressed()'), self.onFontColorButtonClicked)
|
||||
QtCore.QObject.connect(self.FontComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onFontComboBoxClicked)
|
||||
QtCore.QObject.connect(self.LocationComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onLocationComboBoxClicked)
|
||||
QtCore.QObject.connect(self.TimeoutSpinBox,
|
||||
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
|
||||
QtCore.QObject.connect(self.FontSizeSpinBox,
|
||||
QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.FontGroupBox.setTitle(
|
||||
self.fontGroupBox.setTitle(
|
||||
translate('AlertsPlugin.AlertsTab', 'Font'))
|
||||
self.FontLabel.setText(
|
||||
translate('AlertsPlugin.AlertsTab', 'Font name:'))
|
||||
@ -123,18 +115,8 @@ class AlertsTab(SettingsTab):
|
||||
translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
|
||||
self.TimeoutSpinBox.setSuffix(
|
||||
translate('AlertsPlugin.AlertsTab', 's'))
|
||||
self.LocationLabel.setText(
|
||||
translate('AlertsPlugin.AlertsTab', 'Location:'))
|
||||
self.PreviewGroupBox.setTitle(
|
||||
translate('AlertsPlugin.AlertsTab', 'Preview'))
|
||||
self.FontPreview.setText(
|
||||
translate('AlertsPlugin.AlertsTab', 'OpenLP 2.0'))
|
||||
self.LocationComboBox.setItemText(0,
|
||||
translate('AlertsPlugin.AlertsTab', 'Top'))
|
||||
self.LocationComboBox.setItemText(1,
|
||||
translate('AlertsPlugin.AlertsTab', 'Middle'))
|
||||
self.LocationComboBox.setItemText(2,
|
||||
translate('AlertsPlugin.AlertsTab', 'Bottom'))
|
||||
self.PreviewGroupBox.setTitle(UiStrings.Preview)
|
||||
self.FontPreview.setText(UiStrings.OLPV2)
|
||||
|
||||
def onBackgroundColorButtonClicked(self):
|
||||
new_color = QtGui.QColorDialog.getColor(
|
||||
@ -148,9 +130,6 @@ class AlertsTab(SettingsTab):
|
||||
def onFontComboBoxClicked(self):
|
||||
self.updateDisplay()
|
||||
|
||||
def onLocationComboBoxClicked(self, location):
|
||||
self.location = location
|
||||
|
||||
def onFontColorButtonClicked(self):
|
||||
new_color = QtGui.QColorDialog.getColor(
|
||||
QtGui.QColor(self.font_color), self)
|
||||
@ -188,7 +167,7 @@ class AlertsTab(SettingsTab):
|
||||
u'background-color: %s' % self.font_color)
|
||||
self.BackgroundColorButton.setStyleSheet(
|
||||
u'background-color: %s' % self.bg_color)
|
||||
self.LocationComboBox.setCurrentIndex(self.location)
|
||||
self.verticalComboBox.setCurrentIndex(self.location)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(self.font_face)
|
||||
self.FontComboBox.setCurrentFont(font)
|
||||
@ -197,14 +176,14 @@ class AlertsTab(SettingsTab):
|
||||
def save(self):
|
||||
settings = QtCore.QSettings()
|
||||
settings.beginGroup(self.settingsSection)
|
||||
self.font_face = self.FontComboBox.currentFont().family()
|
||||
settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
|
||||
settings.setValue(u'font color', QtCore.QVariant(self.font_color))
|
||||
settings.setValue(u'font size', QtCore.QVariant(self.font_size))
|
||||
self.font_face = self.FontComboBox.currentFont().family()
|
||||
settings.setValue(u'font face', QtCore.QVariant(self.font_face))
|
||||
settings.setValue(u'timeout', QtCore.QVariant(self.timeout))
|
||||
settings.setValue(u'location',
|
||||
QtCore.QVariant(self.LocationComboBox.currentIndex()))
|
||||
self.location = self.verticalComboBox.currentIndex()
|
||||
settings.setValue(u'location', QtCore.QVariant(self.location))
|
||||
settings.endGroup()
|
||||
|
||||
def updateDisplay(self):
|
||||
|
@ -37,7 +37,8 @@ class BiblePlugin(Plugin):
|
||||
log.info(u'Bible Plugin loaded')
|
||||
|
||||
def __init__(self, plugin_helpers):
|
||||
Plugin.__init__(self, u'Bibles', u'1.9.4', plugin_helpers)
|
||||
Plugin.__init__(self, u'Bibles', u'1.9.4', plugin_helpers,
|
||||
BibleMediaItem, BiblesTab)
|
||||
self.weight = -9
|
||||
self.icon_path = u':/plugins/plugin_bibles.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
@ -61,14 +62,6 @@ class BiblePlugin(Plugin):
|
||||
self.importBibleItem.setVisible(False)
|
||||
self.exportBibleItem.setVisible(False)
|
||||
|
||||
def getSettingsTab(self):
|
||||
visible_name = self.getString(StringContent.VisibleName)
|
||||
return BiblesTab(self.name, visible_name[u'title'])
|
||||
|
||||
def getMediaManagerItem(self):
|
||||
# Create the BibleManagerItem object.
|
||||
return BibleMediaItem(self, self, self.icon)
|
||||
|
||||
def addImportMenuItem(self, import_menu):
|
||||
self.importBibleItem = QtGui.QAction(import_menu)
|
||||
self.importBibleItem.setObjectName(u'importBibleItem')
|
||||
@ -102,7 +95,7 @@ class BiblePlugin(Plugin):
|
||||
Called to find out if the bible plugin is currently using a theme.
|
||||
Returns True if the theme is being used, otherwise returns False.
|
||||
"""
|
||||
if self.settings_tab.bible_theme == theme:
|
||||
if unicode(self.settings_tab.bible_theme) == theme:
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -119,6 +112,7 @@ class BiblePlugin(Plugin):
|
||||
The new name the plugin should now use.
|
||||
"""
|
||||
self.settings_tab.bible_theme = newTheme
|
||||
self.settings_tab.save()
|
||||
|
||||
def setPluginTextStrings(self):
|
||||
"""
|
||||
@ -134,40 +128,15 @@ class BiblePlugin(Plugin):
|
||||
u'title': translate('BiblesPlugin', 'Bibles', 'container title')
|
||||
}
|
||||
# Middle Header Bar
|
||||
## Import Action ##
|
||||
self.textStrings[StringContent.Import] = {
|
||||
u'title': translate('BiblesPlugin', '&Import'),
|
||||
u'tooltip': translate('BiblesPlugin', 'Import a Bible')
|
||||
}
|
||||
## New Action ##
|
||||
self.textStrings[StringContent.New] = {
|
||||
u'title': translate('BiblesPlugin', '&Add'),
|
||||
u'tooltip': translate('BiblesPlugin', 'Add a new Bible')
|
||||
}
|
||||
## Edit Action ##
|
||||
self.textStrings[StringContent.Edit] = {
|
||||
u'title': translate('BiblesPlugin', '&Edit'),
|
||||
u'tooltip': translate('BiblesPlugin', 'Edit the selected Bible')
|
||||
}
|
||||
## Delete Action ##
|
||||
self.textStrings[StringContent.Delete] = {
|
||||
u'title': translate('BiblesPlugin', '&Delete'),
|
||||
u'tooltip': translate('BiblesPlugin', 'Delete the selected Bible')
|
||||
}
|
||||
## Preview Action ##
|
||||
self.textStrings[StringContent.Preview] = {
|
||||
u'title': translate('BiblesPlugin', 'Preview'),
|
||||
u'tooltip': translate('BiblesPlugin', 'Preview the selected Bible')
|
||||
}
|
||||
## Send Live Action ##
|
||||
self.textStrings[StringContent.Live] = {
|
||||
u'title': translate('BiblesPlugin', 'Live'),
|
||||
u'tooltip': translate('BiblesPlugin',
|
||||
'Send the selected Bible live')
|
||||
}
|
||||
## Add to Service Action ##
|
||||
self.textStrings[StringContent.Service] = {
|
||||
u'title': translate('BiblesPlugin', 'Service'),
|
||||
u'tooltip': translate('BiblesPlugin',
|
||||
tooltips = {
|
||||
u'load': u'',
|
||||
u'import': translate('BiblesPlugin', 'Import a Bible'),
|
||||
u'new': translate('BiblesPlugin', 'Add a new Bible'),
|
||||
u'edit': translate('BiblesPlugin', 'Edit the selected Bible'),
|
||||
u'delete': translate('BiblesPlugin', 'Delete the selected Bible'),
|
||||
u'preview': translate('BiblesPlugin', 'Preview the selected Bible'),
|
||||
u'live': translate('BiblesPlugin', 'Send the selected Bible live'),
|
||||
u'service': translate('BiblesPlugin',
|
||||
'Add the selected Bible to the service')
|
||||
}
|
||||
self.setPluginUiTextStrings(tooltips)
|
||||
|
@ -33,9 +33,9 @@ import os.path
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, SettingsManager, translate
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib.db import delete_database
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.wizard import OpenLPWizard
|
||||
from openlp.core.utils import AppLocation, string_is_unicode
|
||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||
@ -124,9 +124,12 @@ class BibleImportForm(OpenLPWizard):
|
||||
QtCore.QObject.connect(self.osisBrowseButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onOsisBrowseButtonClicked)
|
||||
QtCore.QObject.connect(self.csvTestamentsButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onCsvTestamentsBrowseButtonClicked)
|
||||
QtCore.QObject.connect(self.csvBooksButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onBooksBrowseButtonClicked)
|
||||
self.onCsvBooksBrowseButtonClicked)
|
||||
QtCore.QObject.connect(self.csvVersesButton,
|
||||
QtCore.SIGNAL(u'clicked()'),
|
||||
self.onCsvVersesBrowseButtonClicked)
|
||||
@ -154,10 +157,9 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.formatComboBox.addItems([u'', u'', u'', u'', u''])
|
||||
self.formatComboBox.setObjectName(u'FormatComboBox')
|
||||
self.formatLayout.addRow(self.formatLabel, self.formatComboBox)
|
||||
self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
self.spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
QtGui.QSizePolicy.Minimum)
|
||||
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole,
|
||||
self.formatSpacer)
|
||||
self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||
self.selectPageLayout.addLayout(self.formatLayout)
|
||||
self.selectStack = QtGui.QStackedLayout()
|
||||
self.selectStack.setObjectName(u'SelectStack')
|
||||
@ -178,15 +180,25 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.osisBrowseButton.setObjectName(u'OsisBrowseButton')
|
||||
self.osisFileLayout.addWidget(self.osisBrowseButton)
|
||||
self.osisLayout.addRow(self.osisFileLabel, self.osisFileLayout)
|
||||
self.osisSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
QtGui.QSizePolicy.Minimum)
|
||||
self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.osisSpacer)
|
||||
self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||
self.selectStack.addWidget(self.osisWidget)
|
||||
self.csvWidget = QtGui.QWidget(self.selectPage)
|
||||
self.csvWidget.setObjectName(u'CsvWidget')
|
||||
self.csvLayout = QtGui.QFormLayout(self.csvWidget)
|
||||
self.csvLayout.setMargin(0)
|
||||
self.csvLayout.setObjectName(u'CsvLayout')
|
||||
self.csvTestamentsLabel = QtGui.QLabel(self.csvWidget)
|
||||
self.csvTestamentsLabel.setObjectName(u'CsvTestamentsLabel')
|
||||
self.csvTestamentsLayout = QtGui.QHBoxLayout()
|
||||
self.csvTestamentsLayout.setObjectName(u'CsvTestamentsLayout')
|
||||
self.csvTestamentsEdit = QtGui.QLineEdit(self.csvWidget)
|
||||
self.csvTestamentsEdit.setObjectName(u'CsvTestamentsEdit')
|
||||
self.csvTestamentsLayout.addWidget(self.csvTestamentsEdit)
|
||||
self.csvTestamentsButton = QtGui.QToolButton(self.csvWidget)
|
||||
self.csvTestamentsButton.setIcon(self.openIcon)
|
||||
self.csvTestamentsButton.setObjectName(u'CsvTestamentsButton')
|
||||
self.csvTestamentsLayout.addWidget(self.csvTestamentsButton)
|
||||
self.csvLayout.addRow(self.csvTestamentsLabel, self.csvTestamentsLayout)
|
||||
self.csvBooksLabel = QtGui.QLabel(self.csvWidget)
|
||||
self.csvBooksLabel.setObjectName(u'CsvBooksLabel')
|
||||
self.csvBooksLayout = QtGui.QHBoxLayout()
|
||||
@ -211,9 +223,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.csvVersesButton.setObjectName(u'CsvVersesButton')
|
||||
self.csvVersesLayout.addWidget(self.csvVersesButton)
|
||||
self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout)
|
||||
self.csvSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
QtGui.QSizePolicy.Minimum)
|
||||
self.csvLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.csvSpacer)
|
||||
self.csvLayout.setItem(3, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||
self.selectStack.addWidget(self.csvWidget)
|
||||
self.openSongWidget = QtGui.QWidget(self.selectPage)
|
||||
self.openSongWidget.setObjectName(u'OpenSongWidget')
|
||||
@ -233,10 +243,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.openSongFileLayout.addWidget(self.openSongBrowseButton)
|
||||
self.openSongLayout.addRow(self.openSongFileLabel,
|
||||
self.openSongFileLayout)
|
||||
self.openSongSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
QtGui.QSizePolicy.Minimum)
|
||||
self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole,
|
||||
self.openSongSpacer)
|
||||
self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||
self.selectStack.addWidget(self.openSongWidget)
|
||||
self.webTabWidget = QtGui.QTabWidget(self.selectPage)
|
||||
self.webTabWidget.setObjectName(u'WebTabWidget')
|
||||
@ -315,10 +322,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.openlp1DisabledLabel.setWordWrap(True)
|
||||
self.openlp1DisabledLabel.setObjectName(u'Openlp1DisabledLabel')
|
||||
self.openlp1Layout.addRow(self.openlp1DisabledLabel)
|
||||
self.openlp1Spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
|
||||
QtGui.QSizePolicy.Minimum)
|
||||
self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole,
|
||||
self.openlp1Spacer)
|
||||
self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole, self.spacer)
|
||||
self.selectStack.addWidget(self.openlp1Widget)
|
||||
self.selectPageLayout.addLayout(self.selectStack)
|
||||
self.addPage(self.selectPage)
|
||||
@ -386,15 +390,17 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.formatComboBox.setItemText(4,
|
||||
translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x'))
|
||||
self.openlp1FileLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'File location:'))
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
||||
self.osisFileLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'File location:'))
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
||||
self.csvTestamentsLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Testaments file:'))
|
||||
self.csvBooksLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Books location:'))
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Books file:'))
|
||||
self.csvVersesLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Verse location:'))
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Verses file:'))
|
||||
self.openSongFileLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Bible filename:'))
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
||||
self.webSourceLabel.setText(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Location:'))
|
||||
self.webSourceComboBox.setItemText(0,
|
||||
@ -445,19 +451,12 @@ class BibleImportForm(OpenLPWizard):
|
||||
# Align all QFormLayouts towards each other.
|
||||
labelWidth = max(self.formatLabel.minimumSizeHint().width(),
|
||||
self.osisFileLabel.minimumSizeHint().width(),
|
||||
self.csvTestamentsLabel.minimumSizeHint().width(),
|
||||
self.csvBooksLabel.minimumSizeHint().width(),
|
||||
self.csvVersesLabel.minimumSizeHint().width(),
|
||||
self.openSongFileLabel.minimumSizeHint().width(),
|
||||
self.openlp1FileLabel.minimumSizeHint().width())
|
||||
self.formatSpacer.changeSize(labelWidth, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.osisSpacer.changeSize(labelWidth, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.csvSpacer.changeSize(labelWidth, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.openSongSpacer.changeSize(labelWidth, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
self.openlp1Spacer.changeSize(labelWidth, 0,
|
||||
self.spacer.changeSize(labelWidth, 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
|
||||
def validateCurrentPage(self):
|
||||
@ -469,7 +468,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
elif self.currentPage() == self.selectPage:
|
||||
if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS:
|
||||
if not self.field(u'osis_location').toString():
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'Invalid Bible Location'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
@ -478,8 +477,17 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.osisFileEdit.setFocus()
|
||||
return False
|
||||
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
|
||||
if not self.field(u'csv_booksfile').toString():
|
||||
criticalErrorMessageBox(
|
||||
if not self.field(u'csv_testamentsfile').toString():
|
||||
answer = critical_error_message_box(translate(
|
||||
'BiblesPlugin.ImportWizardForm', 'No Testaments File'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'You have not specified a testaments file. Do you '
|
||||
'want to proceed with the import?'), question=True)
|
||||
if answer == QtGui.QMessageBox.No:
|
||||
self.csvTestamentsEdit.setFocus()
|
||||
return False
|
||||
elif not self.field(u'csv_booksfile').toString():
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'Invalid Books File'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
@ -488,7 +496,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.csvBooksEdit.setFocus()
|
||||
return False
|
||||
elif not self.field(u'csv_versefile').toString():
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'Invalid Verse File'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
@ -499,7 +507,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
elif self.field(u'source_format').toInt()[0] == \
|
||||
BibleFormat.OpenSong:
|
||||
if not self.field(u'opensong_file').toString():
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'Invalid OpenSong Bible'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
@ -509,7 +517,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
return False
|
||||
elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1:
|
||||
if not self.field(u'openlp1_location').toString():
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'Invalid Bible Location'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
@ -523,7 +531,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
license_copyright = \
|
||||
unicode(self.field(u'license_copyright').toString())
|
||||
if not license_version:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'Empty Version Name'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
@ -531,7 +539,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.versionNameEdit.setFocus()
|
||||
return False
|
||||
elif not license_copyright:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'Empty Copyright'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
@ -540,7 +548,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.copyrightEdit.setFocus()
|
||||
return False
|
||||
elif self.manager.exists(license_version):
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'),
|
||||
translate('BiblesPlugin.ImportWizardForm',
|
||||
'This Bible already exists. Please import '
|
||||
@ -572,7 +580,15 @@ class BibleImportForm(OpenLPWizard):
|
||||
translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'),
|
||||
self.osisFileEdit)
|
||||
|
||||
def onBooksBrowseButtonClicked(self):
|
||||
def onCsvTestamentsBrowseButtonClicked(self):
|
||||
"""
|
||||
Show the file open dialog for the testaments CSV file.
|
||||
"""
|
||||
self.getFileName(translate('BiblesPlugin.ImportWizardForm',
|
||||
'Open Testaments CSV File'), self.csvTestamentsEdit, u'%s (*.csv)'
|
||||
% translate('BiblesPlugin.ImportWizardForm', 'CSV File'))
|
||||
|
||||
def onCsvBooksBrowseButtonClicked(self):
|
||||
"""
|
||||
Show the file open dialog for the books CSV file.
|
||||
"""
|
||||
@ -613,12 +629,14 @@ class BibleImportForm(OpenLPWizard):
|
||||
"""
|
||||
self.selectPage.registerField(u'source_format', self.formatComboBox)
|
||||
self.selectPage.registerField(u'osis_location', self.osisFileEdit)
|
||||
self.selectPage.registerField(
|
||||
u'csv_testamentsfile', self.csvTestamentsEdit)
|
||||
self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit)
|
||||
self.selectPage.registerField(u'csv_versefile', self.csvVersesEdit)
|
||||
self.selectPage.registerField(u'opensong_file', self.openSongFileEdit)
|
||||
self.selectPage.registerField(u'web_location', self.webSourceComboBox)
|
||||
self.selectPage.registerField(u'web_biblename',
|
||||
self.webTranslationComboBox)
|
||||
self.selectPage.registerField(
|
||||
u'web_biblename', self.webTranslationComboBox)
|
||||
self.selectPage.registerField(u'proxy_server', self.webServerEdit)
|
||||
self.selectPage.registerField(u'proxy_username', self.webUserEdit)
|
||||
self.selectPage.registerField(u'proxy_password', self.webPasswordEdit)
|
||||
@ -641,6 +659,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
self.cancelButton.setVisible(True)
|
||||
self.setField(u'source_format', QtCore.QVariant(0))
|
||||
self.setField(u'osis_location', QtCore.QVariant(''))
|
||||
self.setField(u'csv_testamentsfile', QtCore.QVariant(''))
|
||||
self.setField(u'csv_booksfile', QtCore.QVariant(''))
|
||||
self.setField(u'csv_versefile', QtCore.QVariant(''))
|
||||
self.setField(u'opensong_file', QtCore.QVariant(''))
|
||||
@ -708,34 +727,6 @@ class BibleImportForm(OpenLPWizard):
|
||||
if books_file:
|
||||
books_file.close()
|
||||
|
||||
def getFileName(self, title, editbox, filters=u''):
|
||||
"""
|
||||
Opens a QFileDialog and saves the filename to the given editbox.
|
||||
|
||||
``title``
|
||||
The title of the dialog (unicode).
|
||||
|
||||
``editbox``
|
||||
A editbox (QLineEdit).
|
||||
|
||||
``filters``
|
||||
The file extension filters. It should contain the file description
|
||||
as well as the file extension. For example::
|
||||
|
||||
u'openlp.org 1.x bible (*.bible)'
|
||||
"""
|
||||
if filters:
|
||||
filters += u';;'
|
||||
filters += u'%s (*)' % translate('BiblesPlugin.ImportWizardForm',
|
||||
'All Files')
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self, title,
|
||||
os.path.dirname(SettingsManager.get_last_dir(
|
||||
self.plugin.settingsSection, 1)), filters)
|
||||
if filename:
|
||||
editbox.setText(filename)
|
||||
SettingsManager.set_last_dir(
|
||||
self.plugin.settingsSection, filename, 1)
|
||||
|
||||
def preWizard(self):
|
||||
"""
|
||||
Prepare the UI for the import.
|
||||
@ -770,7 +761,8 @@ class BibleImportForm(OpenLPWizard):
|
||||
elif bible_type == BibleFormat.CSV:
|
||||
# Import a CSV bible.
|
||||
importer = self.manager.import_bible(BibleFormat.CSV,
|
||||
name=license_version,
|
||||
name=license_version, testamentsfile=unicode(
|
||||
self.field(u'csv_testamentsfile').toString()),
|
||||
booksfile=unicode(self.field(u'csv_booksfile').toString()),
|
||||
versefile=unicode(self.field(u'csv_versefile').toString())
|
||||
)
|
||||
@ -795,8 +787,7 @@ class BibleImportForm(OpenLPWizard):
|
||||
bible = \
|
||||
self.web_bible_list[WebDownload.Bibleserver][bible_version]
|
||||
importer = self.manager.import_bible(
|
||||
BibleFormat.WebDownload,
|
||||
name=license_version,
|
||||
BibleFormat.WebDownload, name=license_version,
|
||||
download_source=WebDownload.get_name(download_location),
|
||||
download_name=bible,
|
||||
proxy_server=unicode(self.field(u'proxy_server').toString()),
|
||||
|
@ -33,6 +33,13 @@ import re
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def get_reference_match(match_type):
|
||||
"""
|
||||
Provides the regexes and matches to use while parsing strings for bible
|
||||
references.
|
||||
|
||||
``match_type``
|
||||
The type of reference information trying to be extracted in this call.
|
||||
"""
|
||||
local_separator = unicode(u':;;\s*[:vV]\s*;;-;;\s*-\s*;;,;;\s*,\s*;;end'
|
||||
).split(u';;') # English
|
||||
# local_separator = unicode(u',;;\s*,\s*;;-;;\s*-\s*;;.;;\.;;[Ee]nde'
|
||||
@ -62,69 +69,90 @@ def get_reference_match(match_type):
|
||||
def parse_reference(reference):
|
||||
"""
|
||||
This is the next generation über-awesome function that takes a person's
|
||||
typed in string and converts it to a reference list, a list of references to
|
||||
be queried from the Bible database files.
|
||||
typed in string and converts it to a list of references to be queried from
|
||||
the Bible database files.
|
||||
|
||||
This is a user manual like description, how the references are working.
|
||||
``reference``
|
||||
A string. The Bible reference to parse.
|
||||
|
||||
- Each reference starts with the book name. A chapter name is manditory.
|
||||
``John 3`` refers to Gospel of John chapter 3
|
||||
- A reference range can be given after a range separator.
|
||||
``John 3-5`` refers to John chapters 3 to 5
|
||||
- Single verses can be addressed after a verse separator
|
||||
``John 3:16`` refers to John chapter 3 verse 16
|
||||
``John 3:16-4:3`` refers to John chapter 3 verse 16 to chapter 4 verse 3
|
||||
- After a verse reference all further single values are treat as verse in
|
||||
the last selected chapter.
|
||||
``John 3:16-18`` refers to John chapter 3 verses 16 to 18
|
||||
- After a list separator it is possible to refer to additional verses. They
|
||||
are build analog to the first ones. This way it is possible to define
|
||||
each number of verse references. It is not possible to refer to verses in
|
||||
additional books.
|
||||
``John 3:16,18`` refers to John chapter 3 verses 16 and 18
|
||||
``John 3:16-18,20`` refers to John chapter 3 verses 16 to 18 and 20
|
||||
``John 3:16-18,4:1`` refers to John chapter 3 verses 16 to 18 and
|
||||
chapter 3 verse 1
|
||||
- If there is a range separator without further verse declaration the last
|
||||
refered chapter is addressed until the end.
|
||||
|
||||
``range_string`` is a regular expression which matches for verse range
|
||||
declarations:
|
||||
|
||||
1. ``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?'
|
||||
It starts with a optional chapter reference ``from_chapter`` followed by
|
||||
a verse separator.
|
||||
2. ``(?P<from_verse>[0-9]+)``
|
||||
The verse reference ``from_verse`` is manditory
|
||||
3. ``(?P<range_to>%(sep_r)s(?:`` ... ``|%(sep_e)s)?)?``
|
||||
A ``range_to`` declaration is optional. It starts with a range separator
|
||||
and contains optional a chapter and verse declaration or a end
|
||||
separator.
|
||||
4. ``(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?``
|
||||
The ``to_chapter`` reference with separator is equivalent to group 1.
|
||||
5. ``(?P<to_verse>[0-9]+)``
|
||||
The ``to_verse`` reference is equivalent to group 2.
|
||||
|
||||
The full reference is matched against get_reference_match(u'full'). This
|
||||
regular expression looks like this:
|
||||
|
||||
1. ``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*``
|
||||
The ``book`` group starts with the first non-whitespace character. There
|
||||
are optional leading digits followed by non-digits. The group ends
|
||||
before the whitspace in front of the next digit.
|
||||
2. ``(?P<ranges>(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$``
|
||||
The second group contains all ``ranges``. This can be multiple
|
||||
declarations of a range_string separated by a list separator.
|
||||
Returns ``None`` or a reference list.
|
||||
|
||||
The reference list is a list of tuples, with each tuple structured like
|
||||
this::
|
||||
|
||||
(book, chapter, from_verse, to_verse)
|
||||
|
||||
For example::
|
||||
|
||||
[(u'John', 3, 16, 18), (u'John', 4, 1, 1)]
|
||||
|
||||
``reference``
|
||||
The bible reference to parse.
|
||||
**Reference string details:**
|
||||
|
||||
Each reference starts with the book name and a chapter number. These are
|
||||
both mandatory.
|
||||
|
||||
* ``John 3`` refers to Gospel of John chapter 3
|
||||
|
||||
A reference range can be given after a range separator.
|
||||
|
||||
* ``John 3-5`` refers to John chapters 3 to 5
|
||||
|
||||
Single verses can be addressed after a verse separator.
|
||||
|
||||
* ``John 3:16`` refers to John chapter 3 verse 16
|
||||
* ``John 3:16-4:3`` refers to John chapter 3 verse 16 to chapter 4 verse 3
|
||||
|
||||
After a verse reference all further single values are treat as verse in
|
||||
the last selected chapter.
|
||||
|
||||
* ``John 3:16-18`` refers to John chapter 3 verses 16 to 18
|
||||
|
||||
After a list separator it is possible to refer to additional verses. They
|
||||
are build analog to the first ones. This way it is possible to define each
|
||||
number of verse references. It is not possible to refer to verses in
|
||||
additional books.
|
||||
|
||||
* ``John 3:16,18`` refers to John chapter 3 verses 16 and 18
|
||||
* ``John 3:16-18,20`` refers to John chapter 3 verses 16 to 18 and 20
|
||||
* ``John 3:16-18,4:1`` refers to John chapter 3 verses 16 to 18 and
|
||||
chapter 4 verse 1
|
||||
|
||||
If there is a range separator without further verse declaration the last
|
||||
refered chapter is addressed until the end.
|
||||
|
||||
``range_string`` is a regular expression which matches for verse range
|
||||
declarations:
|
||||
|
||||
``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?``
|
||||
It starts with a optional chapter reference ``from_chapter`` followed by
|
||||
a verse separator.
|
||||
|
||||
``(?P<from_verse>[0-9]+)``
|
||||
The verse reference ``from_verse`` is manditory
|
||||
|
||||
``(?P<range_to>%(sep_r)s(?:`` ... ``|%(sep_e)s)?)?``
|
||||
A ``range_to`` declaration is optional. It starts with a range separator
|
||||
and contains optional a chapter and verse declaration or a end
|
||||
separator.
|
||||
|
||||
``(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?``
|
||||
The ``to_chapter`` reference with separator is equivalent to group 1.
|
||||
|
||||
``(?P<to_verse>[0-9]+)``
|
||||
The ``to_verse`` reference is equivalent to group 2.
|
||||
|
||||
The full reference is matched against get_reference_match(u'full'). This
|
||||
regular expression looks like this:
|
||||
|
||||
``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*``
|
||||
The ``book`` group starts with the first non-whitespace character. There
|
||||
are optional leading digits followed by non-digits. The group ends
|
||||
before the whitspace in front of the next digit.
|
||||
|
||||
``(?P<ranges>(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$``
|
||||
The second group contains all ``ranges``. This can be multiple
|
||||
declarations of a range_string separated by a list separator.
|
||||
|
||||
Returns None or a reference list.
|
||||
"""
|
||||
log.debug(u'parse_reference("%s")', reference)
|
||||
match = get_reference_match(u'full').match(reference)
|
||||
@ -194,7 +222,7 @@ def parse_reference(reference):
|
||||
|
||||
class SearchResults(object):
|
||||
"""
|
||||
Encapsulate a set of search results. This is Bible-type independent.
|
||||
Encapsulate a set of search results. This is Bible-type independent.
|
||||
"""
|
||||
def __init__(self, book, chapter, verselist):
|
||||
"""
|
||||
@ -207,7 +235,8 @@ class SearchResults(object):
|
||||
The chapter of the book.
|
||||
|
||||
``verselist``
|
||||
The list of verses for this reading
|
||||
The list of verses for this reading.
|
||||
|
||||
"""
|
||||
self.book = book
|
||||
self.chapter = chapter
|
||||
|
@ -23,7 +23,48 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`cvsbible` modules provides a facility to import bibles from a set of
|
||||
CSV files.
|
||||
|
||||
The module expects two mandatory files containing the books and the verses and
|
||||
will accept an optional third file containing the testaments.
|
||||
|
||||
The format of the testament file is:
|
||||
|
||||
<testament_id>,<testament_name>
|
||||
|
||||
For example:
|
||||
|
||||
1,Old Testament
|
||||
2,New Testament
|
||||
|
||||
The format of the books file is:
|
||||
|
||||
<book_id>,<testament_id>,<book_name>,<book_abbreviation>
|
||||
|
||||
For example
|
||||
|
||||
1,1,Genesis,Gen
|
||||
2,1,Exodus,Exod
|
||||
...
|
||||
40,2,Matthew,Matt
|
||||
|
||||
There are two acceptable formats of the verses file. They are:
|
||||
|
||||
<book_id>,<chapter_number>,<verse_number>,<verse_text>
|
||||
or
|
||||
<book_name>,<chapter_number>,<verse_number>,<verse_text>
|
||||
|
||||
For example:
|
||||
|
||||
1,1,1,"In the beginning God created the heaven and the earth."
|
||||
or
|
||||
"Genesis",1,2,"And the earth was without form, and void; and...."
|
||||
|
||||
All CSV files are expected to use a comma (',') as the delimeter and double
|
||||
quotes ('"') as the quote symbol.
|
||||
"""
|
||||
import logging
|
||||
import chardet
|
||||
import csv
|
||||
@ -31,7 +72,7 @@ import csv
|
||||
from PyQt4 import QtCore
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.plugins.bibles.lib.db import BibleDB
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, Testament
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -39,68 +80,120 @@ class CSVBible(BibleDB):
|
||||
"""
|
||||
This class provides a specialisation for importing of CSV Bibles.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
"""
|
||||
Loads a Bible from a pair of CVS files passed in
|
||||
Loads a Bible from a set of CVS files.
|
||||
This class assumes the files contain all the information and
|
||||
a clean bible is being loaded.
|
||||
"""
|
||||
log.info(self.__class__.__name__)
|
||||
BibleDB.__init__(self, parent, **kwargs)
|
||||
try:
|
||||
self.testamentsfile = kwargs[u'testamentsfile']
|
||||
except KeyError:
|
||||
self.testamentsfile = None
|
||||
self.booksfile = kwargs[u'booksfile']
|
||||
self.versesfile = kwargs[u'versefile']
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
|
||||
|
||||
def setup_testaments(self):
|
||||
"""
|
||||
Overrides parent method so we can handle importing a testament file.
|
||||
"""
|
||||
if self.testamentsfile:
|
||||
self.wizard.progressBar.setMinimum(0)
|
||||
self.wizard.progressBar.setMaximum(2)
|
||||
self.wizard.progressBar.setValue(0)
|
||||
testaments_file = None
|
||||
try:
|
||||
details = get_file_encoding(self.testamentsfile)
|
||||
testaments_file = open(self.testamentsfile, 'rb')
|
||||
testaments_reader = csv.reader(testaments_file, delimiter=',',
|
||||
quotechar='"')
|
||||
for line in testaments_reader:
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
self.wizard.incrementProgressBar(unicode(
|
||||
translate('BibleDB.Wizard',
|
||||
'Importing testaments... %s')) %
|
||||
unicode(line[1], details['encoding']), 0)
|
||||
self.save_object(Testament.populate(
|
||||
name=unicode(line[1], details['encoding'])))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
except (IOError, IndexError):
|
||||
log.exception(u'Loading testaments from file failed')
|
||||
finally:
|
||||
if testaments_file:
|
||||
testaments_file.close()
|
||||
self.wizard.incrementProgressBar(unicode(translate(
|
||||
'BibleDB.Wizard', 'Importing testaments... done.')), 2)
|
||||
else:
|
||||
BibleDB.setup_testaments(self)
|
||||
|
||||
def do_import(self):
|
||||
"""
|
||||
Import the bible books and verses.
|
||||
"""
|
||||
self.wizard.progressBar.setValue(0)
|
||||
self.wizard.progressBar.setMinimum(0)
|
||||
self.wizard.progressBar.setMaximum(66)
|
||||
success = True
|
||||
books_file = None
|
||||
book_ptr = None
|
||||
verse_file = None
|
||||
book_list = {}
|
||||
# Populate the Tables
|
||||
try:
|
||||
details = get_file_encoding(self.booksfile)
|
||||
books_file = open(self.booksfile, 'r')
|
||||
dialect = csv.Sniffer().sniff(books_file.read(1024))
|
||||
books_file.seek(0)
|
||||
books_reader = csv.reader(books_file, dialect)
|
||||
books_reader = csv.reader(books_file, delimiter=',', quotechar='"')
|
||||
for line in books_reader:
|
||||
# cancel pressed
|
||||
if self.stop_import_flag:
|
||||
break
|
||||
details = chardet.detect(line[1])
|
||||
self.create_book(unicode(line[1], details['encoding']),
|
||||
line[2], int(line[0]))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.wizard.incrementProgressBar(unicode(
|
||||
translate('BibleDB.Wizard', 'Importing books... %s')) %
|
||||
unicode(line[2], details['encoding']))
|
||||
self.create_book(unicode(line[2], details['encoding']),
|
||||
unicode(line[3], details['encoding']), int(line[1]))
|
||||
book_list[int(line[0])] = unicode(line[2], details['encoding'])
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
except (IOError, IndexError):
|
||||
log.exception(u'Loading books from file failed')
|
||||
success = False
|
||||
finally:
|
||||
if books_file:
|
||||
books_file.close()
|
||||
if not success:
|
||||
if self.stop_import_flag or not success:
|
||||
return False
|
||||
self.wizard.progressBar.setValue(0)
|
||||
self.wizard.progressBar.setMaximum(67)
|
||||
verse_file = None
|
||||
try:
|
||||
verse_file = open(self.versesfile, 'r')
|
||||
dialect = csv.Sniffer().sniff(verse_file.read(1024))
|
||||
verse_file.seek(0)
|
||||
verse_reader = csv.reader(verse_file, dialect)
|
||||
book_ptr = None
|
||||
details = get_file_encoding(self.versesfile)
|
||||
verse_file = open(self.versesfile, 'rb')
|
||||
verse_reader = csv.reader(verse_file, delimiter=',', quotechar='"')
|
||||
for line in verse_reader:
|
||||
if self.stop_import_flag:
|
||||
# cancel pressed
|
||||
break
|
||||
details = chardet.detect(line[3])
|
||||
if book_ptr != line[0]:
|
||||
book = self.get_book(line[0])
|
||||
try:
|
||||
line_book = book_list[int(line[0])]
|
||||
except ValueError:
|
||||
line_book = unicode(line[0], details['encoding'])
|
||||
if book_ptr != line_book:
|
||||
book = self.get_book(line_book)
|
||||
book_ptr = book.name
|
||||
self.wizard.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.CSVImport', 'Importing %s %s...',
|
||||
'Importing <book name> <chapter>...')) %
|
||||
(book.name, int(line[1])))
|
||||
'BibleDB.Wizard', 'Importing verses from %s...',
|
||||
'Importing verses from <book name>...')) % book.name)
|
||||
self.session.commit()
|
||||
self.create_verse(book.id, line[1], line[2],
|
||||
unicode(line[3], details['encoding']))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
try:
|
||||
verse_text = unicode(line[3], details['encoding'])
|
||||
except UnicodeError:
|
||||
verse_text = unicode(line[3], u'cp1252')
|
||||
self.create_verse(book.id, line[1], line[2], verse_text)
|
||||
self.wizard.incrementProgressBar(translate('BibleDB.Wizard',
|
||||
'Importing verses... done.'))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.session.commit()
|
||||
except IOError:
|
||||
log.exception(u'Loading verses from file failed')
|
||||
@ -112,3 +205,18 @@ class CSVBible(BibleDB):
|
||||
return False
|
||||
else:
|
||||
return success
|
||||
|
||||
def get_file_encoding(filename):
|
||||
"""
|
||||
Utility function to get the file encoding.
|
||||
"""
|
||||
detect_file = None
|
||||
try:
|
||||
detect_file = open(filename, 'r')
|
||||
details = chardet.detect(detect_file.read(1024))
|
||||
except IOError:
|
||||
log.exception(u'Error detecting file encoding')
|
||||
finally:
|
||||
if detect_file:
|
||||
detect_file.close()
|
||||
return details
|
||||
|
@ -35,7 +35,7 @@ from sqlalchemy.orm.exc import UnmappedClassError
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -206,10 +206,16 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
"""
|
||||
self.wizard = wizard
|
||||
self.create_meta(u'dbversion', u'2')
|
||||
self.setup_testaments()
|
||||
return self.name
|
||||
|
||||
def setup_testaments(self):
|
||||
"""
|
||||
Initialise the testaments section of a bible with suitable defaults.
|
||||
"""
|
||||
self.save_object(Testament.populate(name=u'Old Testament'))
|
||||
self.save_object(Testament.populate(name=u'New Testament'))
|
||||
self.save_object(Testament.populate(name=u'Apocrypha'))
|
||||
return self.name
|
||||
|
||||
def create_book(self, name, abbrev, testament=1):
|
||||
"""
|
||||
@ -355,7 +361,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
verse_list.extend(verses)
|
||||
else:
|
||||
log.debug(u'OpenLP failed to find book %s', book)
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin', 'No Book Found'),
|
||||
translate('BiblesPlugin', 'No matching book '
|
||||
'could be found in this Bible. Check that you have '
|
||||
|
@ -38,7 +38,7 @@ from HTMLParser import HTMLParseError
|
||||
from BeautifulSoup import BeautifulSoup, NavigableString
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.utils import AppLocation, get_web_page
|
||||
from openlp.plugins.bibles.lib import SearchResults
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, Book
|
||||
@ -210,7 +210,8 @@ class BGExtract(object):
|
||||
cleaner = [(re.compile(' |<br />|\'\+\''), lambda match: '')]
|
||||
soup = get_soup_for_bible_ref(
|
||||
u'http://www.biblegateway.com/passage/?%s' % url_params,
|
||||
cleaner=cleaner)
|
||||
pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='',
|
||||
cleaner=cleaner)
|
||||
if not soup:
|
||||
return None
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
@ -430,7 +431,7 @@ class HTTPBible(BibleDB):
|
||||
if not db_book:
|
||||
book_details = HTTPBooks.get_book(book)
|
||||
if not book_details:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin', 'No Book Found'),
|
||||
translate('BiblesPlugin', 'No matching '
|
||||
'book could be found in this Bible. Check that you '
|
||||
@ -442,7 +443,6 @@ class HTTPBible(BibleDB):
|
||||
book = db_book.name
|
||||
if BibleDB.get_verse_count(self, book, reference[1]) == 0:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
search_results = self.get_chapter(book, reference[1])
|
||||
if search_results and search_results.has_verselist():
|
||||
## We have found a book of the bible lets check to see
|
||||
@ -499,7 +499,8 @@ class HTTPBible(BibleDB):
|
||||
"""
|
||||
return HTTPBooks.get_verse_count(book, chapter)
|
||||
|
||||
def get_soup_for_bible_ref(reference_url, header=None, cleaner=None):
|
||||
def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None,
|
||||
pre_parse_substitute=None, cleaner=None):
|
||||
"""
|
||||
Gets a webpage and returns a parsed and optionally cleaned soup or None.
|
||||
|
||||
@ -509,6 +510,13 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None):
|
||||
``header``
|
||||
An optional HTTP header to pass to the bible web server.
|
||||
|
||||
``pre_parse_regex``
|
||||
A regular expression to run on the webpage. Allows manipulation of the
|
||||
webpage before passing to BeautifulSoup for parsing.
|
||||
|
||||
``pre_parse_substitute``
|
||||
The text to replace any matches to the regular expression with.
|
||||
|
||||
``cleaner``
|
||||
An optional regex to use during webpage parsing.
|
||||
"""
|
||||
@ -518,12 +526,15 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None):
|
||||
if not page:
|
||||
send_error_message(u'download')
|
||||
return None
|
||||
page_source = page.read()
|
||||
if pre_parse_regex and pre_parse_substitute is not None:
|
||||
page_source = re.sub(pre_parse_regex, pre_parse_substitute, page_source)
|
||||
soup = None
|
||||
try:
|
||||
if cleaner:
|
||||
soup = BeautifulSoup(page, markupMassage=cleaner)
|
||||
soup = BeautifulSoup(page_source, markupMassage=cleaner)
|
||||
else:
|
||||
soup = BeautifulSoup(page)
|
||||
soup = BeautifulSoup(page_source)
|
||||
except HTMLParseError:
|
||||
log.exception(u'BeautifulSoup could not parse the bible page.')
|
||||
if not soup:
|
||||
@ -540,14 +551,14 @@ def send_error_message(error_type):
|
||||
The type of error that occured for the issue.
|
||||
"""
|
||||
if error_type == u'download':
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblePlugin.HTTPBible', 'Download Error'),
|
||||
translate('BiblePlugin.HTTPBible', 'There was a '
|
||||
'problem downloading your verse selection. Please check your '
|
||||
'Internet connection, and if this error continues to occur '
|
||||
'please consider reporting a bug.'))
|
||||
elif error_type == u'parse':
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('BiblePlugin.HTTPBible', 'Parse Error'),
|
||||
translate('BiblePlugin.HTTPBible', 'There was a '
|
||||
'problem extracting your verse selection. If this error continues '
|
||||
|
@ -92,7 +92,7 @@ class BibleFormat(object):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def list():
|
||||
def get_formats_list():
|
||||
"""
|
||||
Return a list of the supported Bible formats.
|
||||
"""
|
||||
|
@ -28,21 +28,22 @@ import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \
|
||||
ItemCapabilities, translate
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
|
||||
translate
|
||||
from openlp.core.lib.searchedit import SearchEdit
|
||||
from openlp.core.lib.ui import UiStrings, add_widget_completer, \
|
||||
media_item_combo_box, critical_error_message_box
|
||||
from openlp.plugins.bibles.forms import BibleImportForm
|
||||
from openlp.plugins.bibles.lib import get_reference_match
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class BibleListView(BaseListWithDnD):
|
||||
class BibleSearch(object):
|
||||
"""
|
||||
Custom list view descendant, required for drag and drop.
|
||||
Enumeration class for the different search methods for the "quick search".
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
self.PluginName = u'Bibles'
|
||||
BaseListWithDnD.__init__(self, parent)
|
||||
Reference = 1
|
||||
Text = 2
|
||||
|
||||
|
||||
class BibleMediaItem(MediaManagerItem):
|
||||
@ -53,7 +54,6 @@ class BibleMediaItem(MediaManagerItem):
|
||||
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'songs/song'
|
||||
self.ListViewWithDnD_class = BibleListView
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
# Place to store the search results for both bibles.
|
||||
self.search_results = {}
|
||||
@ -81,50 +81,33 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.quickLayout.setObjectName(u'quickLayout')
|
||||
self.quickVersionLabel = QtGui.QLabel(self.quickTab)
|
||||
self.quickVersionLabel.setObjectName(u'quickVersionLabel')
|
||||
self.quickVersionComboBox = QtGui.QComboBox(self.quickTab)
|
||||
self.quickVersionComboBox.setSizeAdjustPolicy(
|
||||
QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.quickVersionComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.quickVersionComboBox.setObjectName(u'quickVersionComboBox')
|
||||
self.quickVersionComboBox = media_item_combo_box(self.quickTab,
|
||||
u'quickVersionComboBox')
|
||||
self.quickVersionLabel.setBuddy(self.quickVersionComboBox)
|
||||
self.quickLayout.addRow(self.quickVersionLabel,
|
||||
self.quickVersionComboBox)
|
||||
self.quickSecondLabel = QtGui.QLabel(self.quickTab)
|
||||
self.quickSecondLabel.setObjectName(u'quickSecondLabel')
|
||||
self.quickSecondComboBox = QtGui.QComboBox(self.quickTab)
|
||||
self.quickSecondComboBox.setSizeAdjustPolicy(
|
||||
QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.quickSecondComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.quickSecondComboBox.setObjectName(u'quickSecondComboBox')
|
||||
self.quickSecondComboBox = media_item_combo_box(self.quickTab,
|
||||
u'quickSecondComboBox')
|
||||
self.quickSecondLabel.setBuddy(self.quickSecondComboBox)
|
||||
self.quickLayout.addRow(self.quickSecondLabel, self.quickSecondComboBox)
|
||||
self.quickSearchTypeLabel = QtGui.QLabel(self.quickTab)
|
||||
self.quickSearchTypeLabel.setObjectName(u'quickSearchTypeLabel')
|
||||
self.quickSearchComboBox = QtGui.QComboBox(self.quickTab)
|
||||
self.quickSearchComboBox.setSizeAdjustPolicy(
|
||||
QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.quickSearchComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.quickSearchComboBox.setObjectName(u'quickSearchComboBox')
|
||||
self.quickSearchTypeLabel.setBuddy(self.quickSearchComboBox)
|
||||
self.quickLayout.addRow(self.quickSearchTypeLabel,
|
||||
self.quickSearchComboBox)
|
||||
self.quickSearchLabel = QtGui.QLabel(self.quickTab)
|
||||
self.quickSearchLabel.setObjectName(u'quickSearchLabel')
|
||||
self.quickSearchEdit = QtGui.QLineEdit(self.quickTab)
|
||||
self.quickSearchEdit = SearchEdit(self.quickTab)
|
||||
self.quickSearchEdit.setObjectName(u'quickSearchEdit')
|
||||
self.quickSearchLabel.setBuddy(self.quickSearchEdit)
|
||||
self.quickSearchEdit.setSearchTypes([
|
||||
(BibleSearch.Reference, u':/bibles/bibles_search_reference.png',
|
||||
translate('BiblesPlugin.MediaItem', 'Scripture Reference')),
|
||||
(BibleSearch.Text, u':/bibles/bibles_search_text.png',
|
||||
translate('BiblesPlugin.MediaItem', 'Text Search'))
|
||||
])
|
||||
self.quickLayout.addRow(self.quickSearchLabel, self.quickSearchEdit)
|
||||
self.quickClearLabel = QtGui.QLabel(self.quickTab)
|
||||
self.quickClearLabel.setObjectName(u'quickClearLabel')
|
||||
self.quickClearComboBox = QtGui.QComboBox(self.quickTab)
|
||||
self.quickClearComboBox.setSizeAdjustPolicy(
|
||||
QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.quickClearComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.quickClearComboBox.setObjectName(u'quickClearComboBox')
|
||||
self.quickClearComboBox = media_item_combo_box(self.quickTab,
|
||||
u'quickClearComboBox')
|
||||
self.quickLayout.addRow(self.quickClearLabel, self.quickClearComboBox)
|
||||
self.quickSearchButtonLayout = QtGui.QHBoxLayout()
|
||||
self.quickSearchButtonLayout.setObjectName(u'quickSearchButtonLayout')
|
||||
@ -144,36 +127,24 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.advancedVersionLabel.setObjectName(u'advancedVersionLabel')
|
||||
self.advancedLayout.addWidget(self.advancedVersionLabel, 0, 0,
|
||||
QtCore.Qt.AlignRight)
|
||||
self.advancedVersionComboBox = QtGui.QComboBox(self.advancedTab)
|
||||
self.advancedVersionComboBox.setSizeAdjustPolicy(
|
||||
QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.advancedVersionComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.advancedVersionComboBox.setObjectName(u'advancedVersionComboBox')
|
||||
self.advancedVersionComboBox = media_item_combo_box(self.advancedTab,
|
||||
u'advancedVersionComboBox')
|
||||
self.advancedVersionLabel.setBuddy(self.advancedVersionComboBox)
|
||||
self.advancedLayout.addWidget(self.advancedVersionComboBox, 0, 1, 1, 2)
|
||||
self.advancedSecondLabel = QtGui.QLabel(self.advancedTab)
|
||||
self.advancedSecondLabel.setObjectName(u'advancedSecondLabel')
|
||||
self.advancedLayout.addWidget(self.advancedSecondLabel, 1, 0,
|
||||
QtCore.Qt.AlignRight)
|
||||
self.advancedSecondComboBox = QtGui.QComboBox(self.advancedTab)
|
||||
self.advancedSecondComboBox.setSizeAdjustPolicy(
|
||||
QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.advancedSecondComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.advancedSecondComboBox.setObjectName(u'advancedSecondComboBox')
|
||||
self.advancedSecondComboBox = media_item_combo_box(self.advancedTab,
|
||||
u'advancedSecondComboBox')
|
||||
self.advancedSecondLabel.setBuddy(self.advancedSecondComboBox)
|
||||
self.advancedLayout.addWidget(self.advancedSecondComboBox, 1, 1, 1, 2)
|
||||
self.advancedBookLabel = QtGui.QLabel(self.advancedTab)
|
||||
self.advancedBookLabel.setObjectName(u'advancedBookLabel')
|
||||
self.advancedLayout.addWidget(self.advancedBookLabel, 2, 0,
|
||||
QtCore.Qt.AlignRight)
|
||||
self.advancedBookComboBox = QtGui.QComboBox(self.advancedTab)
|
||||
self.advancedBookComboBox.setSizeAdjustPolicy(
|
||||
QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.advancedBookComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.advancedBookComboBox.setObjectName(u'advancedBookComboBox')
|
||||
self.advancedBookComboBox = media_item_combo_box(self.advancedTab,
|
||||
u'advancedBookComboBox')
|
||||
self.advancedBookLabel.setBuddy(self.advancedBookComboBox)
|
||||
self.advancedLayout.addWidget(self.advancedBookComboBox, 2, 1, 1, 2)
|
||||
self.advancedChapterLabel = QtGui.QLabel(self.advancedTab)
|
||||
@ -202,17 +173,12 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.advancedToVerse = QtGui.QComboBox(self.advancedTab)
|
||||
self.advancedToVerse.setObjectName(u'advancedToVerse')
|
||||
self.advancedLayout.addWidget(self.advancedToVerse, 5, 2)
|
||||
|
||||
self.advancedClearLabel = QtGui.QLabel(self.quickTab)
|
||||
self.advancedClearLabel.setObjectName(u'advancedClearLabel')
|
||||
self.advancedLayout.addWidget(self.advancedClearLabel, 6, 0,
|
||||
QtCore.Qt.AlignRight)
|
||||
self.advancedClearComboBox = QtGui.QComboBox(self.quickTab)
|
||||
self.advancedClearComboBox.setSizeAdjustPolicy(
|
||||
QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.advancedClearComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.advancedClearComboBox.setObjectName(u'advancedClearComboBox')
|
||||
self.advancedClearComboBox = media_item_combo_box(self.quickTab,
|
||||
u'advancedClearComboBox')
|
||||
self.advancedClearLabel.setBuddy(self.advancedClearComboBox)
|
||||
self.advancedLayout.addWidget(self.advancedClearComboBox, 6, 1, 1, 2)
|
||||
self.advancedSearchButtonLayout = QtGui.QHBoxLayout()
|
||||
@ -224,8 +190,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
self.advancedSearchButtonLayout.addWidget(self.advancedSearchButton)
|
||||
self.advancedLayout.addLayout(
|
||||
self.advancedSearchButtonLayout, 7, 0, 1, 3)
|
||||
self.searchTabWidget.addTab(self.advancedTab,
|
||||
translate('BiblesPlugin.MediaItem', 'Advanced'))
|
||||
self.searchTabWidget.addTab(self.advancedTab, UiStrings.Advanced)
|
||||
# Add the search tab widget to the page layout.
|
||||
self.pageLayout.addWidget(self.searchTabWidget)
|
||||
# Combo Boxes
|
||||
@ -239,8 +204,8 @@ class BibleMediaItem(MediaManagerItem):
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedFromVerse)
|
||||
QtCore.QObject.connect(self.advancedToChapter,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onAdvancedToChapter)
|
||||
QtCore.QObject.connect(self.quickSearchComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter)
|
||||
QtCore.QObject.connect(self.quickSearchEdit,
|
||||
QtCore.SIGNAL(u'searchTypeChanged(int)'), self.updateAutoCompleter)
|
||||
QtCore.QObject.connect(self.quickVersionComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter)
|
||||
# Buttons
|
||||
@ -254,9 +219,6 @@ class BibleMediaItem(MediaManagerItem):
|
||||
QtCore.QObject.connect(self.quickSearchEdit,
|
||||
QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton)
|
||||
|
||||
def addListViewToToolBar(self):
|
||||
MediaManagerItem.addListViewToToolBar(self)
|
||||
|
||||
def configUpdated(self):
|
||||
log.debug(u'configUpdated')
|
||||
if QtCore.QSettings().value(self.settingsSection + u'/second bibles',
|
||||
@ -277,8 +239,6 @@ class BibleMediaItem(MediaManagerItem):
|
||||
translate('BiblesPlugin.MediaItem', 'Version:'))
|
||||
self.quickSecondLabel.setText(
|
||||
translate('BiblesPlugin.MediaItem', 'Second:'))
|
||||
self.quickSearchTypeLabel.setText(
|
||||
translate('BiblesPlugin.MediaItem', 'Search type:'))
|
||||
self.quickSearchLabel.setText(
|
||||
translate('BiblesPlugin.MediaItem', 'Find:'))
|
||||
self.quickSearchButton.setText(
|
||||
@ -303,10 +263,6 @@ class BibleMediaItem(MediaManagerItem):
|
||||
translate('BiblesPlugin.MediaItem', 'Results:'))
|
||||
self.advancedSearchButton.setText(
|
||||
translate('BiblesPlugin.MediaItem', 'Search'))
|
||||
self.quickSearchComboBox.addItem(
|
||||
translate('BiblesPlugin.MediaItem', 'Verse Search'))
|
||||
self.quickSearchComboBox.addItem(
|
||||
translate('BiblesPlugin.MediaItem', 'Text Search'))
|
||||
self.quickClearComboBox.addItem(
|
||||
translate('BiblesPlugin.MediaItem', 'Clear'))
|
||||
self.quickClearComboBox.addItem(
|
||||
@ -390,7 +346,8 @@ class BibleMediaItem(MediaManagerItem):
|
||||
verse_count = self.parent.manager.get_verse_count(bible, book, 1)
|
||||
if verse_count == 0:
|
||||
self.advancedSearchButton.setEnabled(False)
|
||||
criticalErrorMessageBox(message=translate('BiblePlugin.MediaItem',
|
||||
critical_error_message_box(
|
||||
message=translate('BiblePlugin.MediaItem',
|
||||
'Bible not fully loaded'))
|
||||
else:
|
||||
self.advancedSearchButton.setEnabled(True)
|
||||
@ -403,20 +360,18 @@ class BibleMediaItem(MediaManagerItem):
|
||||
"""
|
||||
This updates the bible book completion list for the search field. The
|
||||
completion depends on the bible. It is only updated when we are doing a
|
||||
verse search, otherwise the auto completion list is removed.
|
||||
reference search, otherwise the auto completion list is removed.
|
||||
"""
|
||||
books = []
|
||||
# We have to do a 'Verse Search'.
|
||||
if self.quickSearchComboBox.currentIndex() == 0:
|
||||
# We have to do a 'Reference Search'.
|
||||
if self.quickSearchEdit.currentSearchType() == BibleSearch.Reference:
|
||||
bibles = self.parent.manager.get_bibles()
|
||||
bible = unicode(self.quickVersionComboBox.currentText())
|
||||
if bible:
|
||||
book_data = bibles[bible].get_books()
|
||||
books = [book.name for book in book_data]
|
||||
books.sort()
|
||||
completer = QtGui.QCompleter(books)
|
||||
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
|
||||
self.quickSearchEdit.setCompleter(completer)
|
||||
add_widget_completer(books, self.quickSearchEdit)
|
||||
|
||||
def onAdvancedVersionComboBox(self):
|
||||
self.initialiseBible(
|
||||
@ -528,19 +483,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
if self.advancedClearComboBox.currentIndex() == 0:
|
||||
self.listView.clear()
|
||||
if self.listView.count() != 0:
|
||||
# Check if the first item is a second bible item or not.
|
||||
bitem = self.listView.item(0)
|
||||
item_second_bible = self._decodeQtObject(bitem, 'second_bible')
|
||||
if item_second_bible and second_bible or not item_second_bible and \
|
||||
not second_bible:
|
||||
self.displayResults(bible, second_bible)
|
||||
elif criticalErrorMessageBox(
|
||||
message=translate('BiblePlugin.MediaItem',
|
||||
'You cannot combine single and second bible verses. Do you '
|
||||
'want to delete your search results and start a new search?'),
|
||||
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||
self.listView.clear()
|
||||
self.displayResults(bible, second_bible)
|
||||
self.__checkSecondBible(bible, second_bible)
|
||||
else:
|
||||
self.displayResults(bible, second_bible)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
@ -550,7 +493,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
def onQuickSearchButton(self):
|
||||
"""
|
||||
Does a quick search and saves the search results. Quick search can
|
||||
either be "Verse Search" or "Text Search".
|
||||
either be "Reference Search" or "Text Search".
|
||||
"""
|
||||
log.debug(u'Quick Search Button pressed')
|
||||
self.quickSearchButton.setEnabled(False)
|
||||
@ -558,8 +501,8 @@ class BibleMediaItem(MediaManagerItem):
|
||||
bible = unicode(self.quickVersionComboBox.currentText())
|
||||
second_bible = unicode(self.quickSecondComboBox.currentText())
|
||||
text = unicode(self.quickSearchEdit.text())
|
||||
if self.quickSearchComboBox.currentIndex() == 0:
|
||||
# We are doing a 'Verse Search'.
|
||||
if self.quickSearchEdit.currentSearchType() == BibleSearch.Reference:
|
||||
# We are doing a 'Reference Search'.
|
||||
self.search_results = self.parent.manager.get_verses(bible, text)
|
||||
if second_bible and self.search_results:
|
||||
self.second_search_results = self.parent.manager.get_verses(
|
||||
@ -580,24 +523,30 @@ class BibleMediaItem(MediaManagerItem):
|
||||
if self.quickClearComboBox.currentIndex() == 0:
|
||||
self.listView.clear()
|
||||
if self.listView.count() != 0 and self.search_results:
|
||||
bitem = self.listView.item(0)
|
||||
item_second_bible = self._decodeQtObject(bitem, 'second_bible')
|
||||
if item_second_bible and second_bible or not item_second_bible and \
|
||||
not second_bible:
|
||||
self.displayResults(bible, second_bible)
|
||||
elif criticalErrorMessageBox(
|
||||
message=translate('BiblePlugin.MediaItem',
|
||||
'You cannot combine single and second bible verses. Do you '
|
||||
'want to delete your search results and start a new search?'),
|
||||
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||
self.listView.clear()
|
||||
self.displayResults(bible, second_bible)
|
||||
self.__checkSecondBible(bible, second_bible)
|
||||
elif self.search_results:
|
||||
self.displayResults(bible, second_bible)
|
||||
self.quickSearchButton.setEnabled(True)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
||||
def __checkSecondBible(self, bible, second_bible):
|
||||
"""
|
||||
Check if the first item is a second bible item or not.
|
||||
"""
|
||||
bitem = self.listView.item(0)
|
||||
item_second_bible = self._decodeQtObject(bitem, 'second_bible')
|
||||
if item_second_bible and second_bible or not item_second_bible and \
|
||||
not second_bible:
|
||||
self.displayResults(bible, second_bible)
|
||||
elif critical_error_message_box(
|
||||
message=translate('BiblePlugin.MediaItem',
|
||||
'You cannot combine single and second bible verses. Do you '
|
||||
'want to delete your search results and start a new search?'),
|
||||
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||
self.listView.clear()
|
||||
self.displayResults(bible, second_bible)
|
||||
|
||||
def displayResults(self, bible, second_bible=u''):
|
||||
"""
|
||||
Displays the search results in the media manager. All data needed for
|
||||
|
@ -38,7 +38,6 @@ class OpenSongBible(BibleDB):
|
||||
"""
|
||||
OpenSong Bible format importer class.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, **kwargs):
|
||||
"""
|
||||
Constructor to create and set up an instance of the OpenSongBible
|
||||
@ -81,14 +80,13 @@ class OpenSongBible(BibleDB):
|
||||
db_book.id,
|
||||
int(chapter.attrib[u'n'].split()[-1]),
|
||||
int(verse.attrib[u'n']),
|
||||
unicode(verse.text)
|
||||
)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
unicode(verse.text))
|
||||
self.wizard.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.Opensong', 'Importing %s %s...',
|
||||
'Importing <book name> <chapter>...')) %
|
||||
(db_book.name, int(chapter.attrib[u'n'].split()[-1])))
|
||||
self.session.commit()
|
||||
self.session.commit()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
except (IOError, AttributeError):
|
||||
log.exception(u'Loading bible from OpenSong file failed')
|
||||
success = False
|
||||
|
@ -19,7 +19,7 @@ IBS-fordítás (Új Károli), KAR
|
||||
King James Version, KJV
|
||||
Luther 1984, LUT
|
||||
Septuaginta, LXX
|
||||
Neue Genfer Übersetzung, NGÜ
|
||||
Neue Genfer Übersetzung, NGU
|
||||
New International Readers Version, NIRV
|
||||
New International Version, NIV
|
||||
Neues Leben, NL
|
||||
|
|
@ -47,21 +47,14 @@ class CustomPlugin(Plugin):
|
||||
log.info(u'Custom Plugin loaded')
|
||||
|
||||
def __init__(self, plugin_helpers):
|
||||
Plugin.__init__(self, u'Custom', u'1.9.4', plugin_helpers)
|
||||
Plugin.__init__(self, u'Custom', u'1.9.4', plugin_helpers,
|
||||
CustomMediaItem, CustomTab)
|
||||
self.weight = -5
|
||||
self.manager = Manager(u'custom', init_schema)
|
||||
self.edit_custom_form = EditCustomForm(self.manager)
|
||||
self.icon_path = u':/plugins/plugin_custom.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
|
||||
def getSettingsTab(self):
|
||||
visible_name = self.getString(StringContent.VisibleName)
|
||||
return CustomTab(self.name, visible_name[u'title'])
|
||||
|
||||
def getMediaManagerItem(self):
|
||||
# Create the ManagerItem object
|
||||
return CustomMediaItem(self, self, self.icon)
|
||||
|
||||
def about(self):
|
||||
about_text = translate('CustomPlugin', '<strong>Custom Plugin</strong>'
|
||||
'<br />The custom plugin provides the ability to set up custom '
|
||||
@ -112,54 +105,20 @@ class CustomPlugin(Plugin):
|
||||
u'title': translate('CustomsPlugin', 'Custom', 'container title')
|
||||
}
|
||||
# Middle Header Bar
|
||||
## Import Action ##
|
||||
self.textStrings[StringContent.Import] = {
|
||||
u'title': translate('CustomsPlugin', 'Import'),
|
||||
u'tooltip': translate('CustomsPlugin',
|
||||
'Import a Custom')
|
||||
}
|
||||
## Load Action ##
|
||||
self.textStrings[StringContent.Load] = {
|
||||
u'title': translate('CustomsPlugin', 'Load'),
|
||||
u'tooltip': translate('CustomsPlugin',
|
||||
'Load a new Custom')
|
||||
}
|
||||
## New Action ##
|
||||
self.textStrings[StringContent.New] = {
|
||||
u'title': translate('CustomsPlugin', 'Add'),
|
||||
u'tooltip': translate('CustomsPlugin',
|
||||
'Add a new Custom')
|
||||
}
|
||||
## Edit Action ##
|
||||
self.textStrings[StringContent.Edit] = {
|
||||
u'title': translate('CustomsPlugin', 'Edit'),
|
||||
u'tooltip': translate('CustomsPlugin',
|
||||
'Edit the selected Custom')
|
||||
}
|
||||
## Delete Action ##
|
||||
self.textStrings[StringContent.Delete] = {
|
||||
u'title': translate('CustomsPlugin', 'Delete'),
|
||||
u'tooltip': translate('CustomsPlugin',
|
||||
'Delete the selected Custom')
|
||||
}
|
||||
## Preview Action ##
|
||||
self.textStrings[StringContent.Preview] = {
|
||||
u'title': translate('CustomsPlugin', 'Preview'),
|
||||
u'tooltip': translate('CustomsPlugin',
|
||||
'Preview the selected Custom')
|
||||
}
|
||||
## Send Live Action ##
|
||||
self.textStrings[StringContent.Live] = {
|
||||
u'title': translate('CustomsPlugin', 'Live'),
|
||||
u'tooltip': translate('CustomsPlugin',
|
||||
'Send the selected Custom live')
|
||||
}
|
||||
## Add to Service Action ##
|
||||
self.textStrings[StringContent.Service] = {
|
||||
u'title': translate('CustomsPlugin', 'Service'),
|
||||
u'tooltip': translate('CustomsPlugin',
|
||||
tooltips = {
|
||||
u'load': translate('CustomsPlugin', 'Load a new Custom'),
|
||||
u'import': translate('CustomsPlugin', 'Import a Custom'),
|
||||
u'new': translate('CustomsPlugin', 'Add a new Custom'),
|
||||
u'edit': translate('CustomsPlugin', 'Edit the selected Custom'),
|
||||
u'delete': translate('CustomsPlugin', 'Delete the selected Custom'),
|
||||
u'preview': translate('CustomsPlugin',
|
||||
'Preview the selected Custom'),
|
||||
u'live': translate('CustomsPlugin',
|
||||
'Send the selected Custom live'),
|
||||
u'service': translate('CustomsPlugin',
|
||||
'Add the selected Custom to the service')
|
||||
}
|
||||
self.setPluginUiTextStrings(tooltips)
|
||||
|
||||
def finalise(self):
|
||||
"""
|
||||
|
@ -27,6 +27,8 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import build_icon, translate
|
||||
from openlp.core.lib.ui import UiStrings, create_accept_reject_button_box, \
|
||||
create_delete_push_button, create_up_down_push_button_set
|
||||
|
||||
class Ui_CustomEditDialog(object):
|
||||
def setupUi(self, customEditDialog):
|
||||
@ -58,22 +60,21 @@ class Ui_CustomEditDialog(object):
|
||||
self.addButton.setObjectName(u'addButton')
|
||||
self.buttonLayout.addWidget(self.addButton)
|
||||
self.editButton = QtGui.QPushButton(customEditDialog)
|
||||
self.editButton.setEnabled(False)
|
||||
self.editButton.setObjectName(u'editButton')
|
||||
self.buttonLayout.addWidget(self.editButton)
|
||||
self.editAllButton = QtGui.QPushButton(customEditDialog)
|
||||
self.editAllButton.setObjectName(u'editAllButton')
|
||||
self.buttonLayout.addWidget(self.editAllButton)
|
||||
self.deleteButton = QtGui.QPushButton(customEditDialog)
|
||||
self.deleteButton.setObjectName(u'deleteButton')
|
||||
self.deleteButton = create_delete_push_button(customEditDialog)
|
||||
self.deleteButton.setEnabled(False)
|
||||
self.buttonLayout.addWidget(self.deleteButton)
|
||||
self.buttonLayout.addStretch()
|
||||
self.upButton = QtGui.QPushButton(customEditDialog)
|
||||
self.upButton.setIcon(build_icon(u':/services/service_up.png'))
|
||||
self.upButton.setObjectName(u'upButton')
|
||||
self.upButton, self.downButton = create_up_down_push_button_set(
|
||||
customEditDialog)
|
||||
self.upButton.setEnabled(False)
|
||||
self.downButton.setEnabled(False)
|
||||
self.buttonLayout.addWidget(self.upButton)
|
||||
self.downButton = QtGui.QPushButton(customEditDialog)
|
||||
self.downButton.setIcon(build_icon(u':/services/service_down.png'))
|
||||
self.downButton.setObjectName(u'downButton')
|
||||
self.buttonLayout.addWidget(self.downButton)
|
||||
self.centralLayout.addLayout(self.buttonLayout)
|
||||
self.dialogLayout.addLayout(self.centralLayout)
|
||||
@ -93,36 +94,24 @@ class Ui_CustomEditDialog(object):
|
||||
self.creditLabel.setBuddy(self.creditEdit)
|
||||
self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit)
|
||||
self.dialogLayout.addLayout(self.bottomFormLayout)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(customEditDialog)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
|
||||
QtGui.QDialogButtonBox.Save)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.buttonBox = create_accept_reject_button_box(customEditDialog)
|
||||
self.previewButton = QtGui.QPushButton()
|
||||
self.buttonBox.addButton(
|
||||
self.previewButton, QtGui.QDialogButtonBox.ActionRole)
|
||||
self.dialogLayout.addWidget(self.buttonBox)
|
||||
self.retranslateUi(customEditDialog)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
|
||||
customEditDialog.accept)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
|
||||
customEditDialog.closePressed)
|
||||
QtCore.QMetaObject.connectSlotsByName(customEditDialog)
|
||||
|
||||
def retranslateUi(self, customEditDialog):
|
||||
customEditDialog.setWindowTitle(
|
||||
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
|
||||
self.upButton.setToolTip(
|
||||
translate('CustomPlugin.EditCustomForm', 'Move slide up one '
|
||||
'position.'))
|
||||
self.downButton.setToolTip(
|
||||
translate('CustomPlugin.EditCustomForm', 'Move slide down one '
|
||||
'position.'))
|
||||
self.titleLabel.setText(
|
||||
translate('CustomPlugin.EditCustomForm', '&Title:'))
|
||||
self.addButton.setText(
|
||||
translate('CustomPlugin.EditCustomForm', '&Add'))
|
||||
self.addButton.setText(UiStrings.Add)
|
||||
self.addButton.setToolTip(
|
||||
translate('CustomPlugin.EditCustomForm', 'Add a new slide at '
|
||||
'bottom.'))
|
||||
self.editButton.setText(
|
||||
translate('CustomPlugin.EditCustomForm', '&Edit'))
|
||||
self.editButton.setText(UiStrings.Edit)
|
||||
self.editButton.setToolTip(
|
||||
translate('CustomPlugin.EditCustomForm', 'Edit the selected '
|
||||
'slide.'))
|
||||
@ -131,12 +120,9 @@ class Ui_CustomEditDialog(object):
|
||||
self.editAllButton.setToolTip(
|
||||
translate('CustomPlugin.EditCustomForm', 'Edit all the slides at '
|
||||
'once.'))
|
||||
self.deleteButton.setText(
|
||||
translate('CustomPlugin.EditCustomForm', '&Delete'))
|
||||
self.deleteButton.setToolTip(
|
||||
translate('CustomPlugin.EditCustomForm', 'Delete the selected '
|
||||
'slide.'))
|
||||
self.themeLabel.setText(
|
||||
translate('CustomPlugin.EditCustomForm', 'The&me:'))
|
||||
self.creditLabel.setText(
|
||||
translate('CustomPlugin.EditCustomForm', '&Credits:'))
|
||||
self.previewButton.setText(
|
||||
translate('CustomPlugin.EditCustomForm', 'Save && Preview'))
|
||||
|
@ -29,7 +29,7 @@ import logging
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
|
||||
from openlp.plugins.custom.lib.db import CustomSlide
|
||||
from editcustomdialog import Ui_CustomEditDialog
|
||||
@ -48,52 +48,22 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
# Create other objects and forms.
|
||||
self.manager = manager
|
||||
self.editSlideForm = EditCustomSlideForm(self)
|
||||
# Connecting signals and slots
|
||||
self.previewButton = QtGui.QPushButton()
|
||||
self.previewButton.setText(
|
||||
translate('CustomPlugin.EditCustomForm', 'Save && Preview'))
|
||||
self.buttonBox.addButton(
|
||||
self.previewButton, QtGui.QDialogButtonBox.ActionRole)
|
||||
QtCore.QObject.connect(self.buttonBox,
|
||||
QtCore.SIGNAL(u'clicked(QAbstractButton*)'), self.onPreview)
|
||||
QtCore.QObject.connect(self.previewButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onPreviewButtonPressed)
|
||||
QtCore.QObject.connect(self.addButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onAddButtonPressed)
|
||||
QtCore.QObject.connect(self.editButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onEditButtonPressed)
|
||||
QtCore.QObject.connect(self.editAllButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onEditAllButtonPressed)
|
||||
QtCore.QObject.connect(self.deleteButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onDeleteButtonPressed)
|
||||
QtCore.QObject.connect(self.upButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed)
|
||||
QtCore.QObject.connect(self.downButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed)
|
||||
QtCore.QObject.connect(self.slideListView,
|
||||
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
|
||||
self.onSlideListViewPressed)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
|
||||
# Create other objects and forms.
|
||||
self.manager = manager
|
||||
self.editSlideForm = EditCustomSlideForm(self)
|
||||
self.initialise()
|
||||
|
||||
def onPreview(self, button):
|
||||
log.debug(u'onPreview')
|
||||
if button.text() == unicode(translate('CustomPlugin.EditCustomForm',
|
||||
'Save && Preview')) and self.saveCustom():
|
||||
Receiver.send_message(u'custom_preview')
|
||||
|
||||
def initialise(self):
|
||||
self.addButton.setEnabled(True)
|
||||
self.deleteButton.setEnabled(False)
|
||||
self.editButton.setEnabled(False)
|
||||
self.editAllButton.setEnabled(True)
|
||||
self.titleEdit.setText(u'')
|
||||
self.creditEdit.setText(u'')
|
||||
self.slideListView.clear()
|
||||
# Make sure we have a new item.
|
||||
self.customSlide = CustomSlide()
|
||||
QtCore.QObject.connect(self.slideListView,
|
||||
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
|
||||
|
||||
def loadThemes(self, themelist):
|
||||
self.themeComboBox.clear()
|
||||
@ -112,9 +82,13 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
States whether the custom is edited while being previewed in the
|
||||
preview panel.
|
||||
"""
|
||||
self.customSlide = CustomSlide()
|
||||
self.initialise()
|
||||
if id != 0:
|
||||
self.slideListView.clear()
|
||||
if id == 0:
|
||||
self.customSlide = CustomSlide()
|
||||
self.titleEdit.setText(u'')
|
||||
self.creditEdit.setText(u'')
|
||||
self.themeComboBox.setCurrentIndex(0)
|
||||
else:
|
||||
self.customSlide = self.manager.get_object(CustomSlide, id)
|
||||
self.titleEdit.setText(self.customSlide.title)
|
||||
self.creditEdit.setText(self.customSlide.credits)
|
||||
@ -128,31 +102,26 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
if id == -1:
|
||||
id = 0
|
||||
self.themeComboBox.setCurrentIndex(id)
|
||||
else:
|
||||
self.themeComboBox.setCurrentIndex(0)
|
||||
self.editAllButton.setEnabled(False)
|
||||
# If not preview hide the preview button.
|
||||
self.previewButton.setVisible(False)
|
||||
if preview:
|
||||
self.previewButton.setVisible(True)
|
||||
|
||||
def closePressed(self):
|
||||
def reject(self):
|
||||
Receiver.send_message(u'custom_edit_clear')
|
||||
self.close()
|
||||
QtGui.QDialog.reject(self)
|
||||
|
||||
def accept(self):
|
||||
log.debug(u'accept')
|
||||
if self.saveCustom():
|
||||
Receiver.send_message(u'custom_load_list')
|
||||
self.close()
|
||||
QtGui.QDialog.accept(self)
|
||||
|
||||
def saveCustom(self):
|
||||
"""
|
||||
Saves the custom.
|
||||
"""
|
||||
valid, message = self._validate()
|
||||
if not valid:
|
||||
criticalErrorMessageBox(message=message)
|
||||
if not self._validate():
|
||||
return False
|
||||
sxml = CustomXMLBuilder()
|
||||
sxml.new_document()
|
||||
@ -168,14 +137,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
self.customSlide.theme_name = unicode(self.themeComboBox.currentText())
|
||||
return self.manager.save_object(self.customSlide)
|
||||
|
||||
def onUpButtonPressed(self):
|
||||
def onUpButtonClicked(self):
|
||||
selectedRow = self.slideListView.currentRow()
|
||||
if selectedRow != 0:
|
||||
qw = self.slideListView.takeItem(selectedRow)
|
||||
self.slideListView.insertItem(selectedRow - 1, qw)
|
||||
self.slideListView.setCurrentRow(selectedRow - 1)
|
||||
|
||||
def onDownButtonPressed(self):
|
||||
def onDownButtonClicked(self):
|
||||
selectedRow = self.slideListView.currentRow()
|
||||
# zero base arrays
|
||||
if selectedRow != self.slideListView.count() - 1:
|
||||
@ -183,16 +152,11 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
self.slideListView.insertItem(selectedRow + 1, qw)
|
||||
self.slideListView.setCurrentRow(selectedRow + 1)
|
||||
|
||||
def onSlideListViewPressed(self, item):
|
||||
self.deleteButton.setEnabled(True)
|
||||
self.editButton.setEnabled(True)
|
||||
|
||||
def onAddButtonPressed(self):
|
||||
self.editSlideForm.setText(u'')
|
||||
if self.editSlideForm.exec_():
|
||||
for slide in self.editSlideForm.getText():
|
||||
self.slideListView.addItem(slide)
|
||||
self.editAllButton.setEnabled(True)
|
||||
|
||||
def onEditButtonPressed(self):
|
||||
self.editSlideForm.setText(self.slideListView.currentItem().text())
|
||||
@ -203,16 +167,23 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
"""
|
||||
Edits all slides.
|
||||
"""
|
||||
if self.slideListView.count() > 0:
|
||||
slide_list = u''
|
||||
for row in range(0, self.slideListView.count()):
|
||||
item = self.slideListView.item(row)
|
||||
slide_list += item.text()
|
||||
if row != self.slideListView.count() - 1:
|
||||
slide_list += u'\n[---]\n'
|
||||
self.editSlideForm.setText(slide_list)
|
||||
if self.editSlideForm.exec_():
|
||||
self.updateSlideList(self.editSlideForm.getText(), True)
|
||||
slide_list = u''
|
||||
for row in range(0, self.slideListView.count()):
|
||||
item = self.slideListView.item(row)
|
||||
slide_list += item.text()
|
||||
if row != self.slideListView.count() - 1:
|
||||
slide_list += u'\n[---]\n'
|
||||
self.editSlideForm.setText(slide_list)
|
||||
if self.editSlideForm.exec_():
|
||||
self.updateSlideList(self.editSlideForm.getText(), True)
|
||||
|
||||
def onPreviewButtonPressed(self):
|
||||
"""
|
||||
Save the custom item and preview it.
|
||||
"""
|
||||
log.debug(u'onPreview')
|
||||
if self.saveCustom():
|
||||
Receiver.send_message(u'custom_preview')
|
||||
|
||||
def updateSlideList(self, slides, edit_all=False):
|
||||
"""
|
||||
@ -243,14 +214,41 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
self.slideListView.addItem(slide)
|
||||
self.slideListView.repaint()
|
||||
|
||||
def onDeleteButtonPressed(self):
|
||||
def onDeleteButtonClicked(self):
|
||||
"""
|
||||
Removes the current row from the list.
|
||||
"""
|
||||
self.slideListView.takeItem(self.slideListView.currentRow())
|
||||
self.editButton.setEnabled(True)
|
||||
self.editAllButton.setEnabled(True)
|
||||
if self.slideListView.count() == 0:
|
||||
if self.slideListView.currentRow() == 0:
|
||||
self.upButton.setEnabled(False)
|
||||
if self.slideListView.currentRow() == self.slideListView.count():
|
||||
self.downButton.setEnabled(False)
|
||||
|
||||
def onCurrentRowChanged(self, row):
|
||||
"""
|
||||
Called when the *slideListView*'s current row has been changed. This
|
||||
enables or disables buttons which require an slide to act on.
|
||||
|
||||
``row``
|
||||
The row (int). If there is no current row, the value is -1.
|
||||
"""
|
||||
if row == -1:
|
||||
self.deleteButton.setEnabled(False)
|
||||
self.editButton.setEnabled(False)
|
||||
self.editAllButton.setEnabled(False)
|
||||
self.upButton.setEnabled(False)
|
||||
self.downButton.setEnabled(False)
|
||||
else:
|
||||
self.deleteButton.setEnabled(True)
|
||||
self.editButton.setEnabled(True)
|
||||
# Decide if the up/down buttons should be enabled or not.
|
||||
if self.slideListView.count() - 1 == row:
|
||||
self.downButton.setEnabled(False)
|
||||
else:
|
||||
self.downButton.setEnabled(True)
|
||||
if row == 0:
|
||||
self.upButton.setEnabled(False)
|
||||
else:
|
||||
self.upButton.setEnabled(True)
|
||||
|
||||
def _validate(self):
|
||||
"""
|
||||
@ -259,10 +257,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
||||
# We must have a title.
|
||||
if len(self.titleEdit.displayText()) == 0:
|
||||
self.titleEdit.setFocus()
|
||||
return False, translate('CustomPlugin.EditCustomForm',
|
||||
'You need to type in a title.')
|
||||
critical_error_message_box(
|
||||
message=translate('CustomPlugin.EditCustomForm',
|
||||
'You need to type in a title.'))
|
||||
return False
|
||||
# We must have at least one slide.
|
||||
if self.slideListView.count() == 0:
|
||||
return False, translate('CustomPlugin.EditCustomForm',
|
||||
'You need to add at least one slide')
|
||||
return True, u''
|
||||
critical_error_message_box(
|
||||
message=translate('CustomPlugin.EditCustomForm',
|
||||
'You need to add at least one slide'))
|
||||
return False
|
||||
return True
|
||||
|
@ -27,6 +27,7 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, SpellTextEdit
|
||||
from openlp.core.lib.ui import create_accept_reject_button_box
|
||||
|
||||
class Ui_CustomSlideEditDialog(object):
|
||||
def setupUi(self, customSlideEditDialog):
|
||||
@ -36,20 +37,13 @@ class Ui_CustomSlideEditDialog(object):
|
||||
self.slideTextEdit = SpellTextEdit(self)
|
||||
self.slideTextEdit.setObjectName(u'slideTextEdit')
|
||||
self.dialogLayout.addWidget(self.slideTextEdit)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(customSlideEditDialog)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
|
||||
QtGui.QDialogButtonBox.Save)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.buttonBox = create_accept_reject_button_box(customSlideEditDialog)
|
||||
self.splitButton = QtGui.QPushButton(customSlideEditDialog)
|
||||
self.splitButton.setObjectName(u'splitButton')
|
||||
self.buttonBox.addButton(self.splitButton,
|
||||
QtGui.QDialogButtonBox.ActionRole)
|
||||
self.dialogLayout.addWidget(self.buttonBox)
|
||||
self.retranslateUi(customSlideEditDialog)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
|
||||
customSlideEditDialog.accept)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
|
||||
customSlideEditDialog.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(customSlideEditDialog)
|
||||
|
||||
def retranslateUi(self, customSlideEditDialog):
|
||||
|
@ -28,18 +28,13 @@ import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, \
|
||||
Receiver, ItemCapabilities, translate, check_item_selected
|
||||
from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
|
||||
translate, check_item_selected
|
||||
from openlp.plugins.custom.lib import CustomXMLParser
|
||||
from openlp.plugins.custom.lib.db import CustomSlide
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class CustomListView(BaseListWithDnD):
|
||||
def __init__(self, parent=None):
|
||||
self.PluginName = u'Custom'
|
||||
BaseListWithDnD.__init__(self, parent)
|
||||
|
||||
class CustomMediaItem(MediaManagerItem):
|
||||
"""
|
||||
This is the custom media manager item for Custom Slides.
|
||||
@ -48,9 +43,6 @@ class CustomMediaItem(MediaManagerItem):
|
||||
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'custom/custom'
|
||||
# this next is a class, not an instance of a class - it will
|
||||
# be instanced by the base MediaManagerItem
|
||||
self.ListViewWithDnD_class = CustomListView
|
||||
MediaManagerItem.__init__(self, parent, self, icon)
|
||||
self.singleServiceItem = False
|
||||
# Holds information about whether the edit is remotly triggered and
|
||||
@ -68,11 +60,8 @@ class CustomMediaItem(MediaManagerItem):
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
|
||||
|
||||
def requiredIcons(self):
|
||||
MediaManagerItem.requiredIcons(self)
|
||||
|
||||
def initialise(self):
|
||||
self.loadCustomListView(self.manager.get_all_objects(
|
||||
self.loadList(self.manager.get_all_objects(
|
||||
CustomSlide, order_by_ref=CustomSlide.title))
|
||||
# Called to redisplay the custom list screen edith from a search
|
||||
# or from the exit of the Custom edit dialog. If remote editing is
|
||||
@ -83,7 +72,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
self.onPreviewClick()
|
||||
self.onRemoteEditClear()
|
||||
|
||||
def loadCustomListView(self, list):
|
||||
def loadList(self, list):
|
||||
self.listView.clear()
|
||||
for customSlide in list:
|
||||
custom_name = QtGui.QListWidgetItem(customSlide.title)
|
||||
@ -149,16 +138,7 @@ class CustomMediaItem(MediaManagerItem):
|
||||
raw_footer = []
|
||||
slide = None
|
||||
theme = None
|
||||
if item is None:
|
||||
if self.remoteTriggered is None:
|
||||
item = self.listView.currentItem()
|
||||
if item is None:
|
||||
return False
|
||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
else:
|
||||
item_id = self.remoteCustom
|
||||
else:
|
||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
item_id = self._getIdOfItemToGenerate(item, self.remoteCustom)
|
||||
service_item.add_capability(ItemCapabilities.AllowsEdit)
|
||||
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
||||
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
||||
@ -182,4 +162,4 @@ class CustomMediaItem(MediaManagerItem):
|
||||
else:
|
||||
raw_footer.append(u'')
|
||||
service_item.raw_footer = raw_footer
|
||||
return True
|
||||
return True
|
||||
|
@ -35,15 +35,12 @@ class ImagePlugin(Plugin):
|
||||
log.info(u'Image Plugin loaded')
|
||||
|
||||
def __init__(self, plugin_helpers):
|
||||
Plugin.__init__(self, u'Images', u'1.9.4', plugin_helpers)
|
||||
Plugin.__init__(self, u'Images', u'1.9.4', plugin_helpers,
|
||||
ImageMediaItem)
|
||||
self.weight = -7
|
||||
self.icon_path = u':/plugins/plugin_images.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
|
||||
def getMediaManagerItem(self):
|
||||
# Create the MediaManagerItem object.
|
||||
return ImageMediaItem(self, self, self.icon)
|
||||
|
||||
def about(self):
|
||||
about_text = translate('ImagePlugin', '<strong>Image Plugin</strong>'
|
||||
'<br />The image plugin provides displaying of images.<br />One '
|
||||
@ -72,45 +69,15 @@ class ImagePlugin(Plugin):
|
||||
u'title': translate('ImagePlugin', 'Images', 'container title')
|
||||
}
|
||||
# Middle Header Bar
|
||||
## Load Button ##
|
||||
self.textStrings[StringContent.Load] = {
|
||||
u'title': translate('ImagePlugin', 'Load'),
|
||||
u'tooltip': translate('ImagePlugin',
|
||||
'Load a new Image')
|
||||
}
|
||||
## New Button ##
|
||||
self.textStrings[StringContent.New] = {
|
||||
u'title': translate('ImagePlugin', 'Add'),
|
||||
u'tooltip': translate('ImagePlugin',
|
||||
'Add a new Image')
|
||||
}
|
||||
## Edit Button ##
|
||||
self.textStrings[StringContent.Edit] = {
|
||||
u'title': translate('ImagePlugin', 'Edit'),
|
||||
u'tooltip': translate('ImagePlugin',
|
||||
'Edit the selected Image')
|
||||
}
|
||||
## Delete Button ##
|
||||
self.textStrings[StringContent.Delete] = {
|
||||
u'title': translate('ImagePlugin', 'Delete'),
|
||||
u'tooltip': translate('ImagePlugin',
|
||||
'Delete the selected Image')
|
||||
}
|
||||
## Preview ##
|
||||
self.textStrings[StringContent.Preview] = {
|
||||
u'title': translate('ImagePlugin', 'Preview'),
|
||||
u'tooltip': translate('ImagePlugin',
|
||||
'Preview the selected Image')
|
||||
}
|
||||
## Live Button ##
|
||||
self.textStrings[StringContent.Live] = {
|
||||
u'title': translate('ImagePlugin', 'Live'),
|
||||
u'tooltip': translate('ImagePlugin',
|
||||
'Send the selected Image live')
|
||||
}
|
||||
## Add to service Button ##
|
||||
self.textStrings[StringContent.Service] = {
|
||||
u'title': translate('ImagePlugin', 'Service'),
|
||||
u'tooltip': translate('ImagePlugin',
|
||||
tooltips = {
|
||||
u'load': translate('ImagePlugin', 'Load a new Image'),
|
||||
u'import': u'',
|
||||
u'new': translate('ImagePlugin', 'Add a new Image'),
|
||||
u'edit': translate('ImagePlugin', 'Edit the selected Image'),
|
||||
u'delete': translate('ImagePlugin', 'Delete the selected Image'),
|
||||
u'preview': translate('ImagePlugin', 'Preview the selected Image'),
|
||||
u'live': translate('ImagePlugin', 'Send the selected Image live'),
|
||||
u'service': translate('ImagePlugin',
|
||||
'Add the selected Image to the service')
|
||||
}
|
||||
self.setPluginUiTextStrings(tooltips)
|
||||
|
@ -29,22 +29,14 @@ import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
||||
ItemCapabilities, SettingsManager, translate, check_item_selected, \
|
||||
check_directory_exists
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \
|
||||
SettingsManager, translate, check_item_selected, check_directory_exists, \
|
||||
Receiver
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.core.utils import AppLocation, delete_file, get_images_filter
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# We have to explicitly create separate classes for each plugin
|
||||
# in order for DnD to the Service manager to work correctly.
|
||||
class ImageListView(BaseListWithDnD):
|
||||
def __init__(self, parent=None):
|
||||
self.PluginName = u'Images'
|
||||
BaseListWithDnD.__init__(self, parent)
|
||||
|
||||
|
||||
class ImageMediaItem(MediaManagerItem):
|
||||
"""
|
||||
This is the custom media manager item for images.
|
||||
@ -53,25 +45,20 @@ class ImageMediaItem(MediaManagerItem):
|
||||
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'images/image'
|
||||
# This next is a class, not an instance of a class - it will
|
||||
# be instanced by the base MediaManagerItem.
|
||||
self.ListViewWithDnD_class = ImageListView
|
||||
MediaManagerItem.__init__(self, parent, self, icon)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.OnNewPrompt = translate('ImagePlugin.MediaItem',
|
||||
'Select Image(s)')
|
||||
file_formats = get_images_filter()
|
||||
self.OnNewFileMasks = u'%s;;%s (*.*) (*)' % (file_formats,
|
||||
unicode(translate('ImagePlugin.MediaItem', 'All Files')))
|
||||
self.replaceAction.setText(
|
||||
translate('ImagePlugin.MediaItem', 'Replace Background'))
|
||||
self.replaceAction.setToolTip(
|
||||
translate('ImagePlugin.MediaItem', 'Replace Live Background'))
|
||||
self.resetAction.setText(
|
||||
translate('ImagePlugin.MediaItem', 'Reset Background'))
|
||||
self.resetAction.setToolTip(
|
||||
translate('ImagePlugin.MediaItem', 'Reset Live Background'))
|
||||
UiStrings.AllFiles)
|
||||
self.replaceAction.setText(UiStrings.ReplaceBG)
|
||||
self.replaceAction.setToolTip(UiStrings.ReplaceLiveBG)
|
||||
self.resetAction.setText(UiStrings.ResetBG)
|
||||
self.resetAction.setToolTip(UiStrings.ResetLiveBG)
|
||||
|
||||
def requiredIcons(self):
|
||||
MediaManagerItem.requiredIcons(self)
|
||||
@ -83,8 +70,6 @@ class ImageMediaItem(MediaManagerItem):
|
||||
def initialise(self):
|
||||
log.debug(u'initialise')
|
||||
self.listView.clear()
|
||||
self.listView.setSelectionMode(
|
||||
QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.listView.setIconSize(QtCore.QSize(88, 50))
|
||||
self.servicePath = os.path.join(
|
||||
AppLocation.get_section_data_path(self.settingsSection),
|
||||
@ -95,7 +80,6 @@ class ImageMediaItem(MediaManagerItem):
|
||||
|
||||
def addListViewToToolBar(self):
|
||||
MediaManagerItem.addListViewToToolBar(self)
|
||||
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||
self.listView.addAction(self.replaceAction)
|
||||
|
||||
def addEndHeaderBar(self):
|
||||
@ -123,26 +107,26 @@ class ImageMediaItem(MediaManagerItem):
|
||||
self.settingsSection, self.getFileList())
|
||||
|
||||
def loadList(self, list):
|
||||
for file in list:
|
||||
filename = os.path.split(unicode(file))[1]
|
||||
for imageFile in list:
|
||||
filename = os.path.split(unicode(imageFile))[1]
|
||||
thumb = os.path.join(self.servicePath, filename)
|
||||
if os.path.exists(thumb):
|
||||
if self.validate(file, thumb):
|
||||
if self.validate(imageFile, thumb):
|
||||
icon = build_icon(thumb)
|
||||
else:
|
||||
icon = build_icon(u':/general/general_delete.png')
|
||||
else:
|
||||
icon = self.iconFromFile(file, thumb)
|
||||
icon = self.iconFromFile(imageFile, thumb)
|
||||
item_name = QtGui.QListWidgetItem(filename)
|
||||
item_name.setIcon(icon)
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
|
||||
self.listView.addItem(item_name)
|
||||
|
||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
||||
items = self.listView.selectedIndexes()
|
||||
if items:
|
||||
service_item.title = unicode(
|
||||
translate('ImagePlugin.MediaItem', 'Image(s)'))
|
||||
translate('ImagePlugin.MediaItem', 'Images'))
|
||||
service_item.add_capability(ItemCapabilities.AllowsMaintain)
|
||||
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
||||
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
||||
@ -161,7 +145,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
items.remove(item)
|
||||
# We cannot continue, as all images do not exist.
|
||||
if not items:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
|
||||
unicode(translate('ImagePlugin.MediaItem',
|
||||
'The following image(s) no longer exist: %s')) %
|
||||
@ -193,6 +177,12 @@ class ImageMediaItem(MediaManagerItem):
|
||||
self.resetAction.setVisible(False)
|
||||
self.parent.liveController.display.resetImage()
|
||||
|
||||
def liveThemeChanged(self):
|
||||
"""
|
||||
Triggered by the change of theme in the slide controller
|
||||
"""
|
||||
self.resetAction.setVisible(False)
|
||||
|
||||
def onReplaceClick(self):
|
||||
"""
|
||||
Called to replace Live backgound with the image selected.
|
||||
@ -208,11 +198,8 @@ class ImageMediaItem(MediaManagerItem):
|
||||
self.parent.liveController.display.directImage(name, filename)
|
||||
self.resetAction.setVisible(True)
|
||||
else:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('ImagePlugin.MediaItem', 'Live Background Error'),
|
||||
unicode(translate('ImagePlugin.MediaItem',
|
||||
'There was a problem replacing your background, '
|
||||
'the image file "%s" no longer exists.')) % filename)
|
||||
|
||||
def onPreviewClick(self):
|
||||
MediaManagerItem.onPreviewClick(self)
|
||||
|
@ -29,18 +29,13 @@ import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
||||
ItemCapabilities, SettingsManager, translate, check_item_selected
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \
|
||||
SettingsManager, translate, check_item_selected, Receiver
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from PyQt4.phonon import Phonon
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class MediaListView(BaseListWithDnD):
|
||||
def __init__(self, parent=None):
|
||||
self.PluginName = u'Media'
|
||||
BaseListWithDnD.__init__(self, parent)
|
||||
|
||||
|
||||
class MediaMediaItem(MediaManagerItem):
|
||||
"""
|
||||
This is the custom media manager item for Media Slides.
|
||||
@ -50,28 +45,27 @@ class MediaMediaItem(MediaManagerItem):
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'images/image'
|
||||
self.background = False
|
||||
# this next is a class, not an instance of a class - it will
|
||||
# be instanced by the base MediaManagerItem
|
||||
self.ListViewWithDnD_class = MediaListView
|
||||
self.PreviewFunction = QtGui.QPixmap(
|
||||
u':/media/media_video.png').toImage()
|
||||
MediaManagerItem.__init__(self, parent, self, icon)
|
||||
self.singleServiceItem = False
|
||||
self.serviceItemIconName = u':/media/image_clapperboard.png'
|
||||
self.mediaObject = Phonon.MediaObject(self)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'video_background_replaced'),
|
||||
self.videobackgroundReplaced)
|
||||
QtCore.QObject.connect(self.mediaObject,
|
||||
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
|
||||
self.videoStart)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.OnNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
|
||||
self.OnNewFileMasks = unicode(translate('MediaPlugin.MediaItem',
|
||||
'Videos (%s);;Audio (%s);;All files (*)')) % \
|
||||
(self.parent.video_list, self.parent.audio_list)
|
||||
self.replaceAction.setText(
|
||||
translate('MediaPlugin.MediaItem', 'Replace Background'))
|
||||
self.replaceAction.setToolTip(
|
||||
translate('MediaPlugin.MediaItem', 'Replace Live Background'))
|
||||
self.resetAction.setText(
|
||||
translate('MediaPlugin.MediaItem', 'Reset Background'))
|
||||
self.resetAction.setToolTip(
|
||||
translate('ImagePlugin.MediaItem', 'Reset Live Background'))
|
||||
'Videos (%s);;Audio (%s);;%s (*)')) % (self.parent.video_list,
|
||||
self.parent.audio_list, UiStrings.AllFiles)
|
||||
self.replaceAction.setText(UiStrings.ReplaceBG)
|
||||
self.replaceAction.setToolTip(UiStrings.ReplaceLiveBG)
|
||||
self.resetAction.setText(UiStrings.ResetBG)
|
||||
self.resetAction.setToolTip(UiStrings.ResetLiveBG)
|
||||
|
||||
def requiredIcons(self):
|
||||
MediaManagerItem.requiredIcons(self)
|
||||
@ -81,7 +75,6 @@ class MediaMediaItem(MediaManagerItem):
|
||||
|
||||
def addListViewToToolBar(self):
|
||||
MediaManagerItem.addListViewToToolBar(self)
|
||||
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
||||
self.listView.addAction(self.replaceAction)
|
||||
|
||||
def addEndHeaderBar(self):
|
||||
@ -99,6 +92,12 @@ class MediaMediaItem(MediaManagerItem):
|
||||
self.resetAction.setVisible(False)
|
||||
self.parent.liveController.display.resetVideo()
|
||||
|
||||
def videobackgroundReplaced(self):
|
||||
"""
|
||||
Triggered by main display on change of serviceitem
|
||||
"""
|
||||
self.resetAction.setVisible(False)
|
||||
|
||||
def onReplaceClick(self):
|
||||
"""
|
||||
Called to replace Live backgound with the media selected.
|
||||
@ -113,7 +112,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
self.parent.liveController.display.video(filename, 0, True)
|
||||
self.resetAction.setVisible(True)
|
||||
else:
|
||||
criticalErrorMessageBox(translate('MediaPlugin.MediaItem',
|
||||
critical_error_message_box(translate('MediaPlugin.MediaItem',
|
||||
'Live Background Error'),
|
||||
unicode(translate('MediaPlugin.MediaItem',
|
||||
'There was a problem replacing your background, '
|
||||
@ -126,26 +125,34 @@ class MediaMediaItem(MediaManagerItem):
|
||||
return False
|
||||
filename = unicode(item.data(QtCore.Qt.UserRole).toString())
|
||||
if os.path.exists(filename):
|
||||
self.MediaState = None
|
||||
self.mediaObject.stop()
|
||||
self.mediaObject.clearQueue()
|
||||
self.mediaObject.setCurrentSource(Phonon.MediaSource(filename))
|
||||
self.mediaObject.play()
|
||||
service_item.title = unicode(
|
||||
translate('MediaPlugin.MediaItem', 'Media'))
|
||||
service_item.add_capability(ItemCapabilities.RequiresMedia)
|
||||
service_item.add_capability(ItemCapabilities.AllowsVarableStartTime)
|
||||
# force a nonexistent theme
|
||||
service_item.theme = -1
|
||||
frame = u':/media/image_clapperboard.png'
|
||||
(path, name) = os.path.split(filename)
|
||||
while not self.MediaState:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
service_item.media_length = self.mediaLength
|
||||
service_item.add_from_command(path, name, frame)
|
||||
return True
|
||||
else:
|
||||
# File is no longer present
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('MediaPlugin.MediaItem', 'Missing Media File'),
|
||||
unicode(translate('MediaPlugin.MediaItem',
|
||||
'The file %s no longer exists.')) % filename)
|
||||
return False
|
||||
|
||||
def initialise(self):
|
||||
self.listView.setSelectionMode(
|
||||
QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.listView.clear()
|
||||
self.listView.setIconSize(QtCore.QSize(88, 50))
|
||||
self.loadList(SettingsManager.load_list(self.settingsSection,
|
||||
self.settingsSection))
|
||||
@ -171,3 +178,12 @@ class MediaMediaItem(MediaManagerItem):
|
||||
item_name.setIcon(build_icon(img))
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
||||
self.listView.addItem(item_name)
|
||||
|
||||
def videoStart(self, newState, oldState):
|
||||
"""
|
||||
Start the video at a predetermined point.
|
||||
"""
|
||||
if newState == Phonon.PlayingState:
|
||||
self.MediaState = newState
|
||||
self.mediaLength = self.mediaObject.totalTime()/1000
|
||||
self.mediaObject.stop()
|
||||
|
@ -32,8 +32,8 @@ class MediaTab(SettingsTab):
|
||||
"""
|
||||
MediaTab is the Media settings tab in the settings dialog.
|
||||
"""
|
||||
def __init__(self, title):
|
||||
SettingsTab.__init__(self, title)
|
||||
def __init__(self, title, visible_title):
|
||||
SettingsTab.__init__(self, title, visible_title)
|
||||
|
||||
def setupUi(self):
|
||||
self.setObjectName(u'MediaTab')
|
||||
@ -53,9 +53,8 @@ class MediaTab(SettingsTab):
|
||||
self.onUsePhononCheckBoxChanged)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.tabTitleVisible = translate('MediaPlugin.MediaTab', 'Media')
|
||||
self.mediaModeGroupBox.setTitle(translate('MediaPlugin.MediaTab',
|
||||
'Media Display'))
|
||||
self.mediaModeGroupBox.setTitle(
|
||||
translate('MediaPlugin.MediaTab', 'Media Display'))
|
||||
self.usePhononCheckBox.setText(
|
||||
translate('MediaPlugin.MediaTab', 'Use Phonon for video playback'))
|
||||
|
||||
|
@ -38,7 +38,8 @@ class MediaPlugin(Plugin):
|
||||
log.info(u'%s MediaPlugin loaded', __name__)
|
||||
|
||||
def __init__(self, plugin_helpers):
|
||||
Plugin.__init__(self, u'Media', u'1.9.4', plugin_helpers)
|
||||
Plugin.__init__(self, u'Media', u'1.9.4', plugin_helpers,
|
||||
MediaMediaItem, MediaTab)
|
||||
self.weight = -6
|
||||
self.icon_path = u':/plugins/plugin_media.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
@ -75,13 +76,6 @@ class MediaPlugin(Plugin):
|
||||
mimetype = u''
|
||||
return list, mimetype
|
||||
|
||||
def getSettingsTab(self):
|
||||
return MediaTab(self.name)
|
||||
|
||||
def getMediaManagerItem(self):
|
||||
# Create the MediaManagerItem object.
|
||||
return MediaMediaItem(self, self, self.icon)
|
||||
|
||||
def about(self):
|
||||
about_text = translate('MediaPlugin', '<strong>Media Plugin</strong>'
|
||||
'<br />The media plugin provides playback of audio and video.')
|
||||
@ -101,45 +95,15 @@ class MediaPlugin(Plugin):
|
||||
u'title': translate('MediaPlugin', 'Media', 'container title')
|
||||
}
|
||||
# Middle Header Bar
|
||||
## Load Action ##
|
||||
self.textStrings[StringContent.Load] = {
|
||||
u'title': translate('MediaPlugin', 'Load'),
|
||||
u'tooltip': translate('MediaPlugin',
|
||||
'Load a new Media')
|
||||
}
|
||||
## New Action ##
|
||||
self.textStrings[StringContent.New] = {
|
||||
u'title': translate('MediaPlugin', 'Add'),
|
||||
u'tooltip': translate('MediaPlugin',
|
||||
'Add a new Media')
|
||||
}
|
||||
## Edit Action ##
|
||||
self.textStrings[StringContent.Edit] = {
|
||||
u'title': translate('MediaPlugin', 'Edit'),
|
||||
u'tooltip': translate('MediaPlugin',
|
||||
'Edit the selected Media')
|
||||
}
|
||||
## Delete Action ##
|
||||
self.textStrings[StringContent.Delete] = {
|
||||
u'title': translate('MediaPlugin', 'Delete'),
|
||||
u'tooltip': translate('MediaPlugin',
|
||||
'Delete the selected Media')
|
||||
}
|
||||
## Preview Action ##
|
||||
self.textStrings[StringContent.Preview] = {
|
||||
u'title': translate('MediaPlugin', 'Preview'),
|
||||
u'tooltip': translate('MediaPlugin',
|
||||
'Preview the selected Media')
|
||||
}
|
||||
## Send Live Action ##
|
||||
self.textStrings[StringContent.Live] = {
|
||||
u'title': translate('MediaPlugin', 'Live'),
|
||||
u'tooltip': translate('MediaPlugin',
|
||||
'Send the selected Media live')
|
||||
}
|
||||
## Add to Service Action ##
|
||||
self.textStrings[StringContent.Service] = {
|
||||
u'title': translate('MediaPlugin', 'Service'),
|
||||
u'tooltip': translate('MediaPlugin',
|
||||
tooltips = {
|
||||
u'load': translate('MediaPlugin', 'Load a new Media'),
|
||||
u'import': u'',
|
||||
u'new': translate('MediaPlugin', 'Add a new Media'),
|
||||
u'edit': translate('MediaPlugin', 'Edit the selected Media'),
|
||||
u'delete': translate('MediaPlugin', 'Delete the selected Media'),
|
||||
u'preview': translate('MediaPlugin', 'Preview the selected Media'),
|
||||
u'live': translate('MediaPlugin', 'Send the selected Media live'),
|
||||
u'service': translate('MediaPlugin',
|
||||
'Add the selected Media to the service')
|
||||
}
|
||||
self.setPluginUiTextStrings(tooltips)
|
||||
|
@ -69,7 +69,8 @@ class ImpressController(PresentationController):
|
||||
Initialise the class
|
||||
"""
|
||||
log.debug(u'Initialising')
|
||||
PresentationController.__init__(self, plugin, u'Impress')
|
||||
PresentationController.__init__(self, plugin, u'Impress',
|
||||
ImpressDocument)
|
||||
self.supports = [u'odp']
|
||||
self.alsosupports = [u'ppt', u'pps', u'pptx', u'ppsx']
|
||||
self.process = None
|
||||
@ -144,7 +145,12 @@ class ImpressController(PresentationController):
|
||||
log.debug(u'get COM Desktop OpenOffice')
|
||||
if not self.manager:
|
||||
return None
|
||||
return self.manager.createInstance(u'com.sun.star.frame.Desktop')
|
||||
desktop = None
|
||||
try:
|
||||
desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
|
||||
except AttributeError:
|
||||
log.exception(u'Failure to find desktop - Impress may have closed')
|
||||
return desktop if desktop else None
|
||||
|
||||
def get_com_servicemanager(self):
|
||||
"""
|
||||
@ -165,17 +171,19 @@ class ImpressController(PresentationController):
|
||||
log.debug(u'Kill OpenOffice')
|
||||
while self.docs:
|
||||
self.docs[0].close_presentation()
|
||||
if os.name != u'nt':
|
||||
desktop = self.get_uno_desktop()
|
||||
else:
|
||||
desktop = self.get_com_desktop()
|
||||
#Sometimes we get a failure and desktop is None
|
||||
desktop = None
|
||||
try:
|
||||
if os.name != u'nt':
|
||||
desktop = self.get_uno_desktop()
|
||||
else:
|
||||
desktop = self.get_com_desktop()
|
||||
except:
|
||||
log.exception(u'Failed to find an OpenOffice desktop to terminate')
|
||||
if not desktop:
|
||||
log.exception(u'Failed to terminate OpenOffice')
|
||||
return
|
||||
docs = desktop.getComponents()
|
||||
if docs.hasElements():
|
||||
log.debug(u'OpenOffice not terminated')
|
||||
log.debug(u'OpenOffice not terminated as docs are still open')
|
||||
else:
|
||||
try:
|
||||
desktop.terminate()
|
||||
@ -183,14 +191,6 @@ class ImpressController(PresentationController):
|
||||
except:
|
||||
log.exception(u'Failed to terminate OpenOffice')
|
||||
|
||||
def add_doc(self, name):
|
||||
"""
|
||||
Called when a new Impress document is opened
|
||||
"""
|
||||
log.debug(u'Add Doc OpenOffice')
|
||||
doc = ImpressDocument(self, name)
|
||||
self.docs.append(doc)
|
||||
return doc
|
||||
|
||||
class ImpressDocument(PresentationDocument):
|
||||
"""
|
||||
@ -431,35 +431,36 @@ class ImpressDocument(PresentationDocument):
|
||||
|
||||
def get_slide_text(self, slide_no):
|
||||
"""
|
||||
Returns the text on the slide
|
||||
Returns the text on the slide.
|
||||
|
||||
``slide_no``
|
||||
The slide the text is required for, starting at 1
|
||||
The slide the text is required for, starting at 1
|
||||
"""
|
||||
return self.__get_text_from_page(slide_no)
|
||||
|
||||
def get_slide_notes(self, slide_no):
|
||||
"""
|
||||
Returns the text in the slide notes.
|
||||
|
||||
``slide_no``
|
||||
The slide the notes are required for, starting at 1
|
||||
"""
|
||||
return self.__get_text_from_page(slide_no, True)
|
||||
|
||||
def __get_text_from_page(self, slide_no, notes=False):
|
||||
"""
|
||||
Return any text extracted from the presentation page.
|
||||
|
||||
``notes``
|
||||
A boolean. If set the method searches the notes of the slide.
|
||||
"""
|
||||
doc = self.document
|
||||
pages = doc.getDrawPages()
|
||||
text = ''
|
||||
pages = self.document.getDrawPages()
|
||||
page = pages.getByIndex(slide_no - 1)
|
||||
if notes:
|
||||
page = page.getNotesPage()
|
||||
for idx in range(page.getCount()):
|
||||
shape = page.getByIndex(idx)
|
||||
if shape.supportsService("com.sun.star.drawing.Text"):
|
||||
text += shape.getString() + '\n'
|
||||
return text
|
||||
|
||||
def get_slide_notes(self, slide_no):
|
||||
"""
|
||||
Returns the text on the slide
|
||||
|
||||
``slide_no``
|
||||
The slide the notes are required for, starting at 1
|
||||
"""
|
||||
doc = self.document
|
||||
pages = doc.getDrawPages()
|
||||
text = ''
|
||||
page = pages.getByIndex(slide_no - 1)
|
||||
notes = page.getNotesPage()
|
||||
for idx in range(notes.getCount()):
|
||||
shape = notes.getByIndex(idx)
|
||||
if shape.supportsService("com.sun.star.drawing.Text"):
|
||||
text += shape.getString() + '\n'
|
||||
return text
|
||||
|
@ -29,24 +29,13 @@ import os
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
|
||||
SettingsManager, translate, check_item_selected, Receiver, ItemCapabilities
|
||||
from openlp.core.ui import criticalErrorMessageBox
|
||||
from openlp.core.lib import MediaManagerItem, build_icon, SettingsManager, \
|
||||
translate, check_item_selected, Receiver, ItemCapabilities
|
||||
from openlp.core.lib.ui import critical_error_message_box, media_item_combo_box
|
||||
from openlp.plugins.presentations.lib import MessageListener
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class PresentationListView(BaseListWithDnD):
|
||||
"""
|
||||
Class for the list of Presentations
|
||||
|
||||
We have to explicitly create separate classes for each plugin
|
||||
in order for DnD to the Service manager to work correctly.
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
self.PluginName = u'Presentations'
|
||||
BaseListWithDnD.__init__(self, parent)
|
||||
|
||||
class PresentationMediaItem(MediaManagerItem):
|
||||
"""
|
||||
This is the Presentation media manager item for Presentation Items.
|
||||
@ -61,9 +50,6 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
self.controllers = controllers
|
||||
self.IconPath = u'presentations/presentation'
|
||||
self.Automatic = u''
|
||||
# this next is a class, not an instance of a class - it will
|
||||
# be instanced by the base MediaManagerItem
|
||||
self.ListViewWithDnD_class = PresentationListView
|
||||
MediaManagerItem.__init__(self, parent, self, icon)
|
||||
self.message_listener = MessageListener(self)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
@ -116,12 +102,8 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
self.displayLayout.setObjectName(u'displayLayout')
|
||||
self.displayTypeLabel = QtGui.QLabel(self.presentationWidget)
|
||||
self.displayTypeLabel.setObjectName(u'displayTypeLabel')
|
||||
self.displayTypeComboBox = QtGui.QComboBox(self.presentationWidget)
|
||||
self.displayTypeComboBox.setSizeAdjustPolicy(
|
||||
QtGui.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.displayTypeComboBox.setSizePolicy(
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.displayTypeComboBox.setObjectName(u'displayTypeComboBox')
|
||||
self.displayTypeComboBox = media_item_combo_box(
|
||||
self.presentationWidget, u'displayTypeComboBox')
|
||||
self.displayTypeLabel.setBuddy(self.displayTypeComboBox)
|
||||
self.displayLayout.addRow(self.displayTypeLabel,
|
||||
self.displayTypeComboBox)
|
||||
@ -181,7 +163,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
filename = os.path.split(unicode(file))[1]
|
||||
if titles.count(filename) > 0:
|
||||
if not initialLoad:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
'File Exists'),
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
@ -190,7 +172,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
controller_name = self.findControllerByType(filename)
|
||||
if controller_name:
|
||||
controller = self.controllers[controller_name]
|
||||
doc = controller.add_doc(unicode(file))
|
||||
doc = controller.add_document(unicode(file))
|
||||
thumb = os.path.join(doc.get_thumbnail_folder(), u'icon.png')
|
||||
preview = doc.get_thumbnail_path(1, True)
|
||||
if not preview and not initialLoad:
|
||||
@ -205,7 +187,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
if initialLoad:
|
||||
icon = build_icon(u':/general/general_delete.png')
|
||||
else:
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
self, translate('PresentationPlugin.MediaItem',
|
||||
'Unsupported File'),
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
@ -230,7 +212,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
filepath = unicode(item.data(
|
||||
QtCore.Qt.UserRole).toString())
|
||||
for cidx in self.controllers:
|
||||
doc = self.controllers[cidx].add_doc(filepath)
|
||||
doc = self.controllers[cidx].add_document(filepath)
|
||||
doc.presentation_deleted()
|
||||
doc.close_presentation()
|
||||
for row in row_list:
|
||||
@ -250,6 +232,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
service_item.title = unicode(self.displayTypeComboBox.currentText())
|
||||
service_item.shortname = unicode(self.displayTypeComboBox.currentText())
|
||||
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
|
||||
service_item.add_capability(ItemCapabilities.AllowsDetailedTitleDisplay)
|
||||
shortname = service_item.shortname
|
||||
if shortname:
|
||||
for item in items:
|
||||
@ -263,7 +246,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
return False
|
||||
controller = self.controllers[service_item.shortname]
|
||||
(path, name) = os.path.split(filename)
|
||||
doc = controller.add_doc(filename)
|
||||
doc = controller.add_document(filename)
|
||||
if doc.get_thumbnail_path(1, True) is None:
|
||||
doc.load_presentation()
|
||||
i = 1
|
||||
@ -277,7 +260,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
return True
|
||||
else:
|
||||
# File is no longer present
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
'Missing Presentation'),
|
||||
unicode(translate('PresentationPlugin.MediaItem',
|
||||
@ -286,7 +269,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
return False
|
||||
else:
|
||||
# File is no longer present
|
||||
criticalErrorMessageBox(
|
||||
critical_error_message_box(
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
'Missing Presentation'),
|
||||
unicode(translate('PresentationPlugin.MediaItem',
|
||||
|
@ -59,7 +59,7 @@ class Controller(object):
|
||||
self.controller = controller
|
||||
if self.doc is not None:
|
||||
self.shutdown()
|
||||
self.doc = self.controller.add_doc(file)
|
||||
self.doc = self.controller.add_document(file)
|
||||
if not self.doc.load_presentation():
|
||||
# Display error message to user
|
||||
# Inform slidecontroller that the action failed?
|
||||
@ -116,7 +116,7 @@ class Controller(object):
|
||||
|
||||
def last(self):
|
||||
"""
|
||||
Based on the handler passed at startup triggers the first slide
|
||||
Based on the handler passed at startup triggers the last slide
|
||||
"""
|
||||
log.debug(u'Live = %s, last' % self.is_live)
|
||||
if not self.is_live:
|
||||
|
@ -53,7 +53,8 @@ class PowerpointController(PresentationController):
|
||||
Initialise the class
|
||||
"""
|
||||
log.debug(u'Initialising')
|
||||
PresentationController.__init__(self, plugin, u'Powerpoint')
|
||||
PresentationController.__init__(self, plugin, u'Powerpoint',
|
||||
PowerpointDocument)
|
||||
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
|
||||
self.process = None
|
||||
|
||||
@ -97,14 +98,6 @@ class PowerpointController(PresentationController):
|
||||
pass
|
||||
self.process = None
|
||||
|
||||
def add_doc(self, name):
|
||||
"""
|
||||
Called when a new powerpoint document is opened
|
||||
"""
|
||||
log.debug(u'Add Doc PowerPoint')
|
||||
doc = PowerpointDocument(self, name)
|
||||
self.docs.append(doc)
|
||||
return doc
|
||||
|
||||
class PowerpointDocument(PresentationDocument):
|
||||
"""
|
||||
@ -154,8 +147,10 @@ class PowerpointDocument(PresentationDocument):
|
||||
"""
|
||||
if self.check_thumbnails():
|
||||
return
|
||||
self.presentation.Export(os.path.join(self.get_thumbnail_folder(), ''),
|
||||
'png', 320, 240)
|
||||
for num in range(0, self.presentation.Slides.Count):
|
||||
self.presentation.Slides(num + 1).Export(os.path.join(
|
||||
self.get_thumbnail_folder(), 'slide%d.png' % (num + 1)),
|
||||
'png', 320, 240)
|
||||
|
||||
def close_presentation(self):
|
||||
"""
|
||||
@ -291,13 +286,7 @@ class PowerpointDocument(PresentationDocument):
|
||||
``slide_no``
|
||||
The slide the text is required for, starting at 1.
|
||||
"""
|
||||
text = ''
|
||||
shapes = self.presentation.Slides(slide_no).Shapes
|
||||
for idx in range(shapes.Count):
|
||||
shape = shapes(idx + 1)
|
||||
if shape.HasTextFrame:
|
||||
text += shape.TextFrame.TextRange.Text + '\n'
|
||||
return text
|
||||
return _get_text_from_shapes(self.presentation.Slides(slide_no).Shapes)
|
||||
|
||||
def get_slide_notes(self, slide_no):
|
||||
"""
|
||||
@ -306,10 +295,19 @@ class PowerpointDocument(PresentationDocument):
|
||||
``slide_no``
|
||||
The slide the notes are required for, starting at 1.
|
||||
"""
|
||||
text = ''
|
||||
shapes = self.presentation.Slides(slide_no).NotesPage.Shapes
|
||||
for idx in range(shapes.Count):
|
||||
shape = shapes(idx + 1)
|
||||
if shape.HasTextFrame:
|
||||
text += shape.TextFrame.TextRange.Text + '\n'
|
||||
return text
|
||||
return _get_text_from_shapes(
|
||||
self.presentation.Slides(slide_no).NotesPage.Shapes)
|
||||
|
||||
def _get_text_from_shapes(shapes):
|
||||
"""
|
||||
Returns any text extracted from the shapes on a presentation slide.
|
||||
|
||||
``shapes``
|
||||
A set of shapes to search for text.
|
||||
"""
|
||||
text = ''
|
||||
for idx in range(shapes.Count):
|
||||
shape = shapes(idx + 1)
|
||||
if shape.HasTextFrame:
|
||||
text += shape.TextFrame.TextRange.Text + '\n'
|
||||
return text
|
||||
|
@ -49,7 +49,8 @@ class PptviewController(PresentationController):
|
||||
"""
|
||||
log.debug(u'Initialising')
|
||||
self.process = None
|
||||
PresentationController.__init__(self, plugin, u'Powerpoint Viewer')
|
||||
PresentationController.__init__(self, plugin, u'Powerpoint Viewer',
|
||||
PptviewDocument)
|
||||
self.supports = [u'ppt', u'pps', u'pptx', u'ppsx']
|
||||
|
||||
def check_available(self):
|
||||
@ -93,14 +94,6 @@ class PptviewController(PresentationController):
|
||||
while self.docs:
|
||||
self.docs[0].close_presentation()
|
||||
|
||||
def add_doc(self, name):
|
||||
"""
|
||||
Called when a new powerpoint document is opened
|
||||
"""
|
||||
log.debug(u'Add Doc PPTView')
|
||||
doc = PptviewDocument(self, name)
|
||||
self.docs.append(doc)
|
||||
return doc
|
||||
|
||||
class PptviewDocument(PresentationDocument):
|
||||
"""
|
||||
@ -161,8 +154,9 @@ class PptviewDocument(PresentationDocument):
|
||||
being shut down
|
||||
"""
|
||||
log.debug(u'ClosePresentation')
|
||||
self.controller.process.ClosePPT(self.pptid)
|
||||
self.pptid = -1
|
||||
if self.controller.process:
|
||||
self.controller.process.ClosePPT(self.pptid)
|
||||
self.pptid = -1
|
||||
self.controller.remove_doc(self)
|
||||
|
||||
def is_loaded(self):
|
||||
@ -247,4 +241,4 @@ class PptviewDocument(PresentationDocument):
|
||||
"""
|
||||
Triggers the previous slide on the running presentation
|
||||
"""
|
||||
self.controller.process.PrevStep(self.pptid)
|
||||
self.controller.process.PrevStep(self.pptid)
|
||||
|
@ -35,151 +35,6 @@ from openlp.core.utils import AppLocation
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class PresentationController(object):
|
||||
"""
|
||||
This class is used to control interactions with presentation applications
|
||||
by creating a runtime environment. This is a base class for presentation
|
||||
controllers to inherit from.
|
||||
|
||||
To create a new controller, take a copy of this file and name it so it ends
|
||||
with ``controller.py``, i.e. ``foobarcontroller.py``. Make sure it inherits
|
||||
:class:`~openlp.plugins.presentations.lib.presentationcontroller.PresentationController`,
|
||||
and then fill in the blanks. If possible try to make sure it loads on all
|
||||
platforms, usually by using :mod:``os.name`` checks, although
|
||||
``__init__``, ``check_available`` and ``presentation_deleted`` should
|
||||
always be implemented.
|
||||
|
||||
See :class:`~openlp.plugins.presentations.lib.impresscontroller.ImpressController`,
|
||||
:class:`~openlp.plugins.presentations.lib.powerpointcontroller.PowerpointController` or
|
||||
:class:`~openlp.plugins.presentations.lib.pptviewcontroller.PptviewController`
|
||||
for examples.
|
||||
|
||||
**Basic Attributes**
|
||||
|
||||
``name``
|
||||
The name that appears in the options and the media manager
|
||||
|
||||
``enabled``
|
||||
The controller is enabled
|
||||
|
||||
``available``
|
||||
The controller is available on this machine. Set by init via
|
||||
call to check_available
|
||||
|
||||
``plugin``
|
||||
The presentationplugin object
|
||||
|
||||
``supports``
|
||||
The primary native file types this application supports
|
||||
|
||||
``alsosupports``
|
||||
Other file types the application can import, although not necessarily
|
||||
the first choice due to potential incompatibilities
|
||||
|
||||
**Hook Functions**
|
||||
|
||||
``kill()``
|
||||
Called at system exit to clean up any running presentations
|
||||
|
||||
``check_available()``
|
||||
Returns True if presentation application is installed/can run on this
|
||||
machine
|
||||
|
||||
``presentation_deleted()``
|
||||
Deletes presentation specific files, e.g. thumbnails
|
||||
|
||||
"""
|
||||
log.info(u'PresentationController loaded')
|
||||
|
||||
def __init__(self, plugin=None, name=u'PresentationController'):
|
||||
"""
|
||||
This is the constructor for the presentationcontroller object. This
|
||||
provides an easy way for descendent plugins to populate common data.
|
||||
This method *must* be overridden, like so::
|
||||
|
||||
class MyPresentationController(PresentationController):
|
||||
def __init__(self, plugin):
|
||||
PresentationController.__init(
|
||||
self, plugin, u'My Presenter App')
|
||||
|
||||
``plugin``
|
||||
Defaults to *None*. The presentationplugin object
|
||||
|
||||
``name``
|
||||
Name of the application, to appear in the application
|
||||
"""
|
||||
self.supports = []
|
||||
self.alsosupports = []
|
||||
self.docs = []
|
||||
self.plugin = plugin
|
||||
self.name = name
|
||||
self.settings_section = self.plugin.settingsSection
|
||||
self.available = self.check_available()
|
||||
self.temp_folder = os.path.join(
|
||||
AppLocation.get_section_data_path(self.settings_section), name)
|
||||
self.thumbnail_folder = os.path.join(
|
||||
AppLocation.get_section_data_path(self.settings_section),
|
||||
u'thumbnails')
|
||||
self.thumbnail_prefix = u'slide'
|
||||
if not os.path.isdir(self.thumbnail_folder):
|
||||
os.makedirs(self.thumbnail_folder)
|
||||
if not os.path.isdir(self.temp_folder):
|
||||
os.makedirs(self.temp_folder)
|
||||
|
||||
def enabled(self):
|
||||
"""
|
||||
Return whether the controller is currently enabled
|
||||
"""
|
||||
if self.available:
|
||||
return QtCore.QSettings().value(
|
||||
self.settings_section + u'/' + self.name,
|
||||
QtCore.QVariant(QtCore.Qt.Checked)).toInt()[0] == \
|
||||
QtCore.Qt.Checked
|
||||
else:
|
||||
return False
|
||||
|
||||
def check_available(self):
|
||||
"""
|
||||
Presentation app is able to run on this machine
|
||||
"""
|
||||
return False
|
||||
|
||||
def start_process(self):
|
||||
"""
|
||||
Loads a running version of the presentation application in the
|
||||
background.
|
||||
"""
|
||||
pass
|
||||
|
||||
def kill(self):
|
||||
"""
|
||||
Called at system exit to clean up any running presentations and
|
||||
close the application
|
||||
"""
|
||||
log.debug(u'Kill')
|
||||
self.close_presentation()
|
||||
|
||||
def add_doc(self, name):
|
||||
"""
|
||||
Called when a new presentation document is opened
|
||||
"""
|
||||
doc = PresentationDocument(self, name)
|
||||
self.docs.append(doc)
|
||||
return doc
|
||||
|
||||
def remove_doc(self, doc=None):
|
||||
"""
|
||||
Called to remove an open document from the collection
|
||||
"""
|
||||
log.debug(u'remove_doc Presentation')
|
||||
if doc is None:
|
||||
return
|
||||
if doc in self.docs:
|
||||
self.docs.remove(doc)
|
||||
|
||||
def close_presentation(self):
|
||||
pass
|
||||
|
||||
class PresentationDocument(object):
|
||||
"""
|
||||
Base class for presentation documents to inherit from.
|
||||
@ -440,4 +295,152 @@ class PresentationDocument(object):
|
||||
``slide_no``
|
||||
The slide the notes are required for, starting at 1
|
||||
"""
|
||||
return ''
|
||||
return ''
|
||||
|
||||
|
||||
class PresentationController(object):
|
||||
"""
|
||||
This class is used to control interactions with presentation applications
|
||||
by creating a runtime environment. This is a base class for presentation
|
||||
controllers to inherit from.
|
||||
|
||||
To create a new controller, take a copy of this file and name it so it ends
|
||||
with ``controller.py``, i.e. ``foobarcontroller.py``. Make sure it inherits
|
||||
:class:`~openlp.plugins.presentations.lib.presentationcontroller.PresentationController`,
|
||||
and then fill in the blanks. If possible try to make sure it loads on all
|
||||
platforms, usually by using :mod:``os.name`` checks, although
|
||||
``__init__``, ``check_available`` and ``presentation_deleted`` should
|
||||
always be implemented.
|
||||
|
||||
See :class:`~openlp.plugins.presentations.lib.impresscontroller.ImpressController`,
|
||||
:class:`~openlp.plugins.presentations.lib.powerpointcontroller.PowerpointController` or
|
||||
:class:`~openlp.plugins.presentations.lib.pptviewcontroller.PptviewController`
|
||||
for examples.
|
||||
|
||||
**Basic Attributes**
|
||||
|
||||
``name``
|
||||
The name that appears in the options and the media manager
|
||||
|
||||
``enabled``
|
||||
The controller is enabled
|
||||
|
||||
``available``
|
||||
The controller is available on this machine. Set by init via
|
||||
call to check_available
|
||||
|
||||
``plugin``
|
||||
The presentationplugin object
|
||||
|
||||
``supports``
|
||||
The primary native file types this application supports
|
||||
|
||||
``alsosupports``
|
||||
Other file types the application can import, although not necessarily
|
||||
the first choice due to potential incompatibilities
|
||||
|
||||
**Hook Functions**
|
||||
|
||||
``kill()``
|
||||
Called at system exit to clean up any running presentations
|
||||
|
||||
``check_available()``
|
||||
Returns True if presentation application is installed/can run on this
|
||||
machine
|
||||
|
||||
``presentation_deleted()``
|
||||
Deletes presentation specific files, e.g. thumbnails
|
||||
|
||||
"""
|
||||
log.info(u'PresentationController loaded')
|
||||
|
||||
def __init__(self, plugin=None, name=u'PresentationController',
|
||||
document_class=PresentationDocument):
|
||||
"""
|
||||
This is the constructor for the presentationcontroller object. This
|
||||
provides an easy way for descendent plugins to populate common data.
|
||||
This method *must* be overridden, like so::
|
||||
|
||||
class MyPresentationController(PresentationController):
|
||||
def __init__(self, plugin):
|
||||
PresentationController.__init(
|
||||
self, plugin, u'My Presenter App')
|
||||
|
||||
``plugin``
|
||||
Defaults to *None*. The presentationplugin object
|
||||
|
||||
``name``
|
||||
Name of the application, to appear in the application
|
||||
"""
|
||||
self.supports = []
|
||||
self.alsosupports = []
|
||||
self.docs = []
|
||||
self.plugin = plugin
|
||||
self.name = name
|
||||
self.document_class = document_class
|
||||
self.settings_section = self.plugin.settingsSection
|
||||
self.available = self.check_available()
|
||||
self.temp_folder = os.path.join(
|
||||
AppLocation.get_section_data_path(self.settings_section), name)
|
||||
self.thumbnail_folder = os.path.join(
|
||||
AppLocation.get_section_data_path(self.settings_section),
|
||||
u'thumbnails')
|
||||
self.thumbnail_prefix = u'slide'
|
||||
if not os.path.isdir(self.thumbnail_folder):
|
||||
os.makedirs(self.thumbnail_folder)
|
||||
if not os.path.isdir(self.temp_folder):
|
||||
os.makedirs(self.temp_folder)
|
||||
|
||||
def enabled(self):
|
||||
"""
|
||||
Return whether the controller is currently enabled
|
||||
"""
|
||||
if self.available:
|
||||
return QtCore.QSettings().value(
|
||||
self.settings_section + u'/' + self.name,
|
||||
QtCore.QVariant(QtCore.Qt.Checked)).toInt()[0] == \
|
||||
QtCore.Qt.Checked
|
||||
else:
|
||||
return False
|
||||
|
||||
def check_available(self):
|
||||
"""
|
||||
Presentation app is able to run on this machine
|
||||
"""
|
||||
return False
|
||||
|
||||
def start_process(self):
|
||||
"""
|
||||
Loads a running version of the presentation application in the
|
||||
background.
|
||||
"""
|
||||
pass
|
||||
|
||||
def kill(self):
|
||||
"""
|
||||
Called at system exit to clean up any running presentations and
|
||||
close the application
|
||||
"""
|
||||
log.debug(u'Kill')
|
||||
self.close_presentation()
|
||||
|
||||
def add_document(self, name):
|
||||
"""
|
||||
Called when a new presentation document is opened
|
||||
"""
|
||||
document = self.document_class(self, name)
|
||||
self.docs.append(document)
|
||||
return document
|
||||
|
||||
def remove_doc(self, doc=None):
|
||||
"""
|
||||
Called to remove an open document from the collection
|
||||
"""
|
||||
log.debug(u'remove_doc Presentation')
|
||||
if doc is None:
|
||||
return
|
||||
if doc in self.docs:
|
||||
self.docs.remove(doc)
|
||||
|
||||
def close_presentation(self):
|
||||
pass
|
||||
|
@ -27,6 +27,7 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, SettingsTab, translate
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
||||
class PresentationTab(SettingsTab):
|
||||
"""
|
||||
@ -85,9 +86,7 @@ class PresentationTab(SettingsTab):
|
||||
checkbox.setText(
|
||||
unicode(translate('PresentationPlugin.PresentationTab',
|
||||
'%s (unvailable)')) % controller.name)
|
||||
self.AdvancedGroupBox.setTitle(
|
||||
translate('PresentationPlugin.PresentationTab',
|
||||
'Advanced'))
|
||||
self.AdvancedGroupBox.setTitle(UiStrings.Advanced)
|
||||
self.OverrideAppCheckBox.setText(
|
||||
translate('PresentationPlugin.PresentationTab',
|
||||
'Allow presentation application to be overriden'))
|
||||
|
@ -74,7 +74,11 @@ class PresentationPlugin(Plugin):
|
||||
self.insertToolboxItem()
|
||||
for controller in self.controllers:
|
||||
if self.controllers[controller].enabled():
|
||||
self.controllers[controller].start_process()
|
||||
try:
|
||||
self.controllers[controller].start_process()
|
||||
except:
|
||||
log.exception(u'Failed to start controller process')
|
||||
self.controllers[controller].available = False
|
||||
self.mediaItem.buildFileMaskString()
|
||||
|
||||
def finalise(self):
|
||||
@ -163,33 +167,18 @@ class PresentationPlugin(Plugin):
|
||||
'container title')
|
||||
}
|
||||
# Middle Header Bar
|
||||
## Load Action ##
|
||||
self.textStrings[StringContent.Load] = {
|
||||
u'title': translate('PresentationPlugin', 'Load'),
|
||||
u'tooltip': translate('PresentationPlugin',
|
||||
'Load a new Presentation')
|
||||
}
|
||||
## Delete Action ##
|
||||
self.textStrings[StringContent.Delete] = {
|
||||
u'title': translate('PresentationPlugin', 'Delete'),
|
||||
u'tooltip': translate('PresentationPlugin',
|
||||
'Delete the selected Presentation')
|
||||
}
|
||||
## Preview Action ##
|
||||
self.textStrings[StringContent.Preview] = {
|
||||
u'title': translate('PresentationPlugin', 'Preview'),
|
||||
u'tooltip': translate('PresentationPlugin',
|
||||
'Preview the selected Presentation')
|
||||
}
|
||||
## Send Live Action ##
|
||||
self.textStrings[StringContent.Live] = {
|
||||
u'title': translate('PresentationPlugin', 'Live'),
|
||||
u'tooltip': translate('PresentationPlugin',
|
||||
'Send the selected Presentation live')
|
||||
}
|
||||
## Add to Service Action ##
|
||||
self.textStrings[StringContent.Service] = {
|
||||
u'title': translate('PresentationPlugin', 'Service'),
|
||||
u'tooltip': translate('PresentationPlugin',
|
||||
tooltips = {
|
||||
u'load': translate('PresentationPlugin', 'Load a new Presentation'),
|
||||
u'import': u'',
|
||||
u'new': u'',
|
||||
u'edit': u'',
|
||||
u'delete': translate('PresentationPlugin',
|
||||
'Delete the selected Presentation'),
|
||||
u'preview': translate('PresentationPlugin',
|
||||
'Preview the selected Presentation'),
|
||||
u'live': translate('PresentationPlugin',
|
||||
'Send the selected Presentation live'),
|
||||
u'service': translate('PresentationPlugin',
|
||||
'Add the selected Presentation to the service')
|
||||
}
|
||||
self.setPluginUiTextStrings(tooltips)
|
||||
|
@ -38,7 +38,8 @@ class RemotesPlugin(Plugin):
|
||||
"""
|
||||
remotes constructor
|
||||
"""
|
||||
Plugin.__init__(self, u'Remotes', u'1.9.4', plugin_helpers)
|
||||
Plugin.__init__(self, u'Remotes', u'1.9.4', plugin_helpers,
|
||||
settingsTabClass=RemoteTab)
|
||||
self.icon = build_icon(u':/plugins/plugin_remote.png')
|
||||
self.weight = -1
|
||||
self.server = None
|
||||
@ -61,13 +62,6 @@ class RemotesPlugin(Plugin):
|
||||
if self.server:
|
||||
self.server.close()
|
||||
|
||||
def getSettingsTab(self):
|
||||
"""
|
||||
Create the settings Tab
|
||||
"""
|
||||
visible_name = self.getString(StringContent.VisibleName)
|
||||
return RemoteTab(self.name, visible_name[u'title'])
|
||||
|
||||
def about(self):
|
||||
"""
|
||||
Information about this plugin
|
||||
|
@ -57,4 +57,6 @@ from songbookform import SongBookForm
|
||||
from editverseform import EditVerseForm
|
||||
from editsongform import EditSongForm
|
||||
from songmaintenanceform import SongMaintenanceForm
|
||||
from songimportform import SongImportForm
|
||||
from songimportform import SongImportForm
|
||||
from songexportform import SongExportForm
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import create_accept_reject_button_box
|
||||
|
||||
class Ui_AuthorsDialog(object):
|
||||
def setupUi(self, authorsDialog):
|
||||
@ -55,17 +56,10 @@ class Ui_AuthorsDialog(object):
|
||||
self.displayLabel.setBuddy(self.displayEdit)
|
||||
self.authorLayout.addRow(self.displayLabel, self.displayEdit)
|
||||
self.dialogLayout.addLayout(self.authorLayout)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(authorsDialog)
|
||||
self.buttonBox.setStandardButtons(
|
||||
QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.dialogLayout.addWidget(self.buttonBox)
|
||||
self.dialogLayout.addWidget(
|
||||
create_accept_reject_button_box(authorsDialog))
|
||||
self.retranslateUi(authorsDialog)
|
||||
authorsDialog.setMaximumHeight(authorsDialog.sizeHint().height())
|
||||
QtCore.QObject.connect(self.buttonBox,
|
||||
QtCore.SIGNAL(u'accepted()'), authorsDialog.accept)
|
||||
QtCore.QObject.connect(self.buttonBox,
|
||||
QtCore.SIGNAL(u'rejected()'), authorsDialog.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(authorsDialog)
|
||||
|
||||
def retranslateUi(self, authorsDialog):
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user