r1500
@ -21,20 +21,35 @@ You will see the Bible Importer window, click :guilabel:`Next`.
|
|||||||
|
|
||||||
.. image:: pics/bibleimport01.png
|
.. image:: pics/bibleimport01.png
|
||||||
|
|
||||||
After clicking :guilabel:`Next` you can select from the various types of
|
After clicking :guilabel:`Next` you can select from the various types of
|
||||||
software that OpenLP will convert Bibles from.
|
software that OpenLP will convert Bibles from. Click on the file folder icon to
|
||||||
|
choose the file(s) of the Bible database you want to import. See the sections
|
||||||
|
below for more information on the different formats that OpenLP will import.
|
||||||
|
Click :guilabel:`Next` to continue.
|
||||||
|
|
||||||
.. image:: pics/bibleimport02.png
|
.. image:: pics/bibleimport02.png
|
||||||
|
|
||||||
Click on the file folder icon to choose the file of the Bible database you
|
After selecting your file(s), you'll be asked to fill in the details of the
|
||||||
want to import. See the following sections for information on the different
|
Bible you are importing. Remember to check what information you need to display
|
||||||
formats that OpenLP will import.
|
for your Bible's translation, as some of them have strict rules around the
|
||||||
|
copyright notice. Click :guilabel:`Next` to continue.
|
||||||
|
|
||||||
Importing from OpenLP Version 1
|
.. image:: pics/bibleimportdetails1.png
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Converting from OpenLP Version 1 is a simple process. First you will need to
|
After filling in the copyright details, OpenLP will start to import your Bible.
|
||||||
locate your Version 1 Bibles.
|
It may take some time to import your Bible so please be patient.
|
||||||
|
|
||||||
|
.. image:: pics/bibleimportfinished1.png
|
||||||
|
|
||||||
|
When the import has finished click :guilabel:`Finish` and you should be
|
||||||
|
ready to use your Bible in OpenLP.
|
||||||
|
|
||||||
|
Importing from openlp.org 1.x
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Importing Bibles from openlp.org 1.x is a simple process. First you will need to
|
||||||
|
locate your version 1.x Bibles. Version 1.x Bibles have the `.bible` file
|
||||||
|
extension.
|
||||||
|
|
||||||
Windows XP::
|
Windows XP::
|
||||||
|
|
||||||
@ -44,22 +59,15 @@ Windows Vista / Windows 7::
|
|||||||
|
|
||||||
C:\ProgramData\openlp.org\Data\Bibles\
|
C:\ProgramData\openlp.org\Data\Bibles\
|
||||||
|
|
||||||
OpenLP Version 1 Bibles have the `.bible` file extension. After selecting
|
After selecting all of the openlp.org 1.x Bibles you want to convert, click
|
||||||
all of the OpenLP Version 1 Bibles you want to convert, click :guilabel:`Next`
|
:guilabel:`Next` to continue the import process.
|
||||||
|
|
||||||
.. image:: pics/bibleimportdetails1.png
|
|
||||||
|
|
||||||
Enter your Bible name and copyright details. Click :guilabel:`Next`. It may
|
|
||||||
take some time to convert your Bibles so please be patient.
|
|
||||||
|
|
||||||
.. image:: pics/bibleimportfinished1.png
|
|
||||||
|
|
||||||
When the import has finished click :guilabel:`Finish` and you should be
|
|
||||||
ready to use your OpenLP Version 1 Bibles.
|
|
||||||
|
|
||||||
Importing OSIS Bibles
|
Importing OSIS Bibles
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Importing OSIS files is very simple. Select OSIS as your import source, select
|
||||||
|
your OSIS Bible file and continue the import process.
|
||||||
|
|
||||||
**About OSIS Formatted Bibles**
|
**About OSIS Formatted Bibles**
|
||||||
|
|
||||||
The OSIS XML standard was designed to provide a common format for distribution
|
The OSIS XML standard was designed to provide a common format for distribution
|
||||||
@ -69,24 +77,11 @@ of electronic Bibles. More information can be found out at the `Bible Technologi
|
|||||||
If you have any software installed that is part of the `Sword Project
|
If you have any software installed that is part of the `Sword Project
|
||||||
<http://www.crosswire.org/sword/index.jsp>`_ it can be easily converted.
|
<http://www.crosswire.org/sword/index.jsp>`_ it can be easily converted.
|
||||||
|
|
||||||
Importing OSIS files is very simple. Select your OSIS Bible file and click
|
|
||||||
:guilabel:`Next`
|
|
||||||
|
|
||||||
.. image:: pics/bibleimportdetails1.png
|
|
||||||
|
|
||||||
Enter you Bible name and copyright details. Click :guilabel:`Next`. It may take
|
|
||||||
some time to convert your Bibles so please be patient.
|
|
||||||
|
|
||||||
.. image:: pics/bibleimportfinished1.png
|
|
||||||
|
|
||||||
Click :guilabel:`Finish` and you should be ready to use your OpenLP Version
|
|
||||||
1 Bibles.
|
|
||||||
|
|
||||||
You can use the commands below convert Bibles from that software to OSIS format.
|
You can use the commands below convert Bibles from that software to OSIS format.
|
||||||
|
|
||||||
The following commands are used in all platforms and the commands are case
|
The following commands are used in all platforms and the commands are case
|
||||||
sensitive across all platforms. To convert a Bible using Command Prompt in
|
sensitive across all platforms. To convert a Bible using the command prompt in
|
||||||
Windows or a Terminal in Linux or MAC you would type::
|
Windows or a terminal in Linux or Mac OS X you would type::
|
||||||
|
|
||||||
mod2osis biblename > biblename.osis
|
mod2osis biblename > biblename.osis
|
||||||
|
|
||||||
@ -114,17 +109,9 @@ You may also import downloaded bibles from OpenSong. The process is the same,
|
|||||||
except you will need to extract the bible from a zip file. This is usually done
|
except you will need to extract the bible from a zip file. This is usually done
|
||||||
by right clicking on the downloaded file and select `Extract` or `Extract Here`.
|
by right clicking on the downloaded file and select `Extract` or `Extract Here`.
|
||||||
|
|
||||||
After selecting the OpenSong Bibles you want to convert, click :guilabel:`Next`
|
After selecting the OpenSong Bibles you want to import, follow the rest of the
|
||||||
|
import process. When the import has finished you should be ready to use your
|
||||||
.. image:: pics/bibleimportdetails1.png
|
OpenSong Bibles.
|
||||||
|
|
||||||
Enter your Bible name and copyright details. Click :guilabel:`Next`. It may
|
|
||||||
take some time to convert your Bibles so please be patient.
|
|
||||||
|
|
||||||
.. image:: pics/bibleimportfinished1.png
|
|
||||||
|
|
||||||
When the import has finished then click :guilabel:`Finish` and you should now be
|
|
||||||
ready to use your OpenSong Bibles.
|
|
||||||
|
|
||||||
Importing Web Download Bibles
|
Importing Web Download Bibles
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -139,8 +126,6 @@ as another option and does require an internet connection.
|
|||||||
|
|
||||||
To use the web download feature select web download from the import wizard.
|
To use the web download feature select web download from the import wizard.
|
||||||
|
|
||||||
.. image:: pics/bibleimport01.png
|
|
||||||
|
|
||||||
You can select from several options of location to download from and also
|
You can select from several options of location to download from and also
|
||||||
what Bible translation you need. You will probably want to choose the location
|
what Bible translation you need. You will probably want to choose the location
|
||||||
from where you get the best performance or has the translation you need.
|
from where you get the best performance or has the translation you need.
|
||||||
@ -154,30 +139,20 @@ not be needed.
|
|||||||
.. image:: pics/webbibleproxy1.png
|
.. image:: pics/webbibleproxy1.png
|
||||||
|
|
||||||
After selecting your download location and the Bible you wish to use, click
|
After selecting your download location and the Bible you wish to use, click
|
||||||
:guilabel:`Next` When your import is completed click :guilabel:`Finish`
|
:guilabel:`Next` to continue the import process. When your import is completed
|
||||||
|
you should now be ready to use the web bible.
|
||||||
.. image:: pics/biblewebcomplete.png
|
|
||||||
|
|
||||||
You should now be ready to use the web bible.
|
|
||||||
|
|
||||||
Importing CSV formatted Bibles
|
Importing CSV formatted Bibles
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
If you have a Bible in .csv format OpenLP can import it. CSV Bibles will
|
If you have a Bible in .csv format OpenLP can import it. CSV Bibles will
|
||||||
consist of two files a `books` file and a `verse` file.
|
consist of two files a `books` file and a `verse` file. Select CSV from the list
|
||||||
|
of Bible types to import.
|
||||||
Select CSV from the list of Bible types to import.
|
|
||||||
|
|
||||||
.. image:: pics/bibleimport02.png
|
|
||||||
|
|
||||||
You are now ready to select your .csv files. You will need to select both your
|
You are now ready to select your .csv files. You will need to select both your
|
||||||
books and verse file location.
|
books and verse file location.
|
||||||
|
|
||||||
.. image:: pics/csvimport1.png
|
.. image:: pics/csvimport1.png
|
||||||
|
|
||||||
After you have selected the file locations you can click :guilabel:`Next`
|
After you have selected the file locations you can continue with the import
|
||||||
|
process. Once it is complete you should be ready to use your imported CSV Bible.
|
||||||
.. image:: pics/bibleimportfinished1.png
|
|
||||||
|
|
||||||
Click :guilabel:`Finish` and you should now be ready to use your imported CSV
|
|
||||||
Bible
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
.. _dualmonitors:
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Dual Monitor Setup
|
Dual Monitor Setup
|
||||||
==================
|
==================
|
||||||
@ -32,6 +34,14 @@ projector hooked up to your computer as the second monitor. With the option of
|
|||||||
extending your desktop across the second monitor, or your operating system's
|
extending your desktop across the second monitor, or your operating system's
|
||||||
equivalent.
|
equivalent.
|
||||||
|
|
||||||
|
**Special Note For Projectors Using USB Connections**
|
||||||
|
|
||||||
|
Users have reported experiencing difficulties when using a projector with a USB
|
||||||
|
connection, as third party software is often required to properly configure
|
||||||
|
dual monitors. If possible, it is best to use a direct output (VGA, DVI, HDMI,
|
||||||
|
S-Video) from your machine's video card. If a USB connection is your only option
|
||||||
|
please consult the manufacturer's manual for instructions on a proper setup.
|
||||||
|
|
||||||
Microsoft Windows
|
Microsoft Windows
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 16 KiB |
BIN
documentation/manual/source/pics/song_edit_authors.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
documentation/manual/source/pics/song_edit_lyrics.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
documentation/manual/source/pics/song_edit_maintenance.png
Normal file
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 12 KiB |
BIN
documentation/manual/source/pics/song_edit_theme_copyright.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
documentation/manual/source/pics/song_edit_topic_maintenance.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
documentation/manual/source/pics/song_edit_verse_error.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
documentation/manual/source/pics/song_edit_verse_type.png
Normal file
After Width: | Height: | Size: 45 KiB |
@ -99,4 +99,134 @@ completed.
|
|||||||
Press :guilabel:`Finish` and OpenLP will be ready to use your songs imported
|
Press :guilabel:`Finish` and OpenLP will be ready to use your songs imported
|
||||||
from CCLI SongSelect.
|
from CCLI SongSelect.
|
||||||
|
|
||||||
|
Creating or editing a song slide
|
||||||
|
================================
|
||||||
|
|
||||||
|
If you want to create a new song slide or, once you have a song imported, you
|
||||||
|
want to edit and rearrange the Title & Lyrics, Author, Topics & Song Book,
|
||||||
|
assign a Theme, or edit Copyright Info & Comments, you will do this through the
|
||||||
|
`Song Editor`.
|
||||||
|
|
||||||
|
**Edit:** To edit an existing song you can either click on a song in the
|
||||||
|
`Media Manager` and then click the button to :guilabel:`Edit the selected song`
|
||||||
|
or right click a song from either the `Media Manager` or additionally from the
|
||||||
|
`Service Manager` and click :guilabel:`Edit item`. If you are adding a new song
|
||||||
|
click :guilabel:`Add a new Song` in the `Media Manager`.
|
||||||
|
|
||||||
|
.. image:: pics/song_edit_lyrics.png
|
||||||
|
|
||||||
|
**Title:** This is where you would name your song or edit a song name.
|
||||||
|
|
||||||
|
**Alternate title:**Alternate Title was for songs with two names
|
||||||
|
"Lord the Light" - "Shine Jesus Shine". You can also add a name in this box that
|
||||||
|
will bring up the song in Titles search. **Example:** You could use an alternate
|
||||||
|
title of "hymn" on all your hymn song titles for grouping. When you search "hymn"
|
||||||
|
it will show all the hymns that have "hymn" for the Alternate title.
|
||||||
|
|
||||||
|
**Lyrics:** The *Lyrics* window shows all lyrics imported or added. On the left
|
||||||
|
side of the lyrics you will see a capital letter followed by a number. A V1
|
||||||
|
would represent verse 1, C1 would be Chorus 1. You will use these letters and
|
||||||
|
numbers for the order to display the lyrics.
|
||||||
|
|
||||||
|
**Verse Order:** After you entered or edited your song, you will want OpenLP to
|
||||||
|
display the verses in the correct order you want them displayed. On the left side
|
||||||
|
of your lyrics you will see C1, V1, V2 etc. the way they were imported or added.
|
||||||
|
To put your lyrics in the correct order is as simple as typing in the
|
||||||
|
:guilabel:`Verse order box` at the bottom, the correct order you want them
|
||||||
|
displayed, with only a blank space in between each entry. The correct format will
|
||||||
|
look like this: V1 C1 V2 C1 V3 C1. If you forget to put a space in between the
|
||||||
|
order, or if you do not have the corresponding verse number, OpenLP will politely
|
||||||
|
tell you with a pop-up error message what is wrong so you can correct your
|
||||||
|
mistake and save it. Verse order is optional and if left blank the verses will
|
||||||
|
display in the order seen in *Lyrics*.
|
||||||
|
|
||||||
|
.. image:: pics/song_edit_verse_error.png
|
||||||
|
|
||||||
|
Adding or editing the lyrics
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**Add:** To Add a new verse, click on :guilabel:`Add`. The main window is where
|
||||||
|
you will type your lyrics. OpenLP is packaged with a spell checker for most
|
||||||
|
languages. If you misspell a word it will be underlined. Right click the
|
||||||
|
underlined word and left click *Spelling Suggestions* or you can ignore it and
|
||||||
|
continue typing. You also have the ability to format the font using *Formatting
|
||||||
|
Tags*. Highlight the word/words you want to format and right click the highlight.
|
||||||
|
Left click *Formatting Tags* and choose the format you want to apply to the font
|
||||||
|
and the format tags will be entered with your lyrics. These tags are not visible
|
||||||
|
when displayed. To remove the format, delete the tag on each end of the word or
|
||||||
|
sentence.
|
||||||
|
|
||||||
|
**Edit:** To edit an existing verse, click on the verse you wish to *Edit* then click on
|
||||||
|
:guilabel:`Edit`, make your changes and click :guilabel:`Save`.
|
||||||
|
|
||||||
|
**Edit All:** To edit the whole song at once, click on :guilabel:`Edit All`.
|
||||||
|
|
||||||
|
**Delete:** To delete a verse, click on the verse you want to delete and it will
|
||||||
|
highlight, click on the :guilabel:`Delete` button and it will be deleted.
|
||||||
|
**Warning:**, once you click the :guilabel:`Delete` button, you will not be
|
||||||
|
asked again, it will be deleted immediately.
|
||||||
|
|
||||||
|
.. image:: pics/song_edit_verse_type.png
|
||||||
|
|
||||||
|
**Verse type:** gives you 7 ways to classify your lyrics. Verse, Chorus, Bridge,
|
||||||
|
Pre-Chorus, Intro, Ending, Other.
|
||||||
|
|
||||||
|
If you have more than one verse, you would number them Verse 1, 2, 3 as needed.
|
||||||
|
If you find the verse has too many lines for your screen, you can edit and
|
||||||
|
shorten the verse and :guilabel:`Add` another slide.
|
||||||
|
|
||||||
|
Authors, Topics & Song Book
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Once your *Title & Lyrics* are added or edited the way you want them you must
|
||||||
|
add or enter the author or authors of the song. OpenLP requires all songs to
|
||||||
|
have an author entered. You can add a blank space for the author name.
|
||||||
|
|
||||||
|
.. image:: pics/song_edit_authors.png
|
||||||
|
|
||||||
|
**Authors:** Click the drop down arrow to view all authors or start typing a name
|
||||||
|
in the box and a list will appear. If the authors name has not been added, type
|
||||||
|
the authors name in the box and click :guilabel:`Add to Song`. The authors name
|
||||||
|
will appear below and will also be added to your database. If you accidently add
|
||||||
|
the wrong author you can click on the authors name and click :guilabel:`Remove`.
|
||||||
|
|
||||||
|
:guilabel:`Manage Authors, Topics, Song Books`: Clicking this button will bring
|
||||||
|
up your complete list of authors.
|
||||||
|
|
||||||
|
.. image:: pics/song_edit_maintenance.png
|
||||||
|
|
||||||
|
**Add:** Clicking the :guilabel:`Add` button will bring up a box where you will
|
||||||
|
add the Authors First name, Last name and Display name. Click :guilabel:`Save`
|
||||||
|
when you are finished.
|
||||||
|
|
||||||
|
.. image:: pics/song_edit_author_maintenance.png
|
||||||
|
|
||||||
|
**Edit:** The :guilabel:`Edit` button will bring up window where you can edit
|
||||||
|
the info that is already there.
|
||||||
|
|
||||||
|
**Delete:** The :guilabel:`Delete` button will remove the author you have
|
||||||
|
highlighted. Note: You cannot delete an author that is assigned to a song.
|
||||||
|
Authors names are displayed in the footer.
|
||||||
|
|
||||||
|
Theme, Copyright info & Comments
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
On this tab you can assign a *Theme* to a song, enter the *Copyright information*
|
||||||
|
and add the *CCLI number*. If you imported a song from SongSelect this
|
||||||
|
information will usually be entered.
|
||||||
|
|
||||||
|
.. image:: pics/song_edit_theme_copyright.png
|
||||||
|
|
||||||
|
**Theme:** Click the drop down arrow to display your list of themes or start
|
||||||
|
typing a theme name in the box and the list will appear. You can also create a
|
||||||
|
new theme by clicking the :guilabel:`New Theme` button.
|
||||||
|
|
||||||
|
**Copyright information:** Add or edit the copyright information in this box. If
|
||||||
|
you would like to use the © symbol click "guilabel:`©` button. This information
|
||||||
|
is displayed in the footer.
|
||||||
|
|
||||||
|
**CCLI number:** Enter the CCLI number in this box. Note: this is the CCLI number
|
||||||
|
of the song, not your contract number. This number is not displayed in the footer
|
||||||
|
|
||||||
|
**Comments:** You can add comments in this box. This information is not
|
||||||
|
dispayed in the footer.
|
||||||
|
@ -175,3 +175,23 @@ only download the section you search for. If you do not have an internet
|
|||||||
connection where you intend to use OpenLP you will need another scripture
|
connection where you intend to use OpenLP you will need another scripture
|
||||||
source. For more information about acquiring Bibles please see :ref:`bibleimporter`.
|
source. For more information about acquiring Bibles please see :ref:`bibleimporter`.
|
||||||
|
|
||||||
|
OpenLP is using a large amount of RAM when showing a presentation
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
OpenLP uses a large amount of RAM when showing a presentation due to the way it
|
||||||
|
handles presentations. OpenLP itself is unable to show those presentations or
|
||||||
|
load the presentation files, so it interacts with the presentation through
|
||||||
|
either Microsoft PowerPoint or LibreOffice Impress. In order to show the slides
|
||||||
|
in the slide controller, OpenLP requests that the presentation application
|
||||||
|
export the slides to images, and then uses those images as slides. This results
|
||||||
|
in a large amount of RAM being used, especially in presentations with more than
|
||||||
|
about 20 slides.
|
||||||
|
|
||||||
|
OpenLP is not displaying correctly, or is not on the correct screen
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
Please read the documentation on :ref:`dualmonitors`. It is very important to
|
||||||
|
have dual monitors setup properly for OpenLP to function as expected.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ class OpenLP(QtGui.QApplication):
|
|||||||
self.sharedMemory = QtCore.QSharedMemory('OpenLP')
|
self.sharedMemory = QtCore.QSharedMemory('OpenLP')
|
||||||
if self.sharedMemory.attach():
|
if self.sharedMemory.attach():
|
||||||
status = QtGui.QMessageBox.critical(None,
|
status = QtGui.QMessageBox.critical(None,
|
||||||
UiStrings.Error, UiStrings.OpenLPStart,
|
UiStrings().Error, UiStrings().OpenLPStart,
|
||||||
QtGui.QMessageBox.StandardButtons(
|
QtGui.QMessageBox.StandardButtons(
|
||||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
||||||
if status == QtGui.QMessageBox.No:
|
if status == QtGui.QMessageBox.No:
|
||||||
@ -250,4 +250,4 @@ if __name__ == u'__main__':
|
|||||||
"""
|
"""
|
||||||
Instantiate and run the application.
|
Instantiate and run the application.
|
||||||
"""
|
"""
|
||||||
main()
|
main()
|
@ -289,6 +289,5 @@ from htmlbuilder import build_html, build_lyrics_format_css, \
|
|||||||
from toolbar import OpenLPToolbar
|
from toolbar import OpenLPToolbar
|
||||||
from dockwidget import OpenLPDockWidget
|
from dockwidget import OpenLPDockWidget
|
||||||
from renderer import Renderer
|
from renderer import Renderer
|
||||||
from rendermanager import RenderManager
|
|
||||||
from mediamanageritem import MediaManagerItem
|
from mediamanageritem import MediaManagerItem
|
||||||
from openlp.core.utils.actions import ActionList
|
from openlp.core.utils.actions import ActionList
|
||||||
|
@ -435,7 +435,7 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
item to the preview slide controller.
|
item to the preview slide controller.
|
||||||
"""
|
"""
|
||||||
if not self.listView.selectedIndexes() and not self.remoteTriggered:
|
if not self.listView.selectedIndexes() and not self.remoteTriggered:
|
||||||
QtGui.QMessageBox.information(self, UiStrings.NISp,
|
QtGui.QMessageBox.information(self, UiStrings().NISp,
|
||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'You must select one or more items to preview.'))
|
'You must select one or more items to preview.'))
|
||||||
else:
|
else:
|
||||||
@ -453,7 +453,7 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
item to the live slide controller.
|
item to the live slide controller.
|
||||||
"""
|
"""
|
||||||
if not self.listView.selectedIndexes():
|
if not self.listView.selectedIndexes():
|
||||||
QtGui.QMessageBox.information(self, UiStrings.NISp,
|
QtGui.QMessageBox.information(self, UiStrings().NISp,
|
||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'You must select one or more items to send live.'))
|
'You must select one or more items to send live.'))
|
||||||
else:
|
else:
|
||||||
@ -468,7 +468,7 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
Add a selected item to the current service
|
Add a selected item to the current service
|
||||||
"""
|
"""
|
||||||
if not self.listView.selectedIndexes() and not self.remoteTriggered:
|
if not self.listView.selectedIndexes() and not self.remoteTriggered:
|
||||||
QtGui.QMessageBox.information(self, UiStrings.NISp,
|
QtGui.QMessageBox.information(self, UiStrings().NISp,
|
||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'You must select one or more items.'))
|
'You must select one or more items.'))
|
||||||
else:
|
else:
|
||||||
@ -494,14 +494,14 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
Add a selected item to an existing item in the current service.
|
Add a selected item to an existing item in the current service.
|
||||||
"""
|
"""
|
||||||
if not self.listView.selectedIndexes() and not self.remoteTriggered:
|
if not self.listView.selectedIndexes() and not self.remoteTriggered:
|
||||||
QtGui.QMessageBox.information(self, UiStrings.NISp,
|
QtGui.QMessageBox.information(self, UiStrings().NISp,
|
||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'You must select one or more items.'))
|
'You must select one or more items.'))
|
||||||
else:
|
else:
|
||||||
log.debug(u'%s Add requested', self.plugin.name)
|
log.debug(u'%s Add requested', self.plugin.name)
|
||||||
serviceItem = self.parent.serviceManager.getServiceItem()
|
serviceItem = self.parent.serviceManager.getServiceItem()
|
||||||
if not serviceItem:
|
if not serviceItem:
|
||||||
QtGui.QMessageBox.information(self, UiStrings.NISs,
|
QtGui.QMessageBox.information(self, UiStrings().NISs,
|
||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'You must select an existing service item to add to.'))
|
'You must select an existing service item to add to.'))
|
||||||
elif self.plugin.name.lower() == serviceItem.name.lower():
|
elif self.plugin.name.lower() == serviceItem.name.lower():
|
||||||
@ -554,4 +554,4 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
item_id = remoteItem
|
item_id = remoteItem
|
||||||
else:
|
else:
|
||||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||||
return item_id
|
return item_id
|
@ -161,7 +161,7 @@ class Plugin(QtCore.QObject):
|
|||||||
self.log = logging.getLogger(self.name)
|
self.log = logging.getLogger(self.name)
|
||||||
self.previewController = plugin_helpers[u'preview']
|
self.previewController = plugin_helpers[u'preview']
|
||||||
self.liveController = plugin_helpers[u'live']
|
self.liveController = plugin_helpers[u'live']
|
||||||
self.renderManager = plugin_helpers[u'render']
|
self.renderer = plugin_helpers[u'renderer']
|
||||||
self.serviceManager = plugin_helpers[u'service']
|
self.serviceManager = plugin_helpers[u'service']
|
||||||
self.settingsForm = plugin_helpers[u'settings form']
|
self.settingsForm = plugin_helpers[u'settings form']
|
||||||
self.mediadock = plugin_helpers[u'toolbox']
|
self.mediadock = plugin_helpers[u'toolbox']
|
||||||
@ -330,28 +330,28 @@ class Plugin(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
## Load Action ##
|
## Load Action ##
|
||||||
self.__setNameTextString(StringContent.Load,
|
self.__setNameTextString(StringContent.Load,
|
||||||
UiStrings.Load, tooltips[u'load'])
|
UiStrings().Load, tooltips[u'load'])
|
||||||
## Import Action ##
|
## Import Action ##
|
||||||
self.__setNameTextString(StringContent.Import,
|
self.__setNameTextString(StringContent.Import,
|
||||||
UiStrings.Import, tooltips[u'import'])
|
UiStrings().Import, tooltips[u'import'])
|
||||||
## New Action ##
|
## New Action ##
|
||||||
self.__setNameTextString(StringContent.New,
|
self.__setNameTextString(StringContent.New,
|
||||||
UiStrings.Add, tooltips[u'new'])
|
UiStrings().Add, tooltips[u'new'])
|
||||||
## Edit Action ##
|
## Edit Action ##
|
||||||
self.__setNameTextString(StringContent.Edit,
|
self.__setNameTextString(StringContent.Edit,
|
||||||
UiStrings.Edit, tooltips[u'edit'])
|
UiStrings().Edit, tooltips[u'edit'])
|
||||||
## Delete Action ##
|
## Delete Action ##
|
||||||
self.__setNameTextString(StringContent.Delete,
|
self.__setNameTextString(StringContent.Delete,
|
||||||
UiStrings.Delete, tooltips[u'delete'])
|
UiStrings().Delete, tooltips[u'delete'])
|
||||||
## Preview Action ##
|
## Preview Action ##
|
||||||
self.__setNameTextString(StringContent.Preview,
|
self.__setNameTextString(StringContent.Preview,
|
||||||
UiStrings.Preview, tooltips[u'preview'])
|
UiStrings().Preview, tooltips[u'preview'])
|
||||||
## Send Live Action ##
|
## Send Live Action ##
|
||||||
self.__setNameTextString(StringContent.Live,
|
self.__setNameTextString(StringContent.Live,
|
||||||
UiStrings.Live, tooltips[u'live'])
|
UiStrings().Live, tooltips[u'live'])
|
||||||
## Add to Service Action ##
|
## Add to Service Action ##
|
||||||
self.__setNameTextString(StringContent.Service,
|
self.__setNameTextString(StringContent.Service,
|
||||||
UiStrings.Service, tooltips[u'service'])
|
UiStrings().Service, tooltips[u'service'])
|
||||||
|
|
||||||
def __setNameTextString(self, name, title, tooltip):
|
def __setNameTextString(self, name, title, tooltip):
|
||||||
"""
|
"""
|
||||||
|
@ -23,46 +23,260 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
"""
|
|
||||||
The :mod:`renderer` module enables OpenLP to take the input from plugins and
|
|
||||||
format it for the output display.
|
|
||||||
"""
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtWebKit
|
from PyQt4 import QtCore, QtWebKit
|
||||||
|
|
||||||
from openlp.core.lib import expand_tags, build_lyrics_format_css, \
|
from openlp.core.lib import ServiceItem, ImageManager, expand_tags, \
|
||||||
build_lyrics_outline_css, Receiver
|
build_lyrics_format_css, build_lyrics_outline_css, Receiver, \
|
||||||
|
ItemCapabilities
|
||||||
|
from openlp.core.lib.theme import ThemeLevel
|
||||||
|
from openlp.core.ui import MainDisplay
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
VERSE = u'The Lord said to {r}Noah{/r}: \n' \
|
||||||
|
'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n' \
|
||||||
|
'The Lord said to {g}Noah{/g}:\n' \
|
||||||
|
'There\'s gonna be a {st}floody{/st}, {it}floody{/it}\n' \
|
||||||
|
'Get those children out of the muddy, muddy \n' \
|
||||||
|
'{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}' \
|
||||||
|
'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
|
||||||
|
FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456']
|
||||||
|
|
||||||
|
HTML_END = u'</div></body></html>'
|
||||||
|
|
||||||
class Renderer(object):
|
class Renderer(object):
|
||||||
"""
|
"""
|
||||||
Genarates a pixmap image of a array of text. The Text is formatted to
|
Class to pull all Renderer interactions into one place. The plugins will
|
||||||
make sure it fits on the screen and if not extra frames are generated.
|
call helper methods to do the rendering but this class will provide
|
||||||
|
display defense code.
|
||||||
|
|
||||||
|
``theme_manager``
|
||||||
|
The ThemeManager instance, used to get the current theme details.
|
||||||
|
|
||||||
|
``screens``
|
||||||
|
Contains information about the Screens.
|
||||||
|
|
||||||
|
``screen_number``
|
||||||
|
Defaults to *0*. The index of the output/display screen.
|
||||||
"""
|
"""
|
||||||
log.info(u'Renderer Loaded')
|
log.info(u'Renderer Loaded')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, theme_manager, screens):
|
||||||
"""
|
"""
|
||||||
Initialise the renderer.
|
Initialise the render manager.
|
||||||
"""
|
"""
|
||||||
self._rect = None
|
log.debug(u'Initilisation started')
|
||||||
self.theme_name = None
|
self.screens = screens
|
||||||
self._theme = None
|
self.image_manager = ImageManager()
|
||||||
|
self.display = MainDisplay(self, screens, False)
|
||||||
|
self.display.imageManager = self.image_manager
|
||||||
|
self.theme_manager = theme_manager
|
||||||
|
self.service_theme = u''
|
||||||
|
self.theme_level = u''
|
||||||
|
self.override_background = None
|
||||||
|
self.theme_data = None
|
||||||
|
self.force_page = False
|
||||||
|
|
||||||
def set_theme(self, theme):
|
def update_display(self):
|
||||||
"""
|
"""
|
||||||
Set the theme to be used.
|
Updates the render manager's information about the current screen.
|
||||||
|
"""
|
||||||
|
log.debug(u'Update Display')
|
||||||
|
self._calculate_default(self.screens.current[u'size'])
|
||||||
|
self.display = MainDisplay(self, self.screens, False)
|
||||||
|
self.display.imageManager = self.image_manager
|
||||||
|
self.display.setup()
|
||||||
|
self.bg_frame = None
|
||||||
|
self.theme_data = None
|
||||||
|
self.image_manager.update_display(self.width, self.height)
|
||||||
|
|
||||||
|
def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global):
|
||||||
|
"""
|
||||||
|
Set the global-level theme and the theme level.
|
||||||
|
|
||||||
|
``global_theme``
|
||||||
|
The global-level theme to be set.
|
||||||
|
|
||||||
|
``theme_level``
|
||||||
|
Defaults to *``ThemeLevel.Global``*. The theme level, can be
|
||||||
|
``ThemeLevel.Global``, ``ThemeLevel.Service`` or
|
||||||
|
``ThemeLevel.Song``.
|
||||||
|
"""
|
||||||
|
self.global_theme = global_theme
|
||||||
|
self.theme_level = theme_level
|
||||||
|
self.global_theme_data = \
|
||||||
|
self.theme_manager.getThemeData(self.global_theme)
|
||||||
|
self.theme_data = None
|
||||||
|
|
||||||
|
def set_service_theme(self, service_theme):
|
||||||
|
"""
|
||||||
|
Set the service-level theme.
|
||||||
|
|
||||||
|
``service_theme``
|
||||||
|
The service-level theme to be set.
|
||||||
|
"""
|
||||||
|
self.service_theme = service_theme
|
||||||
|
self.theme_data = None
|
||||||
|
|
||||||
|
def set_override_theme(self, override_theme, override_levels=False):
|
||||||
|
"""
|
||||||
|
Set the appropriate theme depending on the theme level.
|
||||||
|
Called by the service item when building a display frame
|
||||||
|
|
||||||
``theme``
|
``theme``
|
||||||
The theme to be used.
|
The name of the song-level theme. None means the service
|
||||||
"""
|
item wants to use the given value.
|
||||||
log.debug(u'set theme')
|
|
||||||
self._theme = theme
|
|
||||||
self.theme_name = theme.theme_name
|
|
||||||
|
|
||||||
def set_text_rectangle(self, rect_main, rect_footer):
|
``override_levels``
|
||||||
|
Used to force the theme data passed in to be used.
|
||||||
|
|
||||||
|
"""
|
||||||
|
log.debug(u'set override theme to %s', override_theme)
|
||||||
|
theme_level = self.theme_level
|
||||||
|
if override_levels:
|
||||||
|
theme_level = ThemeLevel.Song
|
||||||
|
if theme_level == ThemeLevel.Global:
|
||||||
|
theme = self.global_theme
|
||||||
|
elif theme_level == ThemeLevel.Service:
|
||||||
|
if self.service_theme == u'':
|
||||||
|
theme = self.global_theme
|
||||||
|
else:
|
||||||
|
theme = self.service_theme
|
||||||
|
else:
|
||||||
|
# Images have a theme of -1
|
||||||
|
if override_theme and override_theme != -1:
|
||||||
|
theme = override_theme
|
||||||
|
elif theme_level == ThemeLevel.Song or \
|
||||||
|
theme_level == ThemeLevel.Service:
|
||||||
|
if self.service_theme == u'':
|
||||||
|
theme = self.global_theme
|
||||||
|
else:
|
||||||
|
theme = self.service_theme
|
||||||
|
else:
|
||||||
|
theme = self.global_theme
|
||||||
|
log.debug(u'theme is now %s', theme)
|
||||||
|
# Force the theme to be the one passed in.
|
||||||
|
if override_levels:
|
||||||
|
self.theme_data = override_theme
|
||||||
|
else:
|
||||||
|
self.theme_data = self.theme_manager.getThemeData(theme)
|
||||||
|
self._calculate_default(self.screens.current[u'size'])
|
||||||
|
self._build_text_rectangle(self.theme_data)
|
||||||
|
self.image_manager.add_image(self.theme_data.theme_name,
|
||||||
|
self.theme_data.background_filename)
|
||||||
|
return self._rect, self._rect_footer
|
||||||
|
|
||||||
|
def generate_preview(self, theme_data, force_page=False):
|
||||||
|
"""
|
||||||
|
Generate a preview of a theme.
|
||||||
|
|
||||||
|
``theme_data``
|
||||||
|
The theme to generated a preview for.
|
||||||
|
|
||||||
|
``force_page``
|
||||||
|
Flag to tell message lines per page need to be generated.
|
||||||
|
"""
|
||||||
|
log.debug(u'generate preview')
|
||||||
|
# save value for use in format_slide
|
||||||
|
self.force_page = force_page
|
||||||
|
# set the default image size for previews
|
||||||
|
self._calculate_default(self.screens.preview[u'size'])
|
||||||
|
# build a service item to generate preview
|
||||||
|
serviceItem = ServiceItem()
|
||||||
|
serviceItem.theme = theme_data
|
||||||
|
if self.force_page:
|
||||||
|
# make big page for theme edit dialog to get line count
|
||||||
|
serviceItem.add_from_text(u'', VERSE + VERSE + VERSE, FOOTER)
|
||||||
|
else:
|
||||||
|
self.image_manager.del_image(theme_data.theme_name)
|
||||||
|
serviceItem.add_from_text(u'', VERSE, FOOTER)
|
||||||
|
serviceItem.renderer = self
|
||||||
|
serviceItem.raw_footer = FOOTER
|
||||||
|
serviceItem.render(True)
|
||||||
|
if not self.force_page:
|
||||||
|
self.display.buildHtml(serviceItem)
|
||||||
|
raw_html = serviceItem.get_rendered_frame(0)
|
||||||
|
preview = self.display.text(raw_html)
|
||||||
|
# Reset the real screen size for subsequent render requests
|
||||||
|
self._calculate_default(self.screens.current[u'size'])
|
||||||
|
return preview
|
||||||
|
|
||||||
|
def format_slide(self, text, line_break, item):
|
||||||
|
"""
|
||||||
|
Calculate how much text can fit on a slide.
|
||||||
|
|
||||||
|
``text``
|
||||||
|
The words to go on the slides.
|
||||||
|
|
||||||
|
``line_break``
|
||||||
|
Add line endings after each line of text used for bibles.
|
||||||
|
"""
|
||||||
|
log.debug(u'format slide')
|
||||||
|
# clean up line endings
|
||||||
|
lines = self._lines_split(text)
|
||||||
|
pages = self._paginate_slide(lines, line_break, self.force_page)
|
||||||
|
if len(pages) > 1:
|
||||||
|
# Songs and Custom
|
||||||
|
if item.is_capable(ItemCapabilities.AllowsVirtualSplit):
|
||||||
|
# Do not forget the line breaks !
|
||||||
|
slides = text.split(u'\n[---]\n')
|
||||||
|
pages = []
|
||||||
|
for slide in slides:
|
||||||
|
lines = self._lines(slide)
|
||||||
|
new_pages = self._paginate_slide(lines, line_break,
|
||||||
|
self.force_page)
|
||||||
|
pages.extend([page for page in new_pages])
|
||||||
|
# Bibles
|
||||||
|
elif item.is_capable(ItemCapabilities.AllowsWordSplit):
|
||||||
|
pages = self._paginate_slide_words(text, line_break)
|
||||||
|
return pages
|
||||||
|
|
||||||
|
def _calculate_default(self, screen):
|
||||||
|
"""
|
||||||
|
Calculate the default dimentions of the screen.
|
||||||
|
|
||||||
|
``screen``
|
||||||
|
The QSize of the screen.
|
||||||
|
"""
|
||||||
|
log.debug(u'calculate default %s', screen)
|
||||||
|
self.width = screen.width()
|
||||||
|
self.height = screen.height()
|
||||||
|
self.screen_ratio = float(self.height) / float(self.width)
|
||||||
|
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)
|
||||||
|
|
||||||
|
def _build_text_rectangle(self, theme):
|
||||||
|
"""
|
||||||
|
Builds a text block using the settings in ``theme``
|
||||||
|
and the size of the display screen.height.
|
||||||
|
Note the system has a 10 pixel border round the screen
|
||||||
|
|
||||||
|
``theme``
|
||||||
|
The theme to build a text block for.
|
||||||
|
"""
|
||||||
|
log.debug(u'_build_text_rectangle')
|
||||||
|
main_rect = None
|
||||||
|
footer_rect = None
|
||||||
|
if not theme.font_main_override:
|
||||||
|
main_rect = QtCore.QRect(10, 0, self.width - 20, self.footer_start)
|
||||||
|
else:
|
||||||
|
main_rect = QtCore.QRect(theme.font_main_x, theme.font_main_y,
|
||||||
|
theme.font_main_width - 1, theme.font_main_height - 1)
|
||||||
|
if not theme.font_footer_override:
|
||||||
|
footer_rect = QtCore.QRect(10, self.footer_start, self.width - 20,
|
||||||
|
self.height - self.footer_start)
|
||||||
|
else:
|
||||||
|
footer_rect = QtCore.QRect(theme.font_footer_x,
|
||||||
|
theme.font_footer_y, theme.font_footer_width - 1,
|
||||||
|
theme.font_footer_height - 1)
|
||||||
|
self._set_text_rectangle(main_rect, footer_rect)
|
||||||
|
|
||||||
|
def _set_text_rectangle(self, rect_main, rect_footer):
|
||||||
"""
|
"""
|
||||||
Sets the rectangle within which text should be rendered.
|
Sets the rectangle within which text should be rendered.
|
||||||
|
|
||||||
@ -77,9 +291,9 @@ class Renderer(object):
|
|||||||
self._rect_footer = rect_footer
|
self._rect_footer = rect_footer
|
||||||
self.page_width = self._rect.width()
|
self.page_width = self._rect.width()
|
||||||
self.page_height = self._rect.height()
|
self.page_height = self._rect.height()
|
||||||
if self._theme.font_main_shadow:
|
if self.theme_data.font_main_shadow:
|
||||||
self.page_width -= int(self._theme.font_main_shadow_size)
|
self.page_width -= int(self.theme_data.font_main_shadow_size)
|
||||||
self.page_height -= int(self._theme.font_main_shadow_size)
|
self.page_height -= int(self.theme_data.font_main_shadow_size)
|
||||||
self.web = QtWebKit.QWebView()
|
self.web = QtWebKit.QWebView()
|
||||||
self.web.setVisible(False)
|
self.web.setVisible(False)
|
||||||
self.web.resize(self.page_width, self.page_height)
|
self.web.resize(self.page_width, self.page_height)
|
||||||
@ -89,59 +303,163 @@ class Renderer(object):
|
|||||||
u'*{margin: 0; padding: 0; border: 0;} '\
|
u'*{margin: 0; padding: 0; border: 0;} '\
|
||||||
u'#main {position:absolute; top:0px; %s %s}</style><body>' \
|
u'#main {position:absolute; top:0px; %s %s}</style><body>' \
|
||||||
u'<div id="main">' % \
|
u'<div id="main">' % \
|
||||||
(build_lyrics_format_css(self._theme, self.page_width,
|
(build_lyrics_format_css(self.theme_data, self.page_width,
|
||||||
self.page_height), build_lyrics_outline_css(self._theme))
|
self.page_height), build_lyrics_outline_css(self.theme_data))
|
||||||
|
|
||||||
def format_slide(self, words, line_break, force_page=False):
|
def _paginate_slide(self, lines, line_break, force_page=False):
|
||||||
"""
|
"""
|
||||||
Figure out how much text can appear on a slide, using the current
|
Figure out how much text can appear on a slide, using the current
|
||||||
theme settings.
|
theme settings.
|
||||||
|
|
||||||
``words``
|
``lines``
|
||||||
The words to be fitted on the slide.
|
The words to be fitted on the slide split into lines.
|
||||||
|
|
||||||
``line_break``
|
``line_break``
|
||||||
Add line endings after each line of text used for bibles.
|
Add line endings after each line of text (used for bibles).
|
||||||
|
|
||||||
``force_page``
|
``force_page``
|
||||||
Flag to tell message lines in page.
|
Flag to tell message lines in page.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'format_slide - Start')
|
log.debug(u'_paginate_slide - Start')
|
||||||
line_end = u''
|
line_end = u''
|
||||||
if line_break:
|
if line_break:
|
||||||
line_end = u'<br>'
|
line_end = u'<br>'
|
||||||
words = words.replace(u'\r\n', u'\n')
|
|
||||||
verses_text = words.split(u'\n')
|
|
||||||
text = []
|
|
||||||
for verse in verses_text:
|
|
||||||
lines = verse.split(u'\n')
|
|
||||||
for line in lines:
|
|
||||||
text.append(line)
|
|
||||||
formatted = []
|
formatted = []
|
||||||
html_text = u''
|
html_text = u''
|
||||||
styled_text = u''
|
styled_text = u''
|
||||||
line_count = 0
|
line_count = 0
|
||||||
for line in text:
|
for line in lines:
|
||||||
if line_count != -1:
|
if line_count != -1:
|
||||||
line_count += 1
|
line_count += 1
|
||||||
styled_line = expand_tags(line) + line_end
|
styled_line = expand_tags(line) + line_end
|
||||||
styled_text += styled_line
|
styled_text += styled_line
|
||||||
html = self.page_shell + styled_text + u'</div></body></html>'
|
html = self.page_shell + styled_text + HTML_END
|
||||||
self.web.setHtml(html)
|
self.web.setHtml(html)
|
||||||
# Text too long so go to next page
|
# Text too long so go to next page
|
||||||
if self.web_frame.contentsSize().height() > self.page_height:
|
if self.web_frame.contentsSize().height() > self.page_height:
|
||||||
if force_page and line_count > 0:
|
if force_page and line_count > 0:
|
||||||
Receiver.send_message(u'theme_line_count', line_count)
|
Receiver.send_message(u'theme_line_count', line_count)
|
||||||
line_count = -1
|
line_count = -1
|
||||||
if html_text.endswith(u'<br>'):
|
html_text = html_text.rstrip(u'<br>')
|
||||||
html_text = html_text[:len(html_text)-4]
|
|
||||||
formatted.append(html_text)
|
formatted.append(html_text)
|
||||||
html_text = u''
|
html_text = u''
|
||||||
styled_text = styled_line
|
styled_text = styled_line
|
||||||
html_text += line + line_end
|
html_text += line + line_end
|
||||||
if html_text.endswith(u'<br>'):
|
html_text = html_text.rstrip(u'<br>')
|
||||||
html_text = html_text[:len(html_text)-4]
|
|
||||||
formatted.append(html_text)
|
formatted.append(html_text)
|
||||||
log.debug(u'format_slide - End')
|
log.debug(u'_paginate_slide - End')
|
||||||
return formatted
|
return formatted
|
||||||
|
|
||||||
|
def _paginate_slide_words(self, text, line_break):
|
||||||
|
"""
|
||||||
|
Figure out how much text can appear on a slide, using the current
|
||||||
|
theme settings. This version is to handle text which needs to be split
|
||||||
|
into words to get it to fit.
|
||||||
|
|
||||||
|
``text``
|
||||||
|
The words to be fitted on the slide split into lines.
|
||||||
|
|
||||||
|
``line_break``
|
||||||
|
Add line endings after each line of text used for bibles.
|
||||||
|
|
||||||
|
"""
|
||||||
|
log.debug(u'_paginate_slide_words - Start')
|
||||||
|
line_end = u''
|
||||||
|
if line_break:
|
||||||
|
line_end = u'<br>'
|
||||||
|
formatted = []
|
||||||
|
previous_html = u''
|
||||||
|
previous_raw = u''
|
||||||
|
lines = self._lines(text)
|
||||||
|
for line in lines:
|
||||||
|
styled_line = expand_tags(line)
|
||||||
|
html = self.page_shell + previous_html + styled_line + HTML_END
|
||||||
|
self.web.setHtml(html)
|
||||||
|
# Text too long so go to next page
|
||||||
|
if self.web_frame.contentsSize().height() > self.page_height:
|
||||||
|
# Check if there was a verse before the current one and append
|
||||||
|
# it, when it fits on the page.
|
||||||
|
if previous_html:
|
||||||
|
html = self.page_shell + previous_html + HTML_END
|
||||||
|
self.web.setHtml(html)
|
||||||
|
if self.web_frame.contentsSize().height() <= \
|
||||||
|
self.page_height:
|
||||||
|
previous_raw = previous_raw.rstrip(u'<br>')
|
||||||
|
formatted.append(previous_raw)
|
||||||
|
previous_html = u''
|
||||||
|
previous_raw = u''
|
||||||
|
html = self.page_shell + styled_line + HTML_END
|
||||||
|
self.web.setHtml(html)
|
||||||
|
# Now check if the current verse will fit, if it does
|
||||||
|
# not we have to start to process the verse word by
|
||||||
|
# word.
|
||||||
|
if self.web_frame.contentsSize().height() <= \
|
||||||
|
self.page_height:
|
||||||
|
previous_html = styled_line + line_end
|
||||||
|
previous_raw = line + line_end
|
||||||
|
continue
|
||||||
|
words = self._words_split(line)
|
||||||
|
for word in words:
|
||||||
|
styled_word = expand_tags(word)
|
||||||
|
html = self.page_shell + previous_html + styled_word + \
|
||||||
|
HTML_END
|
||||||
|
self.web.setHtml(html)
|
||||||
|
# Text too long so go to next page
|
||||||
|
if self.web_frame.contentsSize().height() > \
|
||||||
|
self.page_height:
|
||||||
|
previous_raw = previous_raw.rstrip(u'<br>')
|
||||||
|
formatted.append(previous_raw)
|
||||||
|
previous_html = u''
|
||||||
|
previous_raw = u''
|
||||||
|
previous_html += styled_word
|
||||||
|
previous_raw += word
|
||||||
|
previous_html += line_end
|
||||||
|
previous_raw += line_end
|
||||||
|
else:
|
||||||
|
previous_html += styled_line + line_end
|
||||||
|
previous_raw += line + line_end
|
||||||
|
previous_raw = previous_raw.rstrip(u'<br>')
|
||||||
|
formatted.append(previous_raw)
|
||||||
|
log.debug(u'_paginate_slide_words - End')
|
||||||
|
return formatted
|
||||||
|
|
||||||
|
def _lines(self, text):
|
||||||
|
"""
|
||||||
|
Split the slide up by physical line
|
||||||
|
"""
|
||||||
|
# this parse we do not want to use this so remove it
|
||||||
|
verses_text = text.split(u'\n')
|
||||||
|
text = []
|
||||||
|
for verse in verses_text:
|
||||||
|
lines = verse.split(u'\n')
|
||||||
|
text.extend([line for line in lines])
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
|
def _words_split(self, line):
|
||||||
|
"""
|
||||||
|
Split the slide up by word so can wrap better
|
||||||
|
"""
|
||||||
|
# this parse we are to be wordy
|
||||||
|
line = line.replace(u'\n', u' ')
|
||||||
|
verses_text = line.split(u' ')
|
||||||
|
text = []
|
||||||
|
for verse in verses_text:
|
||||||
|
lines = verse.split(u' ')
|
||||||
|
text.extend([line + u' ' for line in lines])
|
||||||
|
return text
|
||||||
|
|
||||||
|
def _lines_split(self, text):
|
||||||
|
"""
|
||||||
|
Split the slide up by physical line
|
||||||
|
"""
|
||||||
|
# this parse we do not want to use this so remove it
|
||||||
|
text = text.replace(u'\n[---]', u'')
|
||||||
|
lines = text.split(u'\n')
|
||||||
|
real_lines = []
|
||||||
|
for line in lines:
|
||||||
|
line = line.replace(u'[---]', u'')
|
||||||
|
sub_lines = line.split(u'\n')
|
||||||
|
real_lines.extend([sub_line for sub_line in sub_lines])
|
||||||
|
return real_lines
|
||||||
|
@ -1,261 +0,0 @@
|
|||||||
# -*- 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, Matthias Hub, Meinert Jordan, Armin Köhler, #
|
|
||||||
# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, #
|
|
||||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, 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 logging
|
|
||||||
|
|
||||||
from PyQt4 import QtCore
|
|
||||||
|
|
||||||
from openlp.core.lib import Renderer, ServiceItem, ImageManager
|
|
||||||
from openlp.core.lib.theme import ThemeLevel
|
|
||||||
from openlp.core.ui import MainDisplay
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
VERSE = u'The Lord said to {r}Noah{/r}: \n' \
|
|
||||||
'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n' \
|
|
||||||
'The Lord said to {g}Noah{/g}:\n' \
|
|
||||||
'There\'s gonna be a {st}floody{/st}, {it}floody{/it}\n' \
|
|
||||||
'Get those children out of the muddy, muddy \n' \
|
|
||||||
'{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}' \
|
|
||||||
'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
|
|
||||||
FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456']
|
|
||||||
|
|
||||||
class RenderManager(object):
|
|
||||||
"""
|
|
||||||
Class to pull all Renderer interactions into one place. The plugins will
|
|
||||||
call helper methods to do the rendering but this class will provide
|
|
||||||
display defense code.
|
|
||||||
|
|
||||||
``theme_manager``
|
|
||||||
The ThemeManager instance, used to get the current theme details.
|
|
||||||
|
|
||||||
``screens``
|
|
||||||
Contains information about the Screens.
|
|
||||||
|
|
||||||
``screen_number``
|
|
||||||
Defaults to *0*. The index of the output/display screen.
|
|
||||||
"""
|
|
||||||
log.info(u'RenderManager Loaded')
|
|
||||||
|
|
||||||
def __init__(self, theme_manager, screens):
|
|
||||||
"""
|
|
||||||
Initialise the render manager.
|
|
||||||
"""
|
|
||||||
log.debug(u'Initilisation started')
|
|
||||||
self.screens = screens
|
|
||||||
self.image_manager = ImageManager()
|
|
||||||
self.display = MainDisplay(self, screens, False)
|
|
||||||
self.display.imageManager = self.image_manager
|
|
||||||
self.theme_manager = theme_manager
|
|
||||||
self.renderer = Renderer()
|
|
||||||
self.calculate_default(self.screens.current[u'size'])
|
|
||||||
self.theme = u''
|
|
||||||
self.service_theme = u''
|
|
||||||
self.theme_level = u''
|
|
||||||
self.override_background = None
|
|
||||||
self.theme_data = None
|
|
||||||
self.force_page = False
|
|
||||||
|
|
||||||
def update_display(self):
|
|
||||||
"""
|
|
||||||
Updates the render manager's information about the current screen.
|
|
||||||
"""
|
|
||||||
log.debug(u'Update Display')
|
|
||||||
self.calculate_default(self.screens.current[u'size'])
|
|
||||||
self.display = MainDisplay(self, self.screens, False)
|
|
||||||
self.display.imageManager = self.image_manager
|
|
||||||
self.display.setup()
|
|
||||||
self.renderer.bg_frame = None
|
|
||||||
self.theme_data = None
|
|
||||||
self.image_manager.update_display(self.width, self.height)
|
|
||||||
|
|
||||||
def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global):
|
|
||||||
"""
|
|
||||||
Set the global-level theme and the theme level.
|
|
||||||
|
|
||||||
``global_theme``
|
|
||||||
The global-level theme to be set.
|
|
||||||
|
|
||||||
``theme_level``
|
|
||||||
Defaults to *``ThemeLevel.Global``*. The theme level, can be
|
|
||||||
``ThemeLevel.Global``, ``ThemeLevel.Service`` or
|
|
||||||
``ThemeLevel.Song``.
|
|
||||||
"""
|
|
||||||
self.global_theme = global_theme
|
|
||||||
self.theme_level = theme_level
|
|
||||||
self.global_theme_data = \
|
|
||||||
self.theme_manager.getThemeData(self.global_theme)
|
|
||||||
self.theme_data = None
|
|
||||||
|
|
||||||
def set_service_theme(self, service_theme):
|
|
||||||
"""
|
|
||||||
Set the service-level theme.
|
|
||||||
|
|
||||||
``service_theme``
|
|
||||||
The service-level theme to be set.
|
|
||||||
"""
|
|
||||||
self.service_theme = service_theme
|
|
||||||
self.theme_data = None
|
|
||||||
|
|
||||||
def set_override_theme(self, theme, overrideLevels=False):
|
|
||||||
"""
|
|
||||||
Set the appropriate theme depending on the theme level.
|
|
||||||
Called by the service item when building a display frame
|
|
||||||
|
|
||||||
``theme``
|
|
||||||
The name of the song-level theme. None means the service
|
|
||||||
item wants to use the given value.
|
|
||||||
|
|
||||||
``overrideLevels``
|
|
||||||
Used to force the theme data passed in to be used.
|
|
||||||
|
|
||||||
"""
|
|
||||||
log.debug(u'set override theme to %s', theme)
|
|
||||||
theme_level = self.theme_level
|
|
||||||
if overrideLevels:
|
|
||||||
theme_level = ThemeLevel.Song
|
|
||||||
if theme_level == ThemeLevel.Global:
|
|
||||||
self.theme = self.global_theme
|
|
||||||
elif theme_level == ThemeLevel.Service:
|
|
||||||
if self.service_theme == u'':
|
|
||||||
self.theme = self.global_theme
|
|
||||||
else:
|
|
||||||
self.theme = self.service_theme
|
|
||||||
else:
|
|
||||||
# Images have a theme of -1
|
|
||||||
if theme and theme != -1:
|
|
||||||
self.theme = theme
|
|
||||||
elif theme_level == ThemeLevel.Song or \
|
|
||||||
theme_level == ThemeLevel.Service:
|
|
||||||
if self.service_theme == u'':
|
|
||||||
self.theme = self.global_theme
|
|
||||||
else:
|
|
||||||
self.theme = self.service_theme
|
|
||||||
else:
|
|
||||||
self.theme = self.global_theme
|
|
||||||
if self.theme != self.renderer.theme_name or self.theme_data is None \
|
|
||||||
or overrideLevels:
|
|
||||||
log.debug(u'theme is now %s', self.theme)
|
|
||||||
# Force the theme to be the one passed in.
|
|
||||||
if overrideLevels:
|
|
||||||
self.theme_data = theme
|
|
||||||
else:
|
|
||||||
self.theme_data = self.theme_manager.getThemeData(self.theme)
|
|
||||||
self.calculate_default(self.screens.current[u'size'])
|
|
||||||
self.renderer.set_theme(self.theme_data)
|
|
||||||
self.build_text_rectangle(self.theme_data)
|
|
||||||
self.image_manager.add_image(self.theme_data.theme_name,
|
|
||||||
self.theme_data.background_filename)
|
|
||||||
return self.renderer._rect, self.renderer._rect_footer
|
|
||||||
|
|
||||||
def build_text_rectangle(self, theme):
|
|
||||||
"""
|
|
||||||
Builds a text block using the settings in ``theme``
|
|
||||||
and the size of the display screen.height.
|
|
||||||
|
|
||||||
``theme``
|
|
||||||
The theme to build a text block for.
|
|
||||||
"""
|
|
||||||
log.debug(u'build_text_rectangle')
|
|
||||||
main_rect = None
|
|
||||||
footer_rect = None
|
|
||||||
if not theme.font_main_override:
|
|
||||||
main_rect = QtCore.QRect(10, 0, self.width - 20, self.footer_start)
|
|
||||||
else:
|
|
||||||
main_rect = QtCore.QRect(theme.font_main_x, theme.font_main_y,
|
|
||||||
theme.font_main_width - 1, theme.font_main_height - 1)
|
|
||||||
if not theme.font_footer_override:
|
|
||||||
footer_rect = QtCore.QRect(10, self.footer_start, self.width - 20,
|
|
||||||
self.height - self.footer_start)
|
|
||||||
else:
|
|
||||||
footer_rect = QtCore.QRect(theme.font_footer_x,
|
|
||||||
theme.font_footer_y, theme.font_footer_width - 1,
|
|
||||||
theme.font_footer_height - 1)
|
|
||||||
self.renderer.set_text_rectangle(main_rect, footer_rect)
|
|
||||||
|
|
||||||
def generate_preview(self, theme_data, force_page=False):
|
|
||||||
"""
|
|
||||||
Generate a preview of a theme.
|
|
||||||
|
|
||||||
``theme_data``
|
|
||||||
The theme to generated a preview for.
|
|
||||||
|
|
||||||
``force_page``
|
|
||||||
Flag to tell message lines per page need to be generated.
|
|
||||||
"""
|
|
||||||
log.debug(u'generate preview')
|
|
||||||
# save value for use in format_slide
|
|
||||||
self.force_page = force_page
|
|
||||||
# set the default image size for previews
|
|
||||||
self.calculate_default(self.screens.preview[u'size'])
|
|
||||||
# build a service item to generate preview
|
|
||||||
serviceItem = ServiceItem()
|
|
||||||
serviceItem.theme = theme_data
|
|
||||||
if self.force_page:
|
|
||||||
# make big page for theme edit dialog to get line count
|
|
||||||
serviceItem.add_from_text(u'', VERSE + VERSE + VERSE, FOOTER)
|
|
||||||
else:
|
|
||||||
self.image_manager.del_image(theme_data.theme_name)
|
|
||||||
serviceItem.add_from_text(u'', VERSE, FOOTER)
|
|
||||||
serviceItem.render_manager = self
|
|
||||||
serviceItem.raw_footer = FOOTER
|
|
||||||
serviceItem.render(True)
|
|
||||||
if not self.force_page:
|
|
||||||
self.display.buildHtml(serviceItem)
|
|
||||||
raw_html = serviceItem.get_rendered_frame(0)
|
|
||||||
preview = self.display.text(raw_html)
|
|
||||||
# Reset the real screen size for subsequent render requests
|
|
||||||
self.calculate_default(self.screens.current[u'size'])
|
|
||||||
return preview
|
|
||||||
|
|
||||||
def format_slide(self, words, line_break):
|
|
||||||
"""
|
|
||||||
Calculate how much text can fit on a slide.
|
|
||||||
|
|
||||||
``words``
|
|
||||||
The words to go on the slides.
|
|
||||||
|
|
||||||
``line_break``
|
|
||||||
Add line endings after each line of text used for bibles.
|
|
||||||
"""
|
|
||||||
log.debug(u'format slide')
|
|
||||||
return self.renderer.format_slide(words, line_break, self.force_page)
|
|
||||||
|
|
||||||
def calculate_default(self, screen):
|
|
||||||
"""
|
|
||||||
Calculate the default dimentions of the screen.
|
|
||||||
|
|
||||||
``screen``
|
|
||||||
The QSize of the screen.
|
|
||||||
"""
|
|
||||||
log.debug(u'calculate default %s', screen)
|
|
||||||
self.width = screen.width()
|
|
||||||
self.height = screen.height()
|
|
||||||
self.screen_ratio = float(self.height) / float(self.width)
|
|
||||||
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)
|
|
@ -63,6 +63,8 @@ class ItemCapabilities(object):
|
|||||||
ProvidesOwnDisplay = 10
|
ProvidesOwnDisplay = 10
|
||||||
AllowsDetailedTitleDisplay = 11
|
AllowsDetailedTitleDisplay = 11
|
||||||
AllowsVariableStartTime = 12
|
AllowsVariableStartTime = 12
|
||||||
|
AllowsVirtualSplit = 13
|
||||||
|
AllowsWordSplit = 14
|
||||||
|
|
||||||
|
|
||||||
class ServiceItem(object):
|
class ServiceItem(object):
|
||||||
@ -81,7 +83,7 @@ class ServiceItem(object):
|
|||||||
The plugin that this service item belongs to.
|
The plugin that this service item belongs to.
|
||||||
"""
|
"""
|
||||||
if plugin:
|
if plugin:
|
||||||
self.render_manager = plugin.renderManager
|
self.renderer = plugin.renderer
|
||||||
self.name = plugin.name
|
self.name = plugin.name
|
||||||
self.title = u''
|
self.title = u''
|
||||||
self.shortname = u''
|
self.shortname = u''
|
||||||
@ -151,7 +153,7 @@ class ServiceItem(object):
|
|||||||
self.icon = icon
|
self.icon = icon
|
||||||
self.iconic_representation = build_icon(icon)
|
self.iconic_representation = build_icon(icon)
|
||||||
|
|
||||||
def render(self, useOverride=False):
|
def render(self, use_override=False):
|
||||||
"""
|
"""
|
||||||
The render method is what generates the frames for the screen and
|
The render method is what generates the frames for the screen and
|
||||||
obtains the display information from the renderemanager.
|
obtains the display information from the renderemanager.
|
||||||
@ -161,24 +163,23 @@ class ServiceItem(object):
|
|||||||
log.debug(u'Render called')
|
log.debug(u'Render called')
|
||||||
self._display_frames = []
|
self._display_frames = []
|
||||||
self.bg_image_bytes = None
|
self.bg_image_bytes = None
|
||||||
line_break = True
|
line_break = not self.is_capable(ItemCapabilities.NoLineBreaks)
|
||||||
if self.is_capable(ItemCapabilities.NoLineBreaks):
|
|
||||||
line_break = False
|
|
||||||
theme = self.theme if self.theme else None
|
theme = self.theme if self.theme else None
|
||||||
self.main, self.footer = \
|
self.main, self.footer = \
|
||||||
self.render_manager.set_override_theme(theme, useOverride)
|
self.renderer.set_override_theme(theme, use_override)
|
||||||
self.themedata = self.render_manager.renderer._theme
|
self.themedata = self.renderer.theme_data
|
||||||
if self.service_item_type == ServiceItemType.Text:
|
if self.service_item_type == ServiceItemType.Text:
|
||||||
log.debug(u'Formatting slides')
|
log.debug(u'Formatting slides')
|
||||||
for slide in self._raw_frames:
|
for slide in self._raw_frames:
|
||||||
formatted = self.render_manager \
|
formatted = self.renderer \
|
||||||
.format_slide(slide[u'raw_slide'], line_break)
|
.format_slide(slide[u'raw_slide'], line_break, self)
|
||||||
for page in formatted:
|
for page in formatted:
|
||||||
self._display_frames.append(
|
self._display_frames.append({
|
||||||
{u'title': clean_tags(page),
|
u'title': clean_tags(page),
|
||||||
u'text': clean_tags(page.rstrip()),
|
u'text': clean_tags(page.rstrip()),
|
||||||
u'html': expand_tags(page.rstrip()),
|
u'html': expand_tags(page.rstrip()),
|
||||||
u'verseTag': slide[u'verseTag'] })
|
u'verseTag': slide[u'verseTag']
|
||||||
|
})
|
||||||
elif self.service_item_type == ServiceItemType.Image or \
|
elif self.service_item_type == ServiceItemType.Image or \
|
||||||
self.service_item_type == ServiceItemType.Command:
|
self.service_item_type == ServiceItemType.Command:
|
||||||
pass
|
pass
|
||||||
@ -205,7 +206,7 @@ class ServiceItem(object):
|
|||||||
"""
|
"""
|
||||||
self.service_item_type = ServiceItemType.Image
|
self.service_item_type = ServiceItemType.Image
|
||||||
self._raw_frames.append({u'title': title, u'path': path})
|
self._raw_frames.append({u'title': title, u'path': path})
|
||||||
self.render_manager.image_manager.add_image(title, path)
|
self.renderer.image_manager.add_image(title, path)
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
|
||||||
def add_from_text(self, title, raw_slide, verse_tag=None):
|
def add_from_text(self, title, raw_slide, verse_tag=None):
|
||||||
@ -441,10 +442,10 @@ class ServiceItem(object):
|
|||||||
start = None
|
start = None
|
||||||
end = None
|
end = None
|
||||||
if self.start_time != 0:
|
if self.start_time != 0:
|
||||||
start = UiStrings.StartTimeCode % \
|
start = UiStrings().StartTimeCode % \
|
||||||
unicode(datetime.timedelta(seconds=self.start_time))
|
unicode(datetime.timedelta(seconds=self.start_time))
|
||||||
if self.media_length != 0:
|
if self.media_length != 0:
|
||||||
end = UiStrings.LengthTime % \
|
end = UiStrings().LengthTime % \
|
||||||
unicode(datetime.timedelta(seconds=self.media_length))
|
unicode(datetime.timedelta(seconds=self.media_length))
|
||||||
if not start and not end:
|
if not start and not end:
|
||||||
return None
|
return None
|
||||||
@ -454,3 +455,4 @@ class ServiceItem(object):
|
|||||||
return end
|
return end
|
||||||
else:
|
else:
|
||||||
return u'%s : %s' % (start, end)
|
return u'%s : %s' % (start, end)
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ class VerticalType(object):
|
|||||||
Bottom = 2
|
Bottom = 2
|
||||||
|
|
||||||
Names = [u'top', u'middle', u'bottom']
|
Names = [u'top', u'middle', u'bottom']
|
||||||
TranslatedNames = [UiStrings.Top, UiStrings.Middle, UiStrings.Bottom]
|
TranslatedNames = [UiStrings().Top, UiStrings().Middle, UiStrings().Bottom]
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow',
|
BOOLEAN_LIST = [u'bold', u'italics', u'override', u'outline', u'shadow',
|
||||||
|
@ -39,78 +39,96 @@ class UiStrings(object):
|
|||||||
"""
|
"""
|
||||||
Provide standard strings for objects to use.
|
Provide standard strings for objects to use.
|
||||||
"""
|
"""
|
||||||
# These strings should need a good reason to be retranslated elsewhere.
|
__instance__ = None
|
||||||
# Should some/more/less of these have an & attached?
|
|
||||||
About = translate('OpenLP.Ui', 'About')
|
def __new__(cls):
|
||||||
Add = translate('OpenLP.Ui', '&Add')
|
"""
|
||||||
Advanced = translate('OpenLP.Ui', 'Advanced')
|
Override the default object creation method to return a single instance.
|
||||||
AllFiles = translate('OpenLP.Ui', 'All Files')
|
"""
|
||||||
Bottom = translate('OpenLP.Ui', 'Bottom')
|
if not cls.__instance__:
|
||||||
Browse = translate('OpenLP.Ui', 'Browse...')
|
cls.__instance__ = object.__new__(cls)
|
||||||
Cancel = translate('OpenLP.Ui', 'Cancel')
|
return cls.__instance__
|
||||||
CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:')
|
|
||||||
CreateService = translate('OpenLP.Ui', 'Create a new service.')
|
def __init__(self):
|
||||||
Continuous = translate('OpenLP.Ui', 'Continuous')
|
"""
|
||||||
Default = unicode(translate('OpenLP.Ui', 'Default'))
|
These strings should need a good reason to be retranslated elsewhere.
|
||||||
Delete = translate('OpenLP.Ui', '&Delete')
|
Should some/more/less of these have an & attached?
|
||||||
DisplayStyle = translate('OpenLP.Ui', 'Display style:')
|
"""
|
||||||
Edit = translate('OpenLP.Ui', '&Edit')
|
self.About = translate('OpenLP.Ui', 'About')
|
||||||
EmptyField = translate('OpenLP.Ui', 'Empty Field')
|
self.Add = translate('OpenLP.Ui', '&Add')
|
||||||
Error = translate('OpenLP.Ui', 'Error')
|
self.Advanced = translate('OpenLP.Ui', 'Advanced')
|
||||||
Export = translate('OpenLP.Ui', 'Export')
|
self.AllFiles = translate('OpenLP.Ui', 'All Files')
|
||||||
File = translate('OpenLP.Ui', 'File')
|
self.Bottom = translate('OpenLP.Ui', 'Bottom')
|
||||||
FontSizePtUnit = translate('OpenLP.Ui', 'pt',
|
self.Browse = translate('OpenLP.Ui', 'Browse...')
|
||||||
'Abbreviated font pointsize unit')
|
self.Cancel = translate('OpenLP.Ui', 'Cancel')
|
||||||
Help = translate('OpenLP.Ui', 'Help')
|
self.CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:')
|
||||||
Hours = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours')
|
self.CreateService = translate('OpenLP.Ui', 'Create a new service.')
|
||||||
Image = translate('OpenLP.Ui', 'Image')
|
self.Continuous = translate('OpenLP.Ui', 'Continuous')
|
||||||
Import = translate('OpenLP.Ui', 'Import')
|
self.Default = unicode(translate('OpenLP.Ui', 'Default'))
|
||||||
LayoutStyle = translate('OpenLP.Ui', 'Layout style:')
|
self.Delete = translate('OpenLP.Ui', '&Delete')
|
||||||
LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
|
self.DisplayStyle = translate('OpenLP.Ui', 'Display style:')
|
||||||
Live = translate('OpenLP.Ui', 'Live')
|
self.Edit = translate('OpenLP.Ui', '&Edit')
|
||||||
LiveBGError = translate('OpenLP.Ui', 'Live Background Error')
|
self.EmptyField = translate('OpenLP.Ui', 'Empty Field')
|
||||||
LivePanel = translate('OpenLP.Ui', 'Live Panel')
|
self.Error = translate('OpenLP.Ui', 'Error')
|
||||||
LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar')
|
self.Export = translate('OpenLP.Ui', 'Export')
|
||||||
Load = translate('OpenLP.Ui', 'Load')
|
self.File = translate('OpenLP.Ui', 'File')
|
||||||
Minutes = translate('OpenLP.Ui', 'm', 'The abbreviated unit for minutes')
|
self.FontSizePtUnit = translate('OpenLP.Ui', 'pt',
|
||||||
Middle = translate('OpenLP.Ui', 'Middle')
|
'Abbreviated font pointsize unit')
|
||||||
New = translate('OpenLP.Ui', 'New')
|
self.Help = translate('OpenLP.Ui', 'Help')
|
||||||
NewService = translate('OpenLP.Ui', 'New Service')
|
self.Hours = translate('OpenLP.Ui', 'h',
|
||||||
NewTheme = translate('OpenLP.Ui', 'New Theme')
|
'The abbreviated unit for hours')
|
||||||
NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular')
|
self.Image = translate('OpenLP.Ui', 'Image')
|
||||||
NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
|
self.Import = translate('OpenLP.Ui', 'Import')
|
||||||
NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
|
self.LayoutStyle = translate('OpenLP.Ui', 'Layout style:')
|
||||||
NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
|
self.LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
|
||||||
OLPV1 = translate('OpenLP.Ui', 'openlp.org 1.x')
|
self.Live = translate('OpenLP.Ui', 'Live')
|
||||||
OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0')
|
self.LiveBGError = translate('OpenLP.Ui', 'Live Background Error')
|
||||||
OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you '
|
self.LivePanel = translate('OpenLP.Ui', 'Live Panel')
|
||||||
'wish to continue?')
|
self.LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar')
|
||||||
OpenService = translate('OpenLP.Ui', 'Open Service')
|
self.Load = translate('OpenLP.Ui', 'Load')
|
||||||
Preview = translate('OpenLP.Ui', 'Preview')
|
self.Minutes = translate('OpenLP.Ui', 'm',
|
||||||
PreviewPanel = translate('OpenLP.Ui', 'Preview Panel')
|
'The abbreviated unit for minutes')
|
||||||
PrintServiceOrder = translate('OpenLP.Ui', 'Print Service Order')
|
self.Middle = translate('OpenLP.Ui', 'Middle')
|
||||||
ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
|
self.New = translate('OpenLP.Ui', 'New')
|
||||||
ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background')
|
self.NewService = translate('OpenLP.Ui', 'New Service')
|
||||||
ResetBG = translate('OpenLP.Ui', 'Reset Background')
|
self.NewTheme = translate('OpenLP.Ui', 'New Theme')
|
||||||
ResetLiveBG = translate('OpenLP.Ui', 'Reset Live Background')
|
self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular')
|
||||||
Seconds = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds')
|
self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
|
||||||
SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview')
|
self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
|
||||||
Search = translate('OpenLP.Ui', 'Search')
|
self.NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
|
||||||
SelectDelete = translate('OpenLP.Ui', 'You must select an item to delete.')
|
self.OLPV1 = translate('OpenLP.Ui', 'openlp.org 1.x')
|
||||||
SelectEdit = translate('OpenLP.Ui', 'You must select an item to edit.')
|
self.OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0')
|
||||||
Settings = translate('OpenLP.Ui', 'Settings')
|
self.OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. '
|
||||||
SaveService = translate('OpenLP.Ui', 'Save Service')
|
'Do you wish to continue?')
|
||||||
Service = translate('OpenLP.Ui', 'Service')
|
self.OpenService = translate('OpenLP.Ui', 'Open Service')
|
||||||
StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s'))
|
self.Preview = translate('OpenLP.Ui', 'Preview')
|
||||||
Theme = translate('OpenLP.Ui', 'Theme', 'Singular')
|
self.PreviewPanel = translate('OpenLP.Ui', 'Preview Panel')
|
||||||
Themes = translate('OpenLP.Ui', 'Themes', 'Plural')
|
self.PrintServiceOrder = translate('OpenLP.Ui', 'Print Service Order')
|
||||||
Tools = translate('OpenLP.Ui', 'Tools')
|
self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
|
||||||
Top = translate('OpenLP.Ui', 'Top')
|
self.ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background')
|
||||||
VersePerSlide = translate('OpenLP.Ui', 'Verse Per Slide')
|
self.ResetBG = translate('OpenLP.Ui', 'Reset Background')
|
||||||
VersePerLine = translate('OpenLP.Ui', 'Verse Per Line')
|
self.ResetLiveBG = translate('OpenLP.Ui', 'Reset Live Background')
|
||||||
Version = translate('OpenLP.Ui', 'Version')
|
self.Seconds = translate('OpenLP.Ui', 's',
|
||||||
View = translate('OpenLP.Ui', 'View')
|
'The abbreviated unit for seconds')
|
||||||
ViewMode = translate('OpenLP.Ui', 'View Model')
|
self.SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview')
|
||||||
|
self.Search = translate('OpenLP.Ui', 'Search')
|
||||||
|
self.SelectDelete = translate('OpenLP.Ui', 'You must select an item '
|
||||||
|
'to delete.')
|
||||||
|
self.SelectEdit = translate('OpenLP.Ui', 'You must select an item to '
|
||||||
|
'edit.')
|
||||||
|
self.Settings = translate('OpenLP.Ui', 'Settings')
|
||||||
|
self.SaveService = translate('OpenLP.Ui', 'Save Service')
|
||||||
|
self.Service = translate('OpenLP.Ui', 'Service')
|
||||||
|
self.StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s'))
|
||||||
|
self.Theme = translate('OpenLP.Ui', 'Theme', 'Singular')
|
||||||
|
self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural')
|
||||||
|
self.Tools = translate('OpenLP.Ui', 'Tools')
|
||||||
|
self.Top = translate('OpenLP.Ui', 'Top')
|
||||||
|
self.VersePerSlide = translate('OpenLP.Ui', 'Verse Per Slide')
|
||||||
|
self.VersePerLine = translate('OpenLP.Ui', 'Verse Per Line')
|
||||||
|
self.Version = translate('OpenLP.Ui', 'Version')
|
||||||
|
self.View = translate('OpenLP.Ui', 'View')
|
||||||
|
self.ViewMode = translate('OpenLP.Ui', 'View Model')
|
||||||
|
|
||||||
def add_welcome_page(parent, image):
|
def add_welcome_page(parent, image):
|
||||||
"""
|
"""
|
||||||
@ -157,7 +175,8 @@ def create_accept_reject_button_box(parent, okay=False):
|
|||||||
accept_button = QtGui.QDialogButtonBox.Save
|
accept_button = QtGui.QDialogButtonBox.Save
|
||||||
if okay:
|
if okay:
|
||||||
accept_button = QtGui.QDialogButtonBox.Ok
|
accept_button = QtGui.QDialogButtonBox.Ok
|
||||||
button_box.setStandardButtons(accept_button | QtGui.QDialogButtonBox.Cancel)
|
button_box.setStandardButtons(
|
||||||
|
accept_button | QtGui.QDialogButtonBox.Cancel)
|
||||||
button_box.setObjectName(u'%sButtonBox' % parent)
|
button_box.setObjectName(u'%sButtonBox' % parent)
|
||||||
QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'accepted()'),
|
QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'accepted()'),
|
||||||
parent.accept)
|
parent.accept)
|
||||||
@ -184,11 +203,11 @@ def critical_error_message_box(title=None, message=None, parent=None,
|
|||||||
Should this message box question the user.
|
Should this message box question the user.
|
||||||
"""
|
"""
|
||||||
if question:
|
if question:
|
||||||
return QtGui.QMessageBox.critical(parent, UiStrings.Error, message,
|
return QtGui.QMessageBox.critical(parent, UiStrings().Error, message,
|
||||||
QtGui.QMessageBox.StandardButtons(
|
QtGui.QMessageBox.StandardButtons(
|
||||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
||||||
data = {u'message': message}
|
data = {u'message': message}
|
||||||
data[u'title'] = title if title else UiStrings.Error
|
data[u'title'] = title if title else UiStrings().Error
|
||||||
return Receiver.send_message(u'openlp_error_message', data)
|
return Receiver.send_message(u'openlp_error_message', data)
|
||||||
|
|
||||||
def media_item_combo_box(parent, name):
|
def media_item_combo_box(parent, name):
|
||||||
@ -218,7 +237,7 @@ def create_delete_push_button(parent, icon=None):
|
|||||||
delete_button.setObjectName(u'deleteButton')
|
delete_button.setObjectName(u'deleteButton')
|
||||||
delete_icon = icon if icon else u':/general/general_delete.png'
|
delete_icon = icon if icon else u':/general/general_delete.png'
|
||||||
delete_button.setIcon(build_icon(delete_icon))
|
delete_button.setIcon(build_icon(delete_icon))
|
||||||
delete_button.setText(UiStrings.Delete)
|
delete_button.setText(UiStrings().Delete)
|
||||||
delete_button.setToolTip(
|
delete_button.setToolTip(
|
||||||
translate('OpenLP.Ui', 'Delete the selected item.'))
|
translate('OpenLP.Ui', 'Delete the selected item.'))
|
||||||
QtCore.QObject.connect(delete_button,
|
QtCore.QObject.connect(delete_button,
|
||||||
@ -304,7 +323,7 @@ def shortcut_action(parent, name, shortcuts, function, icon=None, checked=None,
|
|||||||
action.setShortcutContext(context)
|
action.setShortcutContext(context)
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_action(action, category)
|
action_list.add_action(action, category)
|
||||||
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), function)
|
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), function)
|
||||||
return action
|
return action
|
||||||
|
|
||||||
def context_menu_action(base, icon, text, slot, shortcuts=None, category=None,
|
def context_menu_action(base, icon, text, slot, shortcuts=None, category=None,
|
||||||
@ -337,7 +356,7 @@ def context_menu_action(base, icon, text, slot, shortcuts=None, category=None,
|
|||||||
action = QtGui.QAction(text, base)
|
action = QtGui.QAction(text, base)
|
||||||
if icon:
|
if icon:
|
||||||
action.setIcon(build_icon(icon))
|
action.setIcon(build_icon(icon))
|
||||||
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), slot)
|
QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), slot)
|
||||||
if shortcuts is not None:
|
if shortcuts is not None:
|
||||||
action.setShortcuts(shortcuts)
|
action.setShortcuts(shortcuts)
|
||||||
action.setShortcutContext(context)
|
action.setShortcutContext(context)
|
||||||
@ -406,9 +425,9 @@ def create_valign_combo(form, parent, layout):
|
|||||||
verticalLabel.setText(translate('OpenLP.Ui', '&Vertical Align:'))
|
verticalLabel.setText(translate('OpenLP.Ui', '&Vertical Align:'))
|
||||||
form.verticalComboBox = QtGui.QComboBox(parent)
|
form.verticalComboBox = QtGui.QComboBox(parent)
|
||||||
form.verticalComboBox.setObjectName(u'VerticalComboBox')
|
form.verticalComboBox.setObjectName(u'VerticalComboBox')
|
||||||
form.verticalComboBox.addItem(UiStrings.Top)
|
form.verticalComboBox.addItem(UiStrings().Top)
|
||||||
form.verticalComboBox.addItem(UiStrings.Middle)
|
form.verticalComboBox.addItem(UiStrings().Middle)
|
||||||
form.verticalComboBox.addItem(UiStrings.Bottom)
|
form.verticalComboBox.addItem(UiStrings().Bottom)
|
||||||
verticalLabel.setBuddy(form.verticalComboBox)
|
verticalLabel.setBuddy(form.verticalComboBox)
|
||||||
layout.addRow(verticalLabel, form.verticalComboBox)
|
layout.addRow(verticalLabel, form.verticalComboBox)
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ class Ui_AboutDialog(object):
|
|||||||
QtCore.QMetaObject.connectSlotsByName(aboutDialog)
|
QtCore.QMetaObject.connectSlotsByName(aboutDialog)
|
||||||
|
|
||||||
def retranslateUi(self, aboutDialog):
|
def retranslateUi(self, aboutDialog):
|
||||||
aboutDialog.setWindowTitle(u'%s OpenLP' % UiStrings.About)
|
aboutDialog.setWindowTitle(u'%s OpenLP' % UiStrings().About)
|
||||||
self.aboutTextEdit.setPlainText(translate('OpenLP.AboutForm',
|
self.aboutTextEdit.setPlainText(translate('OpenLP.AboutForm',
|
||||||
'OpenLP <version><revision> - Open Source Lyrics '
|
'OpenLP <version><revision> - Open Source Lyrics '
|
||||||
'Projection\n'
|
'Projection\n'
|
||||||
@ -105,7 +105,7 @@ class Ui_AboutDialog(object):
|
|||||||
'consider contributing by using the button below.'
|
'consider contributing by using the button below.'
|
||||||
))
|
))
|
||||||
self.aboutNotebook.setTabText(
|
self.aboutNotebook.setTabText(
|
||||||
self.aboutNotebook.indexOf(self.aboutTab), UiStrings.About)
|
self.aboutNotebook.indexOf(self.aboutTab), UiStrings().About)
|
||||||
lead = u'Raoul "superfly" Snyman'
|
lead = u'Raoul "superfly" Snyman'
|
||||||
developers = [u'Tim "TRB143" Bentley', u'Jonathan "gushie" Corwin',
|
developers = [u'Tim "TRB143" Bentley', u'Jonathan "gushie" Corwin',
|
||||||
u'Michael "cocooncrash" Gorven',
|
u'Michael "cocooncrash" Gorven',
|
||||||
@ -615,4 +615,4 @@ class Ui_AboutDialog(object):
|
|||||||
self.aboutNotebook.indexOf(self.licenseTab),
|
self.aboutNotebook.indexOf(self.licenseTab),
|
||||||
translate('OpenLP.AboutForm', 'License'))
|
translate('OpenLP.AboutForm', 'License'))
|
||||||
self.contributeButton.setText(translate('OpenLP.AboutForm',
|
self.contributeButton.setText(translate('OpenLP.AboutForm',
|
||||||
'Contribute'))
|
'Contribute'))
|
@ -41,11 +41,11 @@ class AdvancedTab(SettingsTab):
|
|||||||
"""
|
"""
|
||||||
Initialise the settings tab
|
Initialise the settings tab
|
||||||
"""
|
"""
|
||||||
generalTranslated = translate('AdvancedTab', 'Advanced')
|
advancedTranslated = translate('OpenLP.AdvancedTab', 'Advanced')
|
||||||
SettingsTab.__init__(self, parent ,u'Advanced', generalTranslated)
|
|
||||||
self.default_image = u':/graphics/openlp-splash-screen.png'
|
self.default_image = u':/graphics/openlp-splash-screen.png'
|
||||||
self.default_color = u'#ffffff'
|
self.default_color = u'#ffffff'
|
||||||
self.icon_path = u':/system/system_settings.png'
|
self.icon_path = u':/system/system_settings.png'
|
||||||
|
SettingsTab.__init__(self, parent, u'Advanced', advancedTranslated)
|
||||||
|
|
||||||
def setupUi(self):
|
def setupUi(self):
|
||||||
"""
|
"""
|
||||||
@ -82,14 +82,6 @@ class AdvancedTab(SettingsTab):
|
|||||||
u'enableAutoCloseCheckBox')
|
u'enableAutoCloseCheckBox')
|
||||||
self.uiLayout.addRow(self.enableAutoCloseCheckBox)
|
self.uiLayout.addRow(self.enableAutoCloseCheckBox)
|
||||||
self.leftLayout.addWidget(self.uiGroupBox)
|
self.leftLayout.addWidget(self.uiGroupBox)
|
||||||
self.hideMouseGroupBox = QtGui.QGroupBox(self.leftColumn)
|
|
||||||
self.hideMouseGroupBox.setObjectName(u'hideMouseGroupBox')
|
|
||||||
self.hideMouseLayout = QtGui.QVBoxLayout(self.hideMouseGroupBox)
|
|
||||||
self.hideMouseLayout.setObjectName(u'hideMouseLayout')
|
|
||||||
self.hideMouseCheckBox = QtGui.QCheckBox(self.hideMouseGroupBox)
|
|
||||||
self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
|
|
||||||
self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
|
|
||||||
self.leftLayout.addWidget(self.hideMouseGroupBox)
|
|
||||||
self.leftLayout.addStretch()
|
self.leftLayout.addStretch()
|
||||||
self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn)
|
self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||||
self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox')
|
self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox')
|
||||||
@ -109,26 +101,42 @@ class AdvancedTab(SettingsTab):
|
|||||||
self.defaultBrowseButton.setObjectName(u'defaultBrowseButton')
|
self.defaultBrowseButton.setObjectName(u'defaultBrowseButton')
|
||||||
self.defaultBrowseButton.setIcon(
|
self.defaultBrowseButton.setIcon(
|
||||||
build_icon(u':/general/general_open.png'))
|
build_icon(u':/general/general_open.png'))
|
||||||
|
self.defaultRevertButton = QtGui.QToolButton(self.defaultImageGroupBox)
|
||||||
|
self.defaultRevertButton.setObjectName(u'defaultRevertButton')
|
||||||
|
self.defaultRevertButton.setIcon(
|
||||||
|
build_icon(u':/general/general_revert.png'))
|
||||||
self.defaultFileLayout = QtGui.QHBoxLayout()
|
self.defaultFileLayout = QtGui.QHBoxLayout()
|
||||||
self.defaultFileLayout.setObjectName(u'defaultFileLayout')
|
self.defaultFileLayout.setObjectName(u'defaultFileLayout')
|
||||||
self.defaultFileLayout.addWidget(self.defaultFileEdit)
|
self.defaultFileLayout.addWidget(self.defaultFileEdit)
|
||||||
self.defaultFileLayout.addWidget(self.defaultBrowseButton)
|
self.defaultFileLayout.addWidget(self.defaultBrowseButton)
|
||||||
|
self.defaultFileLayout.addWidget(self.defaultRevertButton)
|
||||||
self.defaultImageLayout.addRow(self.defaultFileLabel,
|
self.defaultImageLayout.addRow(self.defaultFileLabel,
|
||||||
self.defaultFileLayout)
|
self.defaultFileLayout)
|
||||||
self.rightLayout.addWidget(self.defaultImageGroupBox)
|
self.rightLayout.addWidget(self.defaultImageGroupBox)
|
||||||
|
self.hideMouseGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||||
|
self.hideMouseGroupBox.setObjectName(u'hideMouseGroupBox')
|
||||||
|
self.hideMouseLayout = QtGui.QVBoxLayout(self.hideMouseGroupBox)
|
||||||
|
self.hideMouseLayout.setObjectName(u'hideMouseLayout')
|
||||||
|
self.hideMouseCheckBox = QtGui.QCheckBox(self.hideMouseGroupBox)
|
||||||
|
self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
|
||||||
|
self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
|
||||||
|
self.rightLayout.addWidget(self.hideMouseGroupBox)
|
||||||
self.rightLayout.addStretch()
|
self.rightLayout.addStretch()
|
||||||
|
|
||||||
QtCore.QObject.connect(self.defaultColorButton,
|
QtCore.QObject.connect(self.defaultColorButton,
|
||||||
QtCore.SIGNAL(u'pressed()'), self.onDefaultColorButtonPressed)
|
QtCore.SIGNAL(u'pressed()'), self.onDefaultColorButtonPressed)
|
||||||
QtCore.QObject.connect(self.defaultBrowseButton,
|
QtCore.QObject.connect(self.defaultBrowseButton,
|
||||||
QtCore.SIGNAL(u'pressed()'), self.onDefaultBrowseButtonPressed)
|
QtCore.SIGNAL(u'pressed()'), self.onDefaultBrowseButtonPressed)
|
||||||
|
QtCore.QObject.connect(self.defaultRevertButton,
|
||||||
|
QtCore.SIGNAL(u'pressed()'), self.onDefaultRevertButtonPressed)
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
"""
|
"""
|
||||||
Setup the interface translation strings.
|
Setup the interface translation strings.
|
||||||
"""
|
"""
|
||||||
self.tabTitleVisible = UiStrings.Advanced
|
self.tabTitleVisible = UiStrings().Advanced
|
||||||
self.uiGroupBox.setTitle(translate('OpenLP.AdvancedTab', 'UI Settings'))
|
self.uiGroupBox.setTitle(
|
||||||
|
translate('OpenLP.AdvancedTab', 'UI Settings'))
|
||||||
self.recentLabel.setText(
|
self.recentLabel.setText(
|
||||||
translate('OpenLP.AdvancedTab',
|
translate('OpenLP.AdvancedTab',
|
||||||
'Number of recent files to display:'))
|
'Number of recent files to display:'))
|
||||||
@ -150,8 +158,14 @@ class AdvancedTab(SettingsTab):
|
|||||||
'Default Image'))
|
'Default Image'))
|
||||||
self.defaultColorLabel.setText(translate('OpenLP.AdvancedTab',
|
self.defaultColorLabel.setText(translate('OpenLP.AdvancedTab',
|
||||||
'Background color:'))
|
'Background color:'))
|
||||||
|
self.defaultColorButton.setToolTip(translate('OpenLP.AdvancedTab',
|
||||||
|
'Click to select a color.'))
|
||||||
self.defaultFileLabel.setText(translate('OpenLP.AdvancedTab',
|
self.defaultFileLabel.setText(translate('OpenLP.AdvancedTab',
|
||||||
'Image file:'))
|
'Image file:'))
|
||||||
|
self.defaultBrowseButton.setToolTip(translate('OpenLP.AdvancedTab',
|
||||||
|
'Browse for an image file to display.'))
|
||||||
|
self.defaultRevertButton.setToolTip(translate('OpenLP.AdvancedTab',
|
||||||
|
'Revert to the default OpenLP logo.'))
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
"""
|
"""
|
||||||
@ -226,10 +240,14 @@ class AdvancedTab(SettingsTab):
|
|||||||
|
|
||||||
def onDefaultBrowseButtonPressed(self):
|
def onDefaultBrowseButtonPressed(self):
|
||||||
file_filters = u'%s;;%s (*.*) (*)' % (get_images_filter(),
|
file_filters = u'%s;;%s (*.*) (*)' % (get_images_filter(),
|
||||||
UiStrings.AllFiles)
|
UiStrings().AllFiles)
|
||||||
filename = QtGui.QFileDialog.getOpenFileName(self,
|
filename = QtGui.QFileDialog.getOpenFileName(self,
|
||||||
translate('OpenLP.AdvancedTab', 'Open File'), '',
|
translate('OpenLP.AdvancedTab', 'Open File'), '',
|
||||||
file_filters)
|
file_filters)
|
||||||
if filename:
|
if filename:
|
||||||
self.defaultFileEdit.setText(filename)
|
self.defaultFileEdit.setText(filename)
|
||||||
self.defaultFileEdit.setFocus()
|
self.defaultFileEdit.setFocus()
|
||||||
|
|
||||||
|
def onDefaultRevertButtonPressed(self):
|
||||||
|
self.defaultFileEdit.setText(u':/graphics/openlp-splash-screen.png')
|
||||||
|
self.defaultFileEdit.setFocus()
|
||||||
|
@ -136,10 +136,10 @@ class Ui_DisplayTagDialog(object):
|
|||||||
translate('OpenLP.DisplayTagDialog', 'Start tag'))
|
translate('OpenLP.DisplayTagDialog', 'Start tag'))
|
||||||
self.endTagLabel.setText(
|
self.endTagLabel.setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'End tag'))
|
translate('OpenLP.DisplayTagDialog', 'End tag'))
|
||||||
self.deletePushButton.setText(UiStrings.Delete)
|
self.deletePushButton.setText(UiStrings().Delete)
|
||||||
self.defaultPushButton.setText(
|
self.defaultPushButton.setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'Default'))
|
translate('OpenLP.DisplayTagDialog', 'Default'))
|
||||||
self.newPushButton.setText(UiStrings.New)
|
self.newPushButton.setText(UiStrings().New)
|
||||||
self.tagTableWidget.horizontalHeaderItem(0).setText(
|
self.tagTableWidget.horizontalHeaderItem(0).setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'Description'))
|
translate('OpenLP.DisplayTagDialog', 'Description'))
|
||||||
self.tagTableWidget.horizontalHeaderItem(1).setText(
|
self.tagTableWidget.horizontalHeaderItem(1).setText(
|
||||||
@ -151,4 +151,4 @@ class Ui_DisplayTagDialog(object):
|
|||||||
self.tagTableWidget.setColumnWidth(0, 120)
|
self.tagTableWidget.setColumnWidth(0, 120)
|
||||||
self.tagTableWidget.setColumnWidth(1, 40)
|
self.tagTableWidget.setColumnWidth(1, 40)
|
||||||
self.tagTableWidget.setColumnWidth(2, 240)
|
self.tagTableWidget.setColumnWidth(2, 240)
|
||||||
self.tagTableWidget.setColumnWidth(3, 240)
|
self.tagTableWidget.setColumnWidth(3, 240)
|
@ -178,11 +178,11 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
|
|||||||
self,translate('ImagePlugin.ExceptionDialog',
|
self,translate('ImagePlugin.ExceptionDialog',
|
||||||
'Select Attachment'),
|
'Select Attachment'),
|
||||||
SettingsManager.get_last_dir(u'exceptions'),
|
SettingsManager.get_last_dir(u'exceptions'),
|
||||||
u'%s (*.*) (*)' % UiStrings.AllFiles)
|
u'%s (*.*) (*)' % UiStrings().AllFiles)
|
||||||
log.info(u'New files(s) %s', unicode(files))
|
log.info(u'New files(s) %s', unicode(files))
|
||||||
if files:
|
if files:
|
||||||
self.fileAttachment = unicode(files)
|
self.fileAttachment = unicode(files)
|
||||||
|
|
||||||
def __buttonState(self, state):
|
def __buttonState(self, state):
|
||||||
self.saveReportButton.setEnabled(state)
|
self.saveReportButton.setEnabled(state)
|
||||||
self.sendReportButton.setEnabled(state)
|
self.sendReportButton.setEnabled(state)
|
@ -140,6 +140,8 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
return FirstTimePage.Songs
|
return FirstTimePage.Songs
|
||||||
elif self.currentId() == FirstTimePage.Progress:
|
elif self.currentId() == FirstTimePage.Progress:
|
||||||
return -1
|
return -1
|
||||||
|
elif self.currentId() == FirstTimePage.NoInternet:
|
||||||
|
return FirstTimePage.Progress
|
||||||
else:
|
else:
|
||||||
return self.currentId() + 1
|
return self.currentId() + 1
|
||||||
|
|
||||||
@ -147,11 +149,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
"""
|
"""
|
||||||
Detects Page changes and updates as approprate.
|
Detects Page changes and updates as approprate.
|
||||||
"""
|
"""
|
||||||
if pageId == FirstTimePage.NoInternet:
|
if pageId == FirstTimePage.Defaults:
|
||||||
self.finishButton.setVisible(True)
|
|
||||||
self.finishButton.setEnabled(True)
|
|
||||||
self.nextButton.setVisible(False)
|
|
||||||
elif pageId == FirstTimePage.Defaults:
|
|
||||||
self.themeComboBox.clear()
|
self.themeComboBox.clear()
|
||||||
for iter in xrange(self.themesListWidget.count()):
|
for iter in xrange(self.themesListWidget.count()):
|
||||||
item = self.themesListWidget.item(iter)
|
item = self.themesListWidget.item(iter)
|
||||||
|
@ -238,7 +238,7 @@ class GeneralTab(SettingsTab):
|
|||||||
self.timeoutSpinBox.setSuffix(translate('OpenLP.GeneralTab', ' sec'))
|
self.timeoutSpinBox.setSuffix(translate('OpenLP.GeneralTab', ' sec'))
|
||||||
self.ccliGroupBox.setTitle(
|
self.ccliGroupBox.setTitle(
|
||||||
translate('OpenLP.GeneralTab', 'CCLI Details'))
|
translate('OpenLP.GeneralTab', 'CCLI Details'))
|
||||||
self.numberLabel.setText(UiStrings.CCLINumberLabel)
|
self.numberLabel.setText(UiStrings().CCLINumberLabel)
|
||||||
self.usernameLabel.setText(
|
self.usernameLabel.setText(
|
||||||
translate('OpenLP.GeneralTab', 'SongSelect username:'))
|
translate('OpenLP.GeneralTab', 'SongSelect username:'))
|
||||||
self.passwordLabel.setText(
|
self.passwordLabel.setText(
|
||||||
@ -394,4 +394,4 @@ class GeneralTab(SettingsTab):
|
|||||||
"""
|
"""
|
||||||
Called when the width, height, x position or y position has changed.
|
Called when the width, height, x position or y position has changed.
|
||||||
"""
|
"""
|
||||||
self.overrideChanged = True
|
self.overrideChanged = True
|
@ -34,7 +34,7 @@ from PyQt4 import QtCore, QtGui, QtWebKit
|
|||||||
from PyQt4.phonon import Phonon
|
from PyQt4.phonon import Phonon
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, \
|
from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, \
|
||||||
build_icon, translate
|
translate
|
||||||
|
|
||||||
from openlp.core.ui import HideMode
|
from openlp.core.ui import HideMode
|
||||||
|
|
||||||
@ -69,8 +69,6 @@ class MainDisplay(DisplayWidget):
|
|||||||
self.hideMode = None
|
self.hideMode = None
|
||||||
self.videoHide = False
|
self.videoHide = False
|
||||||
self.override = {}
|
self.override = {}
|
||||||
mainIcon = build_icon(u':/icon/openlp-logo-16x16.png')
|
|
||||||
self.setWindowIcon(mainIcon)
|
|
||||||
self.retranslateUi()
|
self.retranslateUi()
|
||||||
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
|
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
|
||||||
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
|
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
|
||||||
@ -144,7 +142,8 @@ class MainDisplay(DisplayWidget):
|
|||||||
image_file = QtCore.QSettings().value(u'advanced/default image',
|
image_file = QtCore.QSettings().value(u'advanced/default image',
|
||||||
QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\
|
QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\
|
||||||
.toString()
|
.toString()
|
||||||
background_color = QtGui.QColor(QtCore.QSettings().value(
|
background_color = QtGui.QColor()
|
||||||
|
background_color.setNamedColor(QtCore.QSettings().value(
|
||||||
u'advanced/default color',
|
u'advanced/default color',
|
||||||
QtCore.QVariant(u'#ffffff')).toString())
|
QtCore.QVariant(u'#ffffff')).toString())
|
||||||
if not background_color.isValid():
|
if not background_color.isValid():
|
||||||
|
@ -30,7 +30,7 @@ from tempfile import gettempdir
|
|||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import RenderManager, build_icon, OpenLPDockWidget, \
|
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
|
||||||
SettingsManager, PluginManager, Receiver, translate
|
SettingsManager, PluginManager, Receiver, translate
|
||||||
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
|
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
|
||||||
icon_action, shortcut_action
|
icon_action, shortcut_action
|
||||||
@ -71,7 +71,7 @@ class Ui_MainWindow(object):
|
|||||||
mainWindow.setObjectName(u'MainWindow')
|
mainWindow.setObjectName(u'MainWindow')
|
||||||
mainWindow.resize(self.settingsmanager.width,
|
mainWindow.resize(self.settingsmanager.width,
|
||||||
self.settingsmanager.height)
|
self.settingsmanager.height)
|
||||||
mainWindow.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
|
mainWindow.setWindowIcon(build_icon(u':/icon/openlp-logo-64x64.png'))
|
||||||
mainWindow.setDockNestingEnabled(True)
|
mainWindow.setDockNestingEnabled(True)
|
||||||
# Set up the main container, which contains all the other form widgets.
|
# Set up the main container, which contains all the other form widgets.
|
||||||
self.MainContent = QtGui.QWidget(mainWindow)
|
self.MainContent = QtGui.QWidget(mainWindow)
|
||||||
@ -163,82 +163,82 @@ class Ui_MainWindow(object):
|
|||||||
self.themeManagerDock)
|
self.themeManagerDock)
|
||||||
# Create the menu items
|
# Create the menu items
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_category(UiStrings.File, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().File, CategoryOrder.standardMenu)
|
||||||
self.FileNewItem = shortcut_action(mainWindow, u'FileNewItem',
|
self.FileNewItem = shortcut_action(mainWindow, u'FileNewItem',
|
||||||
[QtGui.QKeySequence(u'Ctrl+N')],
|
[QtGui.QKeySequence(u'Ctrl+N')],
|
||||||
self.ServiceManagerContents.onNewServiceClicked,
|
self.ServiceManagerContents.onNewServiceClicked,
|
||||||
u':/general/general_new.png', category=UiStrings.File)
|
u':/general/general_new.png', category=UiStrings().File)
|
||||||
self.FileOpenItem = shortcut_action(mainWindow, u'FileOpenItem',
|
self.FileOpenItem = shortcut_action(mainWindow, u'FileOpenItem',
|
||||||
[QtGui.QKeySequence(u'Ctrl+O')],
|
[QtGui.QKeySequence(u'Ctrl+O')],
|
||||||
self.ServiceManagerContents.onLoadServiceClicked,
|
self.ServiceManagerContents.onLoadServiceClicked,
|
||||||
u':/general/general_open.png', category=UiStrings.File)
|
u':/general/general_open.png', category=UiStrings().File)
|
||||||
self.FileSaveItem = shortcut_action(mainWindow, u'FileSaveItem',
|
self.FileSaveItem = shortcut_action(mainWindow, u'FileSaveItem',
|
||||||
[QtGui.QKeySequence(u'Ctrl+S')],
|
[QtGui.QKeySequence(u'Ctrl+S')],
|
||||||
self.ServiceManagerContents.saveFile,
|
self.ServiceManagerContents.saveFile,
|
||||||
u':/general/general_save.png', category=UiStrings.File)
|
u':/general/general_save.png', category=UiStrings().File)
|
||||||
self.FileSaveAsItem = shortcut_action(mainWindow, u'FileSaveAsItem',
|
self.FileSaveAsItem = shortcut_action(mainWindow, u'FileSaveAsItem',
|
||||||
[QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
[QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
||||||
self.ServiceManagerContents.saveFileAs, category=UiStrings.File)
|
self.ServiceManagerContents.saveFileAs, category=UiStrings().File)
|
||||||
self.printServiceOrderItem = shortcut_action(mainWindow,
|
self.printServiceOrderItem = shortcut_action(mainWindow,
|
||||||
u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')],
|
u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')],
|
||||||
self.ServiceManagerContents.printServiceOrder,
|
self.ServiceManagerContents.printServiceOrder,
|
||||||
category=UiStrings.File)
|
category=UiStrings().File)
|
||||||
self.FileExitItem = shortcut_action(mainWindow, u'FileExitItem',
|
self.FileExitItem = shortcut_action(mainWindow, u'FileExitItem',
|
||||||
[QtGui.QKeySequence(u'Alt+F4')], mainWindow.close,
|
[QtGui.QKeySequence(u'Alt+F4')], mainWindow.close,
|
||||||
u':/system/system_exit.png', category=UiStrings.File)
|
u':/system/system_exit.png', category=UiStrings().File)
|
||||||
action_list.add_category(UiStrings.Import, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().Import, CategoryOrder.standardMenu)
|
||||||
self.ImportThemeItem = base_action(
|
self.ImportThemeItem = base_action(
|
||||||
mainWindow, u'ImportThemeItem', UiStrings.Import)
|
mainWindow, u'ImportThemeItem', UiStrings().Import)
|
||||||
self.ImportLanguageItem = base_action(
|
self.ImportLanguageItem = base_action(
|
||||||
mainWindow, u'ImportLanguageItem')#, UiStrings.Import)
|
mainWindow, u'ImportLanguageItem')#, UiStrings().Import)
|
||||||
action_list.add_category(UiStrings.Export, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().Export, CategoryOrder.standardMenu)
|
||||||
self.ExportThemeItem = base_action(
|
self.ExportThemeItem = base_action(
|
||||||
mainWindow, u'ExportThemeItem', UiStrings.Export)
|
mainWindow, u'ExportThemeItem', UiStrings().Export)
|
||||||
self.ExportLanguageItem = base_action(
|
self.ExportLanguageItem = base_action(
|
||||||
mainWindow, u'ExportLanguageItem')#, UiStrings.Export)
|
mainWindow, u'ExportLanguageItem')#, UiStrings().Export)
|
||||||
action_list.add_category(UiStrings.View, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().View, CategoryOrder.standardMenu)
|
||||||
self.ViewMediaManagerItem = shortcut_action(mainWindow,
|
self.ViewMediaManagerItem = shortcut_action(mainWindow,
|
||||||
u'ViewMediaManagerItem', [QtGui.QKeySequence(u'F8')],
|
u'ViewMediaManagerItem', [QtGui.QKeySequence(u'F8')],
|
||||||
self.toggleMediaManager, u':/system/system_mediamanager.png',
|
self.toggleMediaManager, u':/system/system_mediamanager.png',
|
||||||
self.mediaManagerDock.isVisible(), UiStrings.View)
|
self.mediaManagerDock.isVisible(), UiStrings().View)
|
||||||
self.ViewThemeManagerItem = shortcut_action(mainWindow,
|
self.ViewThemeManagerItem = shortcut_action(mainWindow,
|
||||||
u'ViewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
|
u'ViewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
|
||||||
self.toggleThemeManager, u':/system/system_thememanager.png',
|
self.toggleThemeManager, u':/system/system_thememanager.png',
|
||||||
self.themeManagerDock.isVisible(), UiStrings.View)
|
self.themeManagerDock.isVisible(), UiStrings().View)
|
||||||
self.ViewServiceManagerItem = shortcut_action(mainWindow,
|
self.ViewServiceManagerItem = shortcut_action(mainWindow,
|
||||||
u'ViewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
|
u'ViewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
|
||||||
self.toggleServiceManager, u':/system/system_servicemanager.png',
|
self.toggleServiceManager, u':/system/system_servicemanager.png',
|
||||||
self.serviceManagerDock.isVisible(), UiStrings.View)
|
self.serviceManagerDock.isVisible(), UiStrings().View)
|
||||||
self.ViewPreviewPanel = shortcut_action(mainWindow,
|
self.ViewPreviewPanel = shortcut_action(mainWindow,
|
||||||
u'ViewPreviewPanel', [QtGui.QKeySequence(u'F11')],
|
u'ViewPreviewPanel', [QtGui.QKeySequence(u'F11')],
|
||||||
self.setPreviewPanelVisibility, checked=previewVisible,
|
self.setPreviewPanelVisibility, checked=previewVisible,
|
||||||
category=UiStrings.View)
|
category=UiStrings().View)
|
||||||
self.ViewLivePanel = shortcut_action(mainWindow, u'ViewLivePanel',
|
self.ViewLivePanel = shortcut_action(mainWindow, u'ViewLivePanel',
|
||||||
[QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility,
|
[QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility,
|
||||||
checked=liveVisible, category=UiStrings.View)
|
checked=liveVisible, category=UiStrings().View)
|
||||||
action_list.add_category(UiStrings.ViewMode, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().ViewMode, CategoryOrder.standardMenu)
|
||||||
self.ModeDefaultItem = checkable_action(
|
self.ModeDefaultItem = checkable_action(
|
||||||
mainWindow, u'ModeDefaultItem', category=UiStrings.ViewMode)
|
mainWindow, u'ModeDefaultItem', category=UiStrings().ViewMode)
|
||||||
self.ModeSetupItem = checkable_action(
|
self.ModeSetupItem = checkable_action(
|
||||||
mainWindow, u'ModeLiveItem', category=UiStrings.ViewMode)
|
mainWindow, u'ModeLiveItem', category=UiStrings().ViewMode)
|
||||||
self.ModeLiveItem = checkable_action(
|
self.ModeLiveItem = checkable_action(
|
||||||
mainWindow, u'ModeLiveItem', True, UiStrings.ViewMode)
|
mainWindow, u'ModeLiveItem', True, UiStrings().ViewMode)
|
||||||
self.ModeGroup = QtGui.QActionGroup(mainWindow)
|
self.ModeGroup = QtGui.QActionGroup(mainWindow)
|
||||||
self.ModeGroup.addAction(self.ModeDefaultItem)
|
self.ModeGroup.addAction(self.ModeDefaultItem)
|
||||||
self.ModeGroup.addAction(self.ModeSetupItem)
|
self.ModeGroup.addAction(self.ModeSetupItem)
|
||||||
self.ModeGroup.addAction(self.ModeLiveItem)
|
self.ModeGroup.addAction(self.ModeLiveItem)
|
||||||
self.ModeDefaultItem.setChecked(True)
|
self.ModeDefaultItem.setChecked(True)
|
||||||
action_list.add_category(UiStrings.Tools, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().Tools, CategoryOrder.standardMenu)
|
||||||
self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
|
self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
|
||||||
u':/tools/tools_add.png', category=UiStrings.Tools)
|
u':/tools/tools_add.png', category=UiStrings().Tools)
|
||||||
self.ToolsOpenDataFolder = icon_action(mainWindow,
|
self.ToolsOpenDataFolder = icon_action(mainWindow,
|
||||||
u'ToolsOpenDataFolder', u':/general/general_open.png',
|
u'ToolsOpenDataFolder', u':/general/general_open.png',
|
||||||
category=UiStrings.Tools)
|
category=UiStrings().Tools)
|
||||||
action_list.add_category(UiStrings.Settings, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().Settings, CategoryOrder.standardMenu)
|
||||||
self.settingsPluginListItem = shortcut_action(mainWindow,
|
self.settingsPluginListItem = shortcut_action(mainWindow,
|
||||||
u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')],
|
u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')],
|
||||||
self.onPluginItemClicked, u':/system/settings_plugin_list.png',
|
self.onPluginItemClicked, u':/system/settings_plugin_list.png',
|
||||||
category=UiStrings.Settings)
|
category=UiStrings().Settings)
|
||||||
# i18n Language Items
|
# i18n Language Items
|
||||||
self.AutoLanguageItem = checkable_action(mainWindow,
|
self.AutoLanguageItem = checkable_action(mainWindow,
|
||||||
u'AutoLanguageItem', LanguageManager.auto_language)
|
u'AutoLanguageItem', LanguageManager.auto_language)
|
||||||
@ -255,25 +255,25 @@ class Ui_MainWindow(object):
|
|||||||
self.SettingsShortcutsItem = icon_action(mainWindow,
|
self.SettingsShortcutsItem = icon_action(mainWindow,
|
||||||
u'SettingsShortcutsItem',
|
u'SettingsShortcutsItem',
|
||||||
u':/system/system_configure_shortcuts.png',
|
u':/system/system_configure_shortcuts.png',
|
||||||
category=UiStrings.Settings)
|
category=UiStrings().Settings)
|
||||||
self.DisplayTagItem = icon_action(mainWindow,
|
self.DisplayTagItem = icon_action(mainWindow,
|
||||||
u'DisplayTagItem', u':/system/tag_editor.png',
|
u'DisplayTagItem', u':/system/tag_editor.png',
|
||||||
category=UiStrings.Settings)
|
category=UiStrings().Settings)
|
||||||
self.SettingsConfigureItem = icon_action(mainWindow,
|
self.SettingsConfigureItem = icon_action(mainWindow,
|
||||||
u'SettingsConfigureItem', u':/system/system_settings.png',
|
u'SettingsConfigureItem', u':/system/system_settings.png',
|
||||||
category=UiStrings.Settings)
|
category=UiStrings().Settings)
|
||||||
action_list.add_category(UiStrings.Help, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu)
|
||||||
self.HelpDocumentationItem = icon_action(mainWindow,
|
self.HelpDocumentationItem = icon_action(mainWindow,
|
||||||
u'HelpDocumentationItem', u':/system/system_help_contents.png',
|
u'HelpDocumentationItem', u':/system/system_help_contents.png',
|
||||||
category=None)#UiStrings.Help)
|
category=None)#UiStrings().Help)
|
||||||
self.HelpDocumentationItem.setEnabled(False)
|
self.HelpDocumentationItem.setEnabled(False)
|
||||||
self.HelpAboutItem = shortcut_action(mainWindow, u'HelpAboutItem',
|
self.HelpAboutItem = shortcut_action(mainWindow, u'HelpAboutItem',
|
||||||
[QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked,
|
[QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked,
|
||||||
u':/system/system_about.png', category=UiStrings.Help)
|
u':/system/system_about.png', category=UiStrings().Help)
|
||||||
self.HelpOnlineHelpItem = base_action(
|
self.HelpOnlineHelpItem = base_action(
|
||||||
mainWindow, u'HelpOnlineHelpItem', category=UiStrings.Help)
|
mainWindow, u'HelpOnlineHelpItem', category=UiStrings().Help)
|
||||||
self.helpWebSiteItem = base_action(
|
self.helpWebSiteItem = base_action(
|
||||||
mainWindow, u'helpWebSiteItem', category=UiStrings.Help)
|
mainWindow, u'helpWebSiteItem', category=UiStrings().Help)
|
||||||
add_actions(self.FileImportMenu,
|
add_actions(self.FileImportMenu,
|
||||||
(self.ImportThemeItem, self.ImportLanguageItem))
|
(self.ImportThemeItem, self.ImportLanguageItem))
|
||||||
add_actions(self.FileExportMenu,
|
add_actions(self.FileExportMenu,
|
||||||
@ -320,7 +320,7 @@ class Ui_MainWindow(object):
|
|||||||
"""
|
"""
|
||||||
Set up the translation system
|
Set up the translation system
|
||||||
"""
|
"""
|
||||||
mainWindow.mainTitle = UiStrings.OLPV2
|
mainWindow.mainTitle = UiStrings().OLPV2
|
||||||
mainWindow.setWindowTitle(mainWindow.mainTitle)
|
mainWindow.setWindowTitle(mainWindow.mainTitle)
|
||||||
self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
|
self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
|
||||||
self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
|
self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
|
||||||
@ -339,14 +339,14 @@ class Ui_MainWindow(object):
|
|||||||
self.themeManagerDock.setWindowTitle(
|
self.themeManagerDock.setWindowTitle(
|
||||||
translate('OpenLP.MainWindow', 'Theme Manager'))
|
translate('OpenLP.MainWindow', 'Theme Manager'))
|
||||||
self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New'))
|
self.FileNewItem.setText(translate('OpenLP.MainWindow', '&New'))
|
||||||
self.FileNewItem.setToolTip(UiStrings.NewService)
|
self.FileNewItem.setToolTip(UiStrings().NewService)
|
||||||
self.FileNewItem.setStatusTip(UiStrings.CreateService)
|
self.FileNewItem.setStatusTip(UiStrings().CreateService)
|
||||||
self.FileOpenItem.setText(translate('OpenLP.MainWindow', '&Open'))
|
self.FileOpenItem.setText(translate('OpenLP.MainWindow', '&Open'))
|
||||||
self.FileOpenItem.setToolTip(UiStrings.OpenService)
|
self.FileOpenItem.setToolTip(UiStrings().OpenService)
|
||||||
self.FileOpenItem.setStatusTip(
|
self.FileOpenItem.setStatusTip(
|
||||||
translate('OpenLP.MainWindow', 'Open an existing service.'))
|
translate('OpenLP.MainWindow', 'Open an existing service.'))
|
||||||
self.FileSaveItem.setText(translate('OpenLP.MainWindow', '&Save'))
|
self.FileSaveItem.setText(translate('OpenLP.MainWindow', '&Save'))
|
||||||
self.FileSaveItem.setToolTip(UiStrings.SaveService)
|
self.FileSaveItem.setToolTip(UiStrings().SaveService)
|
||||||
self.FileSaveItem.setStatusTip(
|
self.FileSaveItem.setStatusTip(
|
||||||
translate('OpenLP.MainWindow', 'Save the current service to disk.'))
|
translate('OpenLP.MainWindow', 'Save the current service to disk.'))
|
||||||
self.FileSaveAsItem.setText(
|
self.FileSaveAsItem.setText(
|
||||||
@ -355,7 +355,7 @@ class Ui_MainWindow(object):
|
|||||||
translate('OpenLP.MainWindow', 'Save Service As'))
|
translate('OpenLP.MainWindow', 'Save Service As'))
|
||||||
self.FileSaveAsItem.setStatusTip(translate('OpenLP.MainWindow',
|
self.FileSaveAsItem.setStatusTip(translate('OpenLP.MainWindow',
|
||||||
'Save the current service under a new name.'))
|
'Save the current service under a new name.'))
|
||||||
self.printServiceOrderItem.setText(UiStrings.PrintServiceOrder)
|
self.printServiceOrderItem.setText(UiStrings().PrintServiceOrder)
|
||||||
self.printServiceOrderItem.setStatusTip(translate('OpenLP.MainWindow',
|
self.printServiceOrderItem.setStatusTip(translate('OpenLP.MainWindow',
|
||||||
'Print the current Service Order.'))
|
'Print the current Service Order.'))
|
||||||
self.FileExitItem.setText(
|
self.FileExitItem.setText(
|
||||||
@ -545,9 +545,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
QtCore.SIGNAL(u'openlp_information_message'),
|
QtCore.SIGNAL(u'openlp_information_message'),
|
||||||
self.onInformationMessage)
|
self.onInformationMessage)
|
||||||
# warning cyclic dependency
|
# warning cyclic dependency
|
||||||
# RenderManager needs to call ThemeManager and
|
# renderer needs to call ThemeManager and
|
||||||
# ThemeManager needs to call RenderManager
|
# ThemeManager needs to call Renderer
|
||||||
self.renderManager = RenderManager(
|
self.renderer = Renderer(
|
||||||
self.themeManagerContents, self.screens)
|
self.themeManagerContents, self.screens)
|
||||||
# Define the media Dock Manager
|
# Define the media Dock Manager
|
||||||
self.mediaDockManager = MediaDockManager(self.MediaToolBox)
|
self.mediaDockManager = MediaDockManager(self.MediaToolBox)
|
||||||
@ -555,7 +555,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
# make the controllers available to the plugins
|
# make the controllers available to the plugins
|
||||||
self.pluginHelpers[u'preview'] = self.previewController
|
self.pluginHelpers[u'preview'] = self.previewController
|
||||||
self.pluginHelpers[u'live'] = self.liveController
|
self.pluginHelpers[u'live'] = self.liveController
|
||||||
self.pluginHelpers[u'render'] = self.renderManager
|
self.pluginHelpers[u'renderer'] = self.renderer
|
||||||
self.pluginHelpers[u'service'] = self.ServiceManagerContents
|
self.pluginHelpers[u'service'] = self.ServiceManagerContents
|
||||||
self.pluginHelpers[u'settings form'] = self.settingsForm
|
self.pluginHelpers[u'settings form'] = self.settingsForm
|
||||||
self.pluginHelpers[u'toolbox'] = self.mediaDockManager
|
self.pluginHelpers[u'toolbox'] = self.mediaDockManager
|
||||||
@ -781,7 +781,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
their locations
|
their locations
|
||||||
"""
|
"""
|
||||||
log.debug(u'screenChanged')
|
log.debug(u'screenChanged')
|
||||||
self.renderManager.update_display()
|
self.renderer.update_display()
|
||||||
self.setFocus()
|
self.setFocus()
|
||||||
self.activateWindow()
|
self.activateWindow()
|
||||||
|
|
||||||
@ -896,7 +896,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
def toggleThemeManager(self):
|
def toggleThemeManager(self):
|
||||||
self.themeManagerDock.setVisible(not self.themeManagerDock.isVisible())
|
self.themeManagerDock.setVisible(not self.themeManagerDock.isVisible())
|
||||||
|
|
||||||
def setPreviewPanelVisibility(self, visible=None):
|
def setPreviewPanelVisibility(self, visible):
|
||||||
"""
|
"""
|
||||||
Sets the visibility of the preview panel including saving the setting
|
Sets the visibility of the preview panel including saving the setting
|
||||||
and updating the menu.
|
and updating the menu.
|
||||||
@ -906,14 +906,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
True - Visible
|
True - Visible
|
||||||
False - Hidden
|
False - Hidden
|
||||||
"""
|
"""
|
||||||
if visible is None:
|
|
||||||
visible = self.ViewPreviewPanel.isVisible()
|
|
||||||
self.previewController.panel.setVisible(visible)
|
self.previewController.panel.setVisible(visible)
|
||||||
QtCore.QSettings().setValue(u'user interface/preview panel',
|
QtCore.QSettings().setValue(u'user interface/preview panel',
|
||||||
QtCore.QVariant(visible))
|
QtCore.QVariant(visible))
|
||||||
self.ViewPreviewPanel.setChecked(visible)
|
self.ViewPreviewPanel.setChecked(visible)
|
||||||
|
|
||||||
def setLivePanelVisibility(self, visible=None):
|
def setLivePanelVisibility(self, visible):
|
||||||
"""
|
"""
|
||||||
Sets the visibility of the live panel including saving the setting and
|
Sets the visibility of the live panel including saving the setting and
|
||||||
updating the menu.
|
updating the menu.
|
||||||
@ -923,8 +921,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
True - Visible
|
True - Visible
|
||||||
False - Hidden
|
False - Hidden
|
||||||
"""
|
"""
|
||||||
if visible is None:
|
|
||||||
visible = self.ViewLivePanel.isVisible()
|
|
||||||
self.liveController.panel.setVisible(visible)
|
self.liveController.panel.setVisible(visible)
|
||||||
QtCore.QSettings().setValue(u'user interface/live panel',
|
QtCore.QSettings().setValue(u'user interface/live panel',
|
||||||
QtCore.QVariant(visible))
|
QtCore.QVariant(visible))
|
||||||
|
@ -78,11 +78,11 @@ class Ui_PluginViewDialog(object):
|
|||||||
translate('OpenLP.PluginForm', 'Plugin List'))
|
translate('OpenLP.PluginForm', 'Plugin List'))
|
||||||
self.pluginInfoGroupBox.setTitle(
|
self.pluginInfoGroupBox.setTitle(
|
||||||
translate('OpenLP.PluginForm', 'Plugin Details'))
|
translate('OpenLP.PluginForm', 'Plugin Details'))
|
||||||
self.versionLabel.setText(u'%s:' % UiStrings.Version)
|
self.versionLabel.setText(u'%s:' % UiStrings().Version)
|
||||||
self.aboutLabel.setText(u'%s:' % UiStrings.About)
|
self.aboutLabel.setText(u'%s:' % UiStrings().About)
|
||||||
self.statusLabel.setText(
|
self.statusLabel.setText(
|
||||||
translate('OpenLP.PluginForm', 'Status:'))
|
translate('OpenLP.PluginForm', 'Status:'))
|
||||||
self.statusComboBox.setItemText(0,
|
self.statusComboBox.setItemText(0,
|
||||||
translate('OpenLP.PluginForm', 'Active'))
|
translate('OpenLP.PluginForm', 'Active'))
|
||||||
self.statusComboBox.setItemText(1,
|
self.statusComboBox.setItemText(1,
|
||||||
translate('OpenLP.PluginForm', 'Inactive'))
|
translate('OpenLP.PluginForm', 'Inactive'))
|
@ -148,7 +148,7 @@ class Ui_PrintServiceDialog(object):
|
|||||||
QtCore.SIGNAL(u'toggled(bool)'), self.toggleOptions)
|
QtCore.SIGNAL(u'toggled(bool)'), self.toggleOptions)
|
||||||
|
|
||||||
def retranslateUi(self, printServiceDialog):
|
def retranslateUi(self, printServiceDialog):
|
||||||
printServiceDialog.setWindowTitle(UiStrings.PrintServiceOrder)
|
printServiceDialog.setWindowTitle(UiStrings().PrintServiceOrder)
|
||||||
self.slideTextCheckBox.setText(translate('OpenLP.PrintServiceForm',
|
self.slideTextCheckBox.setText(translate('OpenLP.PrintServiceForm',
|
||||||
'Include slide text if available'))
|
'Include slide text if available'))
|
||||||
self.pageBreakAfterText.setText(translate('OpenLP.PrintServiceForm',
|
self.pageBreakAfterText.setText(translate('OpenLP.PrintServiceForm',
|
||||||
@ -164,4 +164,4 @@ class Ui_PrintServiceDialog(object):
|
|||||||
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.OneHundred])
|
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.OneHundred])
|
||||||
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.SeventyFive])
|
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.SeventyFive])
|
||||||
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.Fifty])
|
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.Fifty])
|
||||||
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.TwentyFive])
|
self.zoomComboBox.addItem(ZoomSize.Sizes[ZoomSize.TwentyFive])
|
@ -46,41 +46,58 @@ http://doc.trolltech.com/4.7/richtext-html-subset.html#css-properties
|
|||||||
color:black;
|
color:black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
color:black;
|
||||||
|
}
|
||||||
|
|
||||||
.itemTitle {
|
.itemTitle {
|
||||||
font-weight:600;
|
font-weight:600;
|
||||||
font-size:large;
|
font-size:large;
|
||||||
color:black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.itemText {
|
.itemText {}
|
||||||
color:black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.itemFooter {
|
.itemFooter {
|
||||||
font-size:8px;
|
font-size:8px;
|
||||||
color:black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.itemNotes {}
|
||||||
|
|
||||||
.itemNotesTitle {
|
.itemNotesTitle {
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
font-size:12px;
|
font-size:12px;
|
||||||
color:black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.itemNotesText {
|
.itemNotesText {
|
||||||
font-size:11px;
|
font-size:11px;
|
||||||
color:black;
|
}
|
||||||
|
|
||||||
|
.media {}
|
||||||
|
|
||||||
|
.mediaTitle {
|
||||||
|
font-weight:bold;
|
||||||
|
font-size:11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mediaText {}
|
||||||
|
|
||||||
|
.imageList {}
|
||||||
|
|
||||||
|
.customNotes {
|
||||||
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.customNotesTitle {
|
.customNotesTitle {
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
font-size:11px;
|
font-size:11px;
|
||||||
color:black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.customNotesText {
|
.customNotesText {
|
||||||
font-size:11px;
|
font-size:11px;
|
||||||
color:black;
|
}
|
||||||
|
|
||||||
|
.newPage {
|
||||||
|
page-break-before:always;
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -153,86 +170,90 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
"""
|
"""
|
||||||
Creates the html text and updates the html of *self.document*.
|
Creates the html text and updates the html of *self.document*.
|
||||||
"""
|
"""
|
||||||
html_data = html.fromstring(
|
html_data = self._addElement(u'html')
|
||||||
u'<title>%s</title>' % unicode(self.titleLineEdit.text()))
|
self._addElement(u'head', parent=html_data)
|
||||||
|
self._addElement(u'title', unicode(self.titleLineEdit.text()),
|
||||||
|
html_data.head)
|
||||||
css_path = os.path.join(
|
css_path = os.path.join(
|
||||||
AppLocation.get_data_path(), u'servicePrint.css')
|
AppLocation.get_data_path(), u'service_print.css')
|
||||||
if not os.path.isfile(css_path):
|
|
||||||
# Create default css file.
|
|
||||||
css_file = open(css_path, u'w')
|
|
||||||
css_file.write(DEFAULT_CSS)
|
|
||||||
css_file.close()
|
|
||||||
custom_css = get_text_file_string(css_path)
|
custom_css = get_text_file_string(css_path)
|
||||||
self._addChildToParent(
|
if not custom_css:
|
||||||
u'style', custom_css, html_data.head, u'type', u'text/css')
|
custom_css = DEFAULT_CSS
|
||||||
self._addChildToParent(u'body', parent=html_data)
|
self._addElement(u'style', custom_css, html_data.head,
|
||||||
self._addChildToParent(u'span', unicode(self.titleLineEdit.text()),
|
attribute=(u'type', u'text/css'))
|
||||||
html_data.body, u'class', u'serviceTitle')
|
self._addElement(u'body', parent=html_data)
|
||||||
|
self._addElement(u'h1', unicode(self.titleLineEdit.text()),
|
||||||
|
html_data.body, classId=u'serviceTitle')
|
||||||
for index, item in enumerate(self.serviceManager.serviceItems):
|
for index, item in enumerate(self.serviceManager.serviceItems):
|
||||||
item = item[u'service_item']
|
self._addPreviewItem(html_data.body, item[u'service_item'], index)
|
||||||
div = self._addChildToParent(u'div', parent=html_data.body)
|
|
||||||
# Add the title of the service item.
|
|
||||||
item_title = self._addChildToParent(
|
|
||||||
u'h2', parent=div, attribute=u'class', value=u'itemTitle')
|
|
||||||
self._addChildToParent(
|
|
||||||
u'img', parent=item_title, attribute=u'src', value=item.icon)
|
|
||||||
self._fromstring(
|
|
||||||
u'<span> %s</span>' % item.get_display_title(), item_title)
|
|
||||||
if self.slideTextCheckBox.isChecked():
|
|
||||||
# Add the text of the service item.
|
|
||||||
if item.is_text():
|
|
||||||
verse_def = None
|
|
||||||
for slide in item.get_frames():
|
|
||||||
if not verse_def or verse_def != slide[u'verseTag']:
|
|
||||||
p = self._addChildToParent(u'p', parent=div,
|
|
||||||
attribute=u'class', value=u'itemText')
|
|
||||||
else:
|
|
||||||
self._addChildToParent(u'br', parent=p)
|
|
||||||
self._fromstring(u'<span>%s</span>' % slide[u'html'], p)
|
|
||||||
verse_def = slide[u'verseTag']
|
|
||||||
# Break the page before the div element.
|
|
||||||
if index != 0 and self.pageBreakAfterText.isChecked():
|
|
||||||
div.set(u'style', u'page-break-before:always')
|
|
||||||
# Add the image names of the service item.
|
|
||||||
elif item.is_image():
|
|
||||||
ol = self._addChildToParent(u'ol', parent=div)
|
|
||||||
for slide in range(len(item.get_frames())):
|
|
||||||
self._addChildToParent(u'li', item.get_frame_title(slide), ol)
|
|
||||||
# add footer
|
|
||||||
if item.foot_text:
|
|
||||||
self._fromstring(
|
|
||||||
item.foot_text, div, u'class', u'itemFooter')
|
|
||||||
# Add service items' notes.
|
|
||||||
if self.notesCheckBox.isChecked():
|
|
||||||
if item.notes:
|
|
||||||
p = self._addChildToParent(u'p', parent=div)
|
|
||||||
self._addChildToParent(u'span', unicode(
|
|
||||||
translate('OpenLP.ServiceManager', 'Notes:')), p,
|
|
||||||
u'class', u'itemNotesTitle')
|
|
||||||
self._fromstring(u'<span> %s</span>' % item.notes.replace(
|
|
||||||
u'\n', u'<br />'), p, u'class', u'itemNotesText')
|
|
||||||
# Add play length of media files.
|
|
||||||
if item.is_media() and self.metaDataCheckBox.isChecked():
|
|
||||||
tme = item.media_length
|
|
||||||
if item.end_time > 0:
|
|
||||||
tme = item.end_time - item.start_time
|
|
||||||
title = self._fromstring(u'<p><strong>%s</strong> </p>' %
|
|
||||||
translate('OpenLP.ServiceManager', 'Playing time:'), div)
|
|
||||||
self._fromstring(u'<span>%s</span>' %
|
|
||||||
unicode(datetime.timedelta(seconds=tme)), title)
|
|
||||||
# Add the custom service notes:
|
# Add the custom service notes:
|
||||||
if self.footerTextEdit.toPlainText():
|
if self.footerTextEdit.toPlainText():
|
||||||
div = self._addChildToParent(u'div', parent=html_data.body)
|
div = self._addElement(u'div', parent=html_data.body,
|
||||||
self._addChildToParent(u'span', translate('OpenLP.ServiceManager',
|
classId=u'customNotes')
|
||||||
u'Custom Service Notes:'), div, u'class', u'customNotesTitle')
|
self._addElement(u'span', translate('OpenLP.ServiceManager',
|
||||||
self._addChildToParent(
|
'Custom Service Notes: '), div, classId=u'customNotesTitle')
|
||||||
u'span', u' %s' % self.footerTextEdit.toPlainText(), div,
|
self._addElement(u'span', self.footerTextEdit.toPlainText(), div,
|
||||||
u'class', u'customNotesText')
|
classId=u'customNotesText')
|
||||||
self.document.setHtml(html.tostring(html_data))
|
self.document.setHtml(html.tostring(html_data))
|
||||||
self.previewWidget.updatePreview()
|
self.previewWidget.updatePreview()
|
||||||
|
|
||||||
def _addChildToParent(self, tag, text=None, parent=None, attribute=None,
|
def _addPreviewItem(self, body, item, index):
|
||||||
value=None):
|
div = self._addElement(u'div', classId=u'item', parent=body)
|
||||||
|
# Add the title of the service item.
|
||||||
|
item_title = self._addElement(u'h2', parent=div, classId=u'itemTitle')
|
||||||
|
self._addElement(u'img', parent=item_title,
|
||||||
|
attribute=(u'src', item.icon))
|
||||||
|
self._addElement(u'span', u' ' + item.get_display_title(),
|
||||||
|
item_title)
|
||||||
|
if self.slideTextCheckBox.isChecked():
|
||||||
|
# Add the text of the service item.
|
||||||
|
if item.is_text():
|
||||||
|
verse_def = None
|
||||||
|
for slide in item.get_frames():
|
||||||
|
if not verse_def or verse_def != slide[u'verseTag']:
|
||||||
|
p = self._addElement(u'div', parent=div,
|
||||||
|
classId=u'itemText')
|
||||||
|
else:
|
||||||
|
self._addElement(u'br', parent=p)
|
||||||
|
self._addElement(u'p', slide[u'html'], p)
|
||||||
|
verse_def = slide[u'verseTag']
|
||||||
|
# Break the page before the div element.
|
||||||
|
if index != 0 and self.pageBreakAfterText.isChecked():
|
||||||
|
div.set(u'class', u'item newPage')
|
||||||
|
# Add the image names of the service item.
|
||||||
|
elif item.is_image():
|
||||||
|
ol = self._addElement(u'ol', parent=div, classId=u'imageList')
|
||||||
|
for slide in range(len(item.get_frames())):
|
||||||
|
self._addElement(u'li', item.get_frame_title(slide), ol)
|
||||||
|
# add footer
|
||||||
|
foot_text = item.foot_text
|
||||||
|
foot_text = foot_text.partition(u'<br>')[2]
|
||||||
|
if foot_text:
|
||||||
|
foot = self._addElement(u'div', foot_text, parent=div,
|
||||||
|
classId=u'itemFooter')
|
||||||
|
# Add service items' notes.
|
||||||
|
if self.notesCheckBox.isChecked():
|
||||||
|
if item.notes:
|
||||||
|
p = self._addElement(u'div', classId=u'itemNotes', parent=div)
|
||||||
|
self._addElement(u'span',
|
||||||
|
translate('OpenLP.ServiceManager', 'Notes: '), p,
|
||||||
|
classId=u'itemNotesTitle')
|
||||||
|
notes = self._addElement(u'span',
|
||||||
|
item.notes.replace(u'\n', u'<br />'), p,
|
||||||
|
classId=u'itemNotesText')
|
||||||
|
# Add play length of media files.
|
||||||
|
if item.is_media() and self.metaDataCheckBox.isChecked():
|
||||||
|
tme = item.media_length
|
||||||
|
if item.end_time > 0:
|
||||||
|
tme = item.end_time - item.start_time
|
||||||
|
title = self._addElement(u'div', classId=u'media', parent=div)
|
||||||
|
self._addElement(u'span', translate('OpenLP.ServiceManager',
|
||||||
|
'Playing time: '), title, classId=u'mediaTitle')
|
||||||
|
self._addElement(u'span', unicode(datetime.timedelta(seconds=tme)),
|
||||||
|
title, classId=u'mediaText')
|
||||||
|
|
||||||
|
def _addElement(self, tag, text=None, parent=None, classId=None,
|
||||||
|
attribute=None):
|
||||||
"""
|
"""
|
||||||
Creates a html element. If ``text`` is given, the element's text will
|
Creates a html element. If ``text`` is given, the element's text will
|
||||||
set and if a ``parent`` is given, the element is appended.
|
set and if a ``parent`` is given, the element is appended.
|
||||||
@ -246,30 +267,22 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
``parent``
|
``parent``
|
||||||
The parent element. Defaults to ``None``.
|
The parent element. Defaults to ``None``.
|
||||||
|
|
||||||
``attribute``
|
``classId``
|
||||||
An optional attribute, for instance ``u'class``.
|
Value for the class attribute
|
||||||
|
|
||||||
``value``
|
``attribute``
|
||||||
The value for the given ``attribute``. It does not have a meaning,
|
Tuple name/value pair to add as an optional attribute
|
||||||
if the attribute is left to its default.
|
|
||||||
"""
|
"""
|
||||||
element = html.Element(tag)
|
|
||||||
if text is not None:
|
if text is not None:
|
||||||
element.text = unicode(text)
|
element = html.fragment_fromstring(unicode(text), create_parent=tag)
|
||||||
|
else:
|
||||||
|
element = html.Element(tag)
|
||||||
if parent is not None:
|
if parent is not None:
|
||||||
parent.append(element)
|
parent.append(element)
|
||||||
|
if classId is not None:
|
||||||
|
element.set(u'class', classId)
|
||||||
if attribute is not None:
|
if attribute is not None:
|
||||||
element.set(attribute, value if value is not None else u'')
|
element.set(attribute[0], attribute[1])
|
||||||
return element
|
|
||||||
|
|
||||||
def _fromstring(self, string, parent, attribute=None, value=None):
|
|
||||||
"""
|
|
||||||
This is used to create a child html element from a string.
|
|
||||||
"""
|
|
||||||
element = html.fromstring(string)
|
|
||||||
if attribute is not None:
|
|
||||||
element.set(attribute, value if value is not None else u'')
|
|
||||||
parent.append(element)
|
|
||||||
return element
|
return element
|
||||||
|
|
||||||
def paintRequested(self, printer):
|
def paintRequested(self, printer):
|
||||||
@ -354,9 +367,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
Called when html copy check box is selected.
|
Called when html copy check box is selected.
|
||||||
"""
|
"""
|
||||||
if value == QtCore.Qt.Checked:
|
if value == QtCore.Qt.Checked:
|
||||||
self.copyTextButton.setText(UiStrings.CopyToHtml)
|
self.copyTextButton.setText(UiStrings().CopyToHtml)
|
||||||
else:
|
else:
|
||||||
self.copyTextButton.setText(UiStrings.CopyToText)
|
self.copyTextButton.setText(UiStrings().CopyToText)
|
||||||
|
|
||||||
def onSlideTextCheckBoxChanged(self, state):
|
def onSlideTextCheckBoxChanged(self, state):
|
||||||
"""
|
"""
|
||||||
|
@ -111,18 +111,18 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
# Create the top toolbar
|
# Create the top toolbar
|
||||||
self.toolbar = OpenLPToolbar(self)
|
self.toolbar = OpenLPToolbar(self)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.NewService, u':/general/general_new.png',
|
UiStrings().NewService, u':/general/general_new.png',
|
||||||
UiStrings.CreateService, self.onNewServiceClicked)
|
UiStrings().CreateService, self.onNewServiceClicked)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.OpenService, u':/general/general_open.png',
|
UiStrings().OpenService, u':/general/general_open.png',
|
||||||
translate('OpenLP.ServiceManager', 'Load an existing service'),
|
translate('OpenLP.ServiceManager', 'Load an existing service'),
|
||||||
self.onLoadServiceClicked)
|
self.onLoadServiceClicked)
|
||||||
self.toolbar.addToolbarButton(
|
self.toolbar.addToolbarButton(
|
||||||
UiStrings.SaveService, u':/general/general_save.png',
|
UiStrings().SaveService, u':/general/general_save.png',
|
||||||
translate('OpenLP.ServiceManager', 'Save this service'),
|
translate('OpenLP.ServiceManager', 'Save this service'),
|
||||||
self.saveFile)
|
self.saveFile)
|
||||||
self.toolbar.addSeparator()
|
self.toolbar.addSeparator()
|
||||||
self.themeLabel = QtGui.QLabel(u'%s:' % UiStrings.Theme, self)
|
self.themeLabel = QtGui.QLabel(u'%s:' % UiStrings().Theme, self)
|
||||||
self.themeLabel.setMargin(3)
|
self.themeLabel.setMargin(3)
|
||||||
self.themeLabel.setObjectName(u'themeLabel')
|
self.themeLabel.setObjectName(u'themeLabel')
|
||||||
self.toolbar.addToolbarWidget(u'ThemeLabel', self.themeLabel)
|
self.toolbar.addToolbarWidget(u'ThemeLabel', self.themeLabel)
|
||||||
@ -169,9 +169,10 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.onServiceTop, shortcuts=[QtCore.Qt.Key_Home])
|
self.onServiceTop, shortcuts=[QtCore.Qt.Key_Home])
|
||||||
self.serviceManagerList.moveTop.setObjectName(u'moveTop')
|
self.serviceManagerList.moveTop.setObjectName(u'moveTop')
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_category(UiStrings.Service, CategoryOrder.standardToolbar)
|
action_list.add_category(
|
||||||
|
UiStrings().Service, CategoryOrder.standardToolbar)
|
||||||
action_list.add_action(
|
action_list.add_action(
|
||||||
self.serviceManagerList.moveTop, UiStrings.Service)
|
self.serviceManagerList.moveTop, UiStrings().Service)
|
||||||
self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton(
|
self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton(
|
||||||
translate('OpenLP.ServiceManager', 'Move &up'),
|
translate('OpenLP.ServiceManager', 'Move &up'),
|
||||||
u':/services/service_up.png',
|
u':/services/service_up.png',
|
||||||
@ -179,7 +180,8 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
'Move item up one position in the service.'),
|
'Move item up one position in the service.'),
|
||||||
self.onServiceUp, shortcuts=[QtCore.Qt.Key_PageUp])
|
self.onServiceUp, shortcuts=[QtCore.Qt.Key_PageUp])
|
||||||
self.serviceManagerList.moveUp.setObjectName(u'moveUp')
|
self.serviceManagerList.moveUp.setObjectName(u'moveUp')
|
||||||
action_list.add_action(self.serviceManagerList.moveUp, UiStrings.Service)
|
action_list.add_action(
|
||||||
|
self.serviceManagerList.moveUp, UiStrings().Service)
|
||||||
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton(
|
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton(
|
||||||
translate('OpenLP.ServiceManager', 'Move &down'),
|
translate('OpenLP.ServiceManager', 'Move &down'),
|
||||||
u':/services/service_down.png',
|
u':/services/service_down.png',
|
||||||
@ -188,7 +190,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.onServiceDown, shortcuts=[QtCore.Qt.Key_PageDown])
|
self.onServiceDown, shortcuts=[QtCore.Qt.Key_PageDown])
|
||||||
self.serviceManagerList.moveDown.setObjectName(u'moveDown')
|
self.serviceManagerList.moveDown.setObjectName(u'moveDown')
|
||||||
action_list.add_action(
|
action_list.add_action(
|
||||||
self.serviceManagerList.moveDown, UiStrings.Service)
|
self.serviceManagerList.moveDown, UiStrings().Service)
|
||||||
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton(
|
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton(
|
||||||
translate('OpenLP.ServiceManager', 'Move to &bottom'),
|
translate('OpenLP.ServiceManager', 'Move to &bottom'),
|
||||||
u':/services/service_bottom.png',
|
u':/services/service_bottom.png',
|
||||||
@ -197,7 +199,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.onServiceEnd, shortcuts=[QtCore.Qt.Key_End])
|
self.onServiceEnd, shortcuts=[QtCore.Qt.Key_End])
|
||||||
self.serviceManagerList.moveBottom.setObjectName(u'moveBottom')
|
self.serviceManagerList.moveBottom.setObjectName(u'moveBottom')
|
||||||
action_list.add_action(
|
action_list.add_action(
|
||||||
self.serviceManagerList.moveBottom, UiStrings.Service)
|
self.serviceManagerList.moveBottom, UiStrings().Service)
|
||||||
self.serviceManagerList.down = self.orderToolbar.addToolbarButton(
|
self.serviceManagerList.down = self.orderToolbar.addToolbarButton(
|
||||||
translate('OpenLP.ServiceManager', 'Move &down'),
|
translate('OpenLP.ServiceManager', 'Move &down'),
|
||||||
None,
|
None,
|
||||||
@ -231,7 +233,8 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
'Expand all the service items.'),
|
'Expand all the service items.'),
|
||||||
self.onExpandAll, shortcuts=[QtCore.Qt.Key_Plus])
|
self.onExpandAll, shortcuts=[QtCore.Qt.Key_Plus])
|
||||||
self.serviceManagerList.expand.setObjectName(u'expand')
|
self.serviceManagerList.expand.setObjectName(u'expand')
|
||||||
action_list.add_action(self.serviceManagerList.expand, UiStrings.Service)
|
action_list.add_action(
|
||||||
|
self.serviceManagerList.expand, UiStrings().Service)
|
||||||
self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton(
|
self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton(
|
||||||
translate('OpenLP.ServiceManager', '&Collapse all'),
|
translate('OpenLP.ServiceManager', '&Collapse all'),
|
||||||
u':/services/service_collapse_all.png',
|
u':/services/service_collapse_all.png',
|
||||||
@ -240,7 +243,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.onCollapseAll, shortcuts=[QtCore.Qt.Key_Minus])
|
self.onCollapseAll, shortcuts=[QtCore.Qt.Key_Minus])
|
||||||
self.serviceManagerList.collapse.setObjectName(u'collapse')
|
self.serviceManagerList.collapse.setObjectName(u'collapse')
|
||||||
action_list.add_action(
|
action_list.add_action(
|
||||||
self.serviceManagerList.collapse, UiStrings.Service)
|
self.serviceManagerList.collapse, UiStrings().Service)
|
||||||
self.orderToolbar.addSeparator()
|
self.orderToolbar.addSeparator()
|
||||||
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton(
|
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton(
|
||||||
translate('OpenLP.ServiceManager', 'Go Live'),
|
translate('OpenLP.ServiceManager', 'Go Live'),
|
||||||
@ -250,7 +253,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
|
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
|
||||||
self.serviceManagerList.makeLive.setObjectName(u'orderToolbar')
|
self.serviceManagerList.makeLive.setObjectName(u'orderToolbar')
|
||||||
action_list.add_action(
|
action_list.add_action(
|
||||||
self.serviceManagerList.makeLive, UiStrings.Service)
|
self.serviceManagerList.makeLive, UiStrings().Service)
|
||||||
self.layout.addWidget(self.orderToolbar)
|
self.layout.addWidget(self.orderToolbar)
|
||||||
# Connect up our signals and slots
|
# Connect up our signals and slots
|
||||||
QtCore.QObject.connect(self.themeComboBox,
|
QtCore.QObject.connect(self.themeComboBox,
|
||||||
@ -344,7 +347,8 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
has been modified.
|
has been modified.
|
||||||
"""
|
"""
|
||||||
self._modified = modified
|
self._modified = modified
|
||||||
serviceFile = self.shortFileName() or u'Untitled Service'
|
serviceFile = self.shortFileName() or translate(
|
||||||
|
'OpenLP.ServiceManager', 'Untitled Service')
|
||||||
self.mainwindow.setServiceModified(modified, serviceFile)
|
self.mainwindow.setServiceModified(modified, serviceFile)
|
||||||
|
|
||||||
def isModified(self):
|
def isModified(self):
|
||||||
@ -525,7 +529,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
save the file.
|
save the file.
|
||||||
"""
|
"""
|
||||||
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
|
fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow,
|
||||||
UiStrings.SaveService,
|
UiStrings().SaveService,
|
||||||
SettingsManager.get_last_dir(
|
SettingsManager.get_last_dir(
|
||||||
self.mainwindow.serviceSettingsSection),
|
self.mainwindow.serviceSettingsSection),
|
||||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
||||||
@ -575,7 +579,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
for item in items:
|
for item in items:
|
||||||
serviceItem = ServiceItem()
|
serviceItem = ServiceItem()
|
||||||
serviceItem.from_service = True
|
serviceItem.from_service = True
|
||||||
serviceItem.render_manager = self.mainwindow.renderManager
|
serviceItem.renderer = self.mainwindow.renderer
|
||||||
serviceItem.set_from_service(item, self.servicePath)
|
serviceItem.set_from_service(item, self.servicePath)
|
||||||
self.validateItem(serviceItem)
|
self.validateItem(serviceItem)
|
||||||
self.addServiceItem(serviceItem)
|
self.addServiceItem(serviceItem)
|
||||||
@ -611,7 +615,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
u'%s' % fileName)
|
u'%s' % fileName)
|
||||||
QtGui.QMessageBox.information(self,
|
QtGui.QMessageBox.information(self,
|
||||||
translate('OpenLP.ServiceManager', 'Corrupt File'),
|
translate('OpenLP.ServiceManager', 'Corrupt File'),
|
||||||
translate('OpenLP.ServiceManager', 'This file is either'
|
translate('OpenLP.ServiceManager', 'This file is either '
|
||||||
'corrupt or not an OpenLP 2.0 service file.'))
|
'corrupt or not an OpenLP 2.0 service file.'))
|
||||||
return
|
return
|
||||||
finally:
|
finally:
|
||||||
@ -682,6 +686,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.serviceItems[item][u'service_item'].notes = \
|
self.serviceItems[item][u'service_item'].notes = \
|
||||||
self.serviceNoteForm.textEdit.toPlainText()
|
self.serviceNoteForm.textEdit.toPlainText()
|
||||||
self.repaintServiceList(item, -1)
|
self.repaintServiceList(item, -1)
|
||||||
|
self.setModified()
|
||||||
|
|
||||||
def onStartTimeForm(self):
|
def onStartTimeForm(self):
|
||||||
item = self.findServiceItem()[0]
|
item = self.findServiceItem()[0]
|
||||||
@ -785,7 +790,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
# Top Item was selected so set the last one
|
# Top Item was selected so set the last one
|
||||||
if setLastItem:
|
if setLastItem:
|
||||||
lastItem.setSelected(True)
|
lastItem.setSelected(True)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def onMoveSelectionDown(self):
|
def onMoveSelectionDown(self):
|
||||||
"""
|
"""
|
||||||
@ -807,7 +812,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
serviceIterator += 1
|
serviceIterator += 1
|
||||||
if setSelected:
|
if setSelected:
|
||||||
firstItem.setSelected(True)
|
firstItem.setSelected(True)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def onCollapseAll(self):
|
def onCollapseAll(self):
|
||||||
"""
|
"""
|
||||||
@ -851,7 +856,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.serviceItems.remove(self.serviceItems[item])
|
self.serviceItems.remove(self.serviceItems[item])
|
||||||
self.serviceItems.insert(0, temp)
|
self.serviceItems.insert(0, temp)
|
||||||
self.repaintServiceList(0, child)
|
self.repaintServiceList(0, child)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def onServiceUp(self):
|
def onServiceUp(self):
|
||||||
"""
|
"""
|
||||||
@ -863,7 +868,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.serviceItems.remove(self.serviceItems[item])
|
self.serviceItems.remove(self.serviceItems[item])
|
||||||
self.serviceItems.insert(item - 1, temp)
|
self.serviceItems.insert(item - 1, temp)
|
||||||
self.repaintServiceList(item - 1, child)
|
self.repaintServiceList(item - 1, child)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def onServiceDown(self):
|
def onServiceDown(self):
|
||||||
"""
|
"""
|
||||||
@ -875,7 +880,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.serviceItems.remove(self.serviceItems[item])
|
self.serviceItems.remove(self.serviceItems[item])
|
||||||
self.serviceItems.insert(item + 1, temp)
|
self.serviceItems.insert(item + 1, temp)
|
||||||
self.repaintServiceList(item + 1, child)
|
self.repaintServiceList(item + 1, child)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def onServiceEnd(self):
|
def onServiceEnd(self):
|
||||||
"""
|
"""
|
||||||
@ -887,7 +892,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.serviceItems.remove(self.serviceItems[item])
|
self.serviceItems.remove(self.serviceItems[item])
|
||||||
self.serviceItems.insert(len(self.serviceItems), temp)
|
self.serviceItems.insert(len(self.serviceItems), temp)
|
||||||
self.repaintServiceList(len(self.serviceItems) - 1, child)
|
self.repaintServiceList(len(self.serviceItems) - 1, child)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def onDeleteFromService(self):
|
def onDeleteFromService(self):
|
||||||
"""
|
"""
|
||||||
@ -897,7 +902,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
if item != -1:
|
if item != -1:
|
||||||
self.serviceItems.remove(self.serviceItems[item])
|
self.serviceItems.remove(self.serviceItems[item])
|
||||||
self.repaintServiceList(item - 1, -1)
|
self.repaintServiceList(item - 1, -1)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def repaintServiceList(self, serviceItem, serviceItemChild):
|
def repaintServiceList(self, serviceItem, serviceItemChild):
|
||||||
"""
|
"""
|
||||||
@ -984,7 +989,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
"""
|
"""
|
||||||
log.debug(u'onThemeComboBoxSelected')
|
log.debug(u'onThemeComboBoxSelected')
|
||||||
self.service_theme = unicode(self.themeComboBox.currentText())
|
self.service_theme = unicode(self.themeComboBox.currentText())
|
||||||
self.mainwindow.renderManager.set_service_theme(self.service_theme)
|
self.mainwindow.renderer.set_service_theme(self.service_theme)
|
||||||
QtCore.QSettings().setValue(
|
QtCore.QSettings().setValue(
|
||||||
self.mainwindow.serviceSettingsSection + u'/service theme',
|
self.mainwindow.serviceSettingsSection + u'/service theme',
|
||||||
QtCore.QVariant(self.service_theme))
|
QtCore.QVariant(self.service_theme))
|
||||||
@ -996,7 +1001,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
sure the theme combo box is in the correct state.
|
sure the theme combo box is in the correct state.
|
||||||
"""
|
"""
|
||||||
log.debug(u'themeChange')
|
log.debug(u'themeChange')
|
||||||
if self.mainwindow.renderManager.theme_level == ThemeLevel.Global:
|
if self.mainwindow.renderer.theme_level == ThemeLevel.Global:
|
||||||
self.toolbar.actions[u'ThemeLabel'].setVisible(False)
|
self.toolbar.actions[u'ThemeLabel'].setVisible(False)
|
||||||
self.toolbar.actions[u'ThemeWidget'].setVisible(False)
|
self.toolbar.actions[u'ThemeWidget'].setVisible(False)
|
||||||
else:
|
else:
|
||||||
@ -1011,7 +1016,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
Receiver.send_message(u'cursor_busy')
|
Receiver.send_message(u'cursor_busy')
|
||||||
log.debug(u'regenerateServiceItems')
|
log.debug(u'regenerateServiceItems')
|
||||||
# force reset of renderer as theme data has changed
|
# force reset of renderer as theme data has changed
|
||||||
self.mainwindow.renderManager.themedata = None
|
self.mainwindow.renderer.themedata = None
|
||||||
if self.serviceItems:
|
if self.serviceItems:
|
||||||
tempServiceItems = self.serviceItems
|
tempServiceItems = self.serviceItems
|
||||||
self.serviceManagerList.clear()
|
self.serviceManagerList.clear()
|
||||||
@ -1022,7 +1027,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
item[u'service_item'], False, expand=item[u'expanded'])
|
item[u'service_item'], False, expand=item[u'expanded'])
|
||||||
# Set to False as items may have changed rendering
|
# Set to False as items may have changed rendering
|
||||||
# does not impact the saved song so True may also be valid
|
# does not impact the saved song so True may also be valid
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
Receiver.send_message(u'cursor_normal')
|
Receiver.send_message(u'cursor_normal')
|
||||||
|
|
||||||
def serviceItemUpdate(self, message):
|
def serviceItemUpdate(self, message):
|
||||||
@ -1033,7 +1038,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
for item in self.serviceItems:
|
for item in self.serviceItems:
|
||||||
if item[u'service_item']._uuid == uuid:
|
if item[u'service_item']._uuid == uuid:
|
||||||
item[u'service_item'].edit_id = int(editId)
|
item[u'service_item'].edit_id = int(editId)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def replaceServiceItem(self, newItem):
|
def replaceServiceItem(self, newItem):
|
||||||
"""
|
"""
|
||||||
@ -1049,7 +1054,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.repaintServiceList(itemcount + 1, 0)
|
self.repaintServiceList(itemcount + 1, 0)
|
||||||
self.mainwindow.liveController.replaceServiceManagerItem(
|
self.mainwindow.liveController.replaceServiceManagerItem(
|
||||||
newItem)
|
newItem)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def addServiceItem(self, item, rebuild=False, expand=None, replace=False):
|
def addServiceItem(self, item, rebuild=False, expand=None, replace=False):
|
||||||
"""
|
"""
|
||||||
@ -1094,7 +1099,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
if rebuild:
|
if rebuild:
|
||||||
self.mainwindow.liveController.replaceServiceManagerItem(item)
|
self.mainwindow.liveController.replaceServiceManagerItem(item)
|
||||||
self.dropPosition = 0
|
self.dropPosition = 0
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
|
|
||||||
def makePreview(self):
|
def makePreview(self):
|
||||||
"""
|
"""
|
||||||
@ -1231,7 +1236,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.serviceItems.remove(serviceItem)
|
self.serviceItems.remove(serviceItem)
|
||||||
self.serviceItems.insert(endpos, serviceItem)
|
self.serviceItems.insert(endpos, serviceItem)
|
||||||
self.repaintServiceList(endpos, child)
|
self.repaintServiceList(endpos, child)
|
||||||
self.setModified(True)
|
self.setModified()
|
||||||
else:
|
else:
|
||||||
# we are not over anything so drop
|
# we are not over anything so drop
|
||||||
replace = False
|
replace = False
|
||||||
@ -1273,7 +1278,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.onThemeChangeAction, context=QtCore.Qt.WidgetShortcut)
|
self.onThemeChangeAction, context=QtCore.Qt.WidgetShortcut)
|
||||||
self.themeMenu.addAction(action)
|
self.themeMenu.addAction(action)
|
||||||
find_and_set_in_combo_box(self.themeComboBox, self.service_theme)
|
find_and_set_in_combo_box(self.themeComboBox, self.service_theme)
|
||||||
self.mainwindow.renderManager.set_service_theme(self.service_theme)
|
self.mainwindow.renderer.set_service_theme(self.service_theme)
|
||||||
self.regenerateServiceItems()
|
self.regenerateServiceItems()
|
||||||
|
|
||||||
def onThemeChangeAction(self):
|
def onThemeChangeAction(self):
|
||||||
|
@ -37,7 +37,7 @@ class Ui_SettingsDialog(object):
|
|||||||
build_icon(u':/system/system_settings.png'))
|
build_icon(u':/system/system_settings.png'))
|
||||||
self.dialogLayout = QtGui.QGridLayout(settingsDialog)
|
self.dialogLayout = QtGui.QGridLayout(settingsDialog)
|
||||||
self.dialogLayout.setObjectName(u'dialogLayout')
|
self.dialogLayout.setObjectName(u'dialogLayout')
|
||||||
self.dialogLayout.setMargin(0)
|
self.dialogLayout.setMargin(8)
|
||||||
self.settingListWidget = QtGui.QListWidget(settingsDialog)
|
self.settingListWidget = QtGui.QListWidget(settingsDialog)
|
||||||
self.settingListWidget.setUniformItemSizes(True)
|
self.settingListWidget.setUniformItemSizes(True)
|
||||||
self.settingListWidget.setMinimumSize(QtCore.QSize(150, 0))
|
self.settingListWidget.setMinimumSize(QtCore.QSize(150, 0))
|
||||||
|
@ -75,6 +75,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
|||||||
Add a tab to the form at a specific location
|
Add a tab to the form at a specific location
|
||||||
"""
|
"""
|
||||||
log.debug(u'Inserting %s tab' % tab.tabTitle)
|
log.debug(u'Inserting %s tab' % tab.tabTitle)
|
||||||
|
# add the tab to get it to display in the correct part of the screen
|
||||||
pos = self.stackedLayout.addWidget(tab)
|
pos = self.stackedLayout.addWidget(tab)
|
||||||
if is_active:
|
if is_active:
|
||||||
item_name = QtGui.QListWidgetItem(tab.tabTitleVisible)
|
item_name = QtGui.QListWidgetItem(tab.tabTitleVisible)
|
||||||
@ -82,7 +83,9 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
|||||||
item_name.setIcon(icon)
|
item_name.setIcon(icon)
|
||||||
self.settingListWidget.insertItem(location, item_name)
|
self.settingListWidget.insertItem(location, item_name)
|
||||||
else:
|
else:
|
||||||
self.stackedLayout.takeAt(location)
|
# then remove tab to stop the UI displaying it even if
|
||||||
|
# it is not required.
|
||||||
|
self.stackedLayout.takeAt(pos)
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
"""
|
"""
|
||||||
|
@ -29,6 +29,7 @@ import re
|
|||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
from openlp.core.lib import Receiver
|
||||||
from openlp.core.utils import translate
|
from openlp.core.utils import translate
|
||||||
from openlp.core.utils.actions import ActionList
|
from openlp.core.utils.actions import ActionList
|
||||||
from shortcutlistdialog import Ui_ShortcutListDialog
|
from shortcutlistdialog import Ui_ShortcutListDialog
|
||||||
@ -95,43 +96,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
QtCore.Qt.ShiftModifier:
|
QtCore.Qt.ShiftModifier:
|
||||||
key_string = u'Shift+' + key_string
|
key_string = u'Shift+' + key_string
|
||||||
key_sequence = QtGui.QKeySequence(key_string)
|
key_sequence = QtGui.QKeySequence(key_string)
|
||||||
# The action we are attempting to change.
|
if self._validiate_shortcut(self._currentItemAction(), key_sequence):
|
||||||
changing_action = self._currentItemAction()
|
|
||||||
shortcut_valid = True
|
|
||||||
for category in self.action_list.categories:
|
|
||||||
for action in category.actions:
|
|
||||||
shortcuts = self._actionShortcuts(action)
|
|
||||||
if key_sequence not in shortcuts:
|
|
||||||
continue
|
|
||||||
if action is changing_action:
|
|
||||||
if self.primaryPushButton.isChecked() and \
|
|
||||||
shortcuts.index(key_sequence) == 0:
|
|
||||||
continue
|
|
||||||
if self.alternatePushButton.isChecked() and \
|
|
||||||
shortcuts.index(key_sequence) == 1:
|
|
||||||
continue
|
|
||||||
# Have the same parent, thus they cannot have the same shortcut.
|
|
||||||
if action.parent() is changing_action.parent():
|
|
||||||
shortcut_valid = False
|
|
||||||
# The new shortcut is already assigned, but if both shortcuts
|
|
||||||
# are only valid in a different widget the new shortcut is
|
|
||||||
# vaild, because they will not interfere.
|
|
||||||
if action.shortcutContext() in [QtCore.Qt.WindowShortcut,
|
|
||||||
QtCore.Qt.ApplicationShortcut]:
|
|
||||||
shortcut_valid = False
|
|
||||||
if changing_action.shortcutContext() in \
|
|
||||||
[QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
|
||||||
shortcut_valid = False
|
|
||||||
if not shortcut_valid:
|
|
||||||
QtGui.QMessageBox.warning(self,
|
|
||||||
translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'),
|
|
||||||
unicode(translate('OpenLP.ShortcutListDialog', 'The shortcut '
|
|
||||||
'"%s" is already assigned to another action, please '
|
|
||||||
'use a different shortcut.')) % key_sequence.toString(),
|
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
|
|
||||||
QtGui.QMessageBox.Ok
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
if self.primaryPushButton.isChecked():
|
if self.primaryPushButton.isChecked():
|
||||||
self._adjustButton(self.primaryPushButton,
|
self._adjustButton(self.primaryPushButton,
|
||||||
False, text=key_sequence.toString())
|
False, text=key_sequence.toString())
|
||||||
@ -227,6 +192,12 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
new_shortcuts.append(
|
new_shortcuts.append(
|
||||||
QtGui.QKeySequence(self.alternatePushButton.text()))
|
QtGui.QKeySequence(self.alternatePushButton.text()))
|
||||||
self.changedActions[action] = new_shortcuts
|
self.changedActions[action] = new_shortcuts
|
||||||
|
if not self.primaryPushButton.text():
|
||||||
|
# When we do not have a primary shortcut, the just entered alternate
|
||||||
|
# shortcut will automatically become the primary shortcut. That is
|
||||||
|
# why we have to adjust the primary button's text.
|
||||||
|
self.primaryPushButton.setText(self.alternatePushButton.text())
|
||||||
|
self.alternatePushButton.setText(u'')
|
||||||
self.refreshShortcutList()
|
self.refreshShortcutList()
|
||||||
|
|
||||||
def onItemDoubleClicked(self, item, column):
|
def onItemDoubleClicked(self, item, column):
|
||||||
@ -374,6 +345,16 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
new_shortcuts = []
|
new_shortcuts = []
|
||||||
if len(action.defaultShortcuts) != 0:
|
if len(action.defaultShortcuts) != 0:
|
||||||
new_shortcuts.append(action.defaultShortcuts[0])
|
new_shortcuts.append(action.defaultShortcuts[0])
|
||||||
|
# We have to check if the primary default shortcut is available. But
|
||||||
|
# we only have to check, if the action has a default primary
|
||||||
|
# shortcut (an "empty" shortcut is always valid and if the action
|
||||||
|
# does not have a default primary shortcut, then the alternative
|
||||||
|
# shortcut (not the default one) will become primary shortcut, thus
|
||||||
|
# the check will assume that an action were going to have the same
|
||||||
|
# shortcut twice.
|
||||||
|
if not self._validiate_shortcut(action, new_shortcuts[0]) and \
|
||||||
|
new_shortcuts[0] != shortcuts[0]:
|
||||||
|
return
|
||||||
if len(shortcuts) == 2:
|
if len(shortcuts) == 2:
|
||||||
new_shortcuts.append(shortcuts[1])
|
new_shortcuts.append(shortcuts[1])
|
||||||
self.changedActions[action] = new_shortcuts
|
self.changedActions[action] = new_shortcuts
|
||||||
@ -394,10 +375,60 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
new_shortcuts.append(shortcuts[0])
|
new_shortcuts.append(shortcuts[0])
|
||||||
if len(action.defaultShortcuts) == 2:
|
if len(action.defaultShortcuts) == 2:
|
||||||
new_shortcuts.append(action.defaultShortcuts[1])
|
new_shortcuts.append(action.defaultShortcuts[1])
|
||||||
|
if len(new_shortcuts) == 2:
|
||||||
|
if not self._validiate_shortcut(action, new_shortcuts[1]):
|
||||||
|
return
|
||||||
self.changedActions[action] = new_shortcuts
|
self.changedActions[action] = new_shortcuts
|
||||||
self.refreshShortcutList()
|
self.refreshShortcutList()
|
||||||
self.onCurrentItemChanged(self.treeWidget.currentItem())
|
self.onCurrentItemChanged(self.treeWidget.currentItem())
|
||||||
|
|
||||||
|
def _validiate_shortcut(self, changing_action, key_sequence):
|
||||||
|
"""
|
||||||
|
Checks if the given ``changing_action `` can use the given
|
||||||
|
``key_sequence``. Returns ``True`` if the ``key_sequence`` can be used
|
||||||
|
by the action, otherwise displays a dialog and returns ``False``.
|
||||||
|
|
||||||
|
``changing_action``
|
||||||
|
The action which wants to use the ``key_sequence``.
|
||||||
|
|
||||||
|
``key_sequence``
|
||||||
|
The key sequence which the action want so use.
|
||||||
|
"""
|
||||||
|
is_valid = True
|
||||||
|
for category in self.action_list.categories:
|
||||||
|
for action in category.actions:
|
||||||
|
shortcuts = self._actionShortcuts(action)
|
||||||
|
if key_sequence not in shortcuts:
|
||||||
|
continue
|
||||||
|
if action is changing_action:
|
||||||
|
if self.primaryPushButton.isChecked() and \
|
||||||
|
shortcuts.index(key_sequence) == 0:
|
||||||
|
continue
|
||||||
|
if self.alternatePushButton.isChecked() and \
|
||||||
|
shortcuts.index(key_sequence) == 1:
|
||||||
|
continue
|
||||||
|
# Have the same parent, thus they cannot have the same shortcut.
|
||||||
|
if action.parent() is changing_action.parent():
|
||||||
|
is_valid = False
|
||||||
|
# The new shortcut is already assigned, but if both shortcuts
|
||||||
|
# are only valid in a different widget the new shortcut is
|
||||||
|
# vaild, because they will not interfere.
|
||||||
|
if action.shortcutContext() in [QtCore.Qt.WindowShortcut,
|
||||||
|
QtCore.Qt.ApplicationShortcut]:
|
||||||
|
is_valid = False
|
||||||
|
if changing_action.shortcutContext() in \
|
||||||
|
[QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||||
|
is_valid = False
|
||||||
|
if not is_valid:
|
||||||
|
Receiver.send_message(u'openlp_warning_message', {
|
||||||
|
u'title': translate('OpenLP.ShortcutListDialog',
|
||||||
|
'Duplicate Shortcut'),
|
||||||
|
u'message': unicode(translate('OpenLP.ShortcutListDialog',
|
||||||
|
'The shortcut "%s" is already assigned to another action, '
|
||||||
|
'please use a different shortcut.')) % key_sequence.toString()
|
||||||
|
})
|
||||||
|
return is_valid
|
||||||
|
|
||||||
def _actionShortcuts(self, action):
|
def _actionShortcuts(self, action):
|
||||||
"""
|
"""
|
||||||
This returns the shortcuts for the given ``action``, which also includes
|
This returns the shortcuts for the given ``action``, which also includes
|
||||||
|
@ -88,11 +88,11 @@ class SlideController(QtGui.QWidget):
|
|||||||
# Type label for the top of the slide controller
|
# Type label for the top of the slide controller
|
||||||
self.typeLabel = QtGui.QLabel(self.panel)
|
self.typeLabel = QtGui.QLabel(self.panel)
|
||||||
if self.isLive:
|
if self.isLive:
|
||||||
self.typeLabel.setText(UiStrings.Live)
|
self.typeLabel.setText(UiStrings().Live)
|
||||||
self.split = 1
|
self.split = 1
|
||||||
self.typePrefix = u'live'
|
self.typePrefix = u'live'
|
||||||
else:
|
else:
|
||||||
self.typeLabel.setText(UiStrings.Preview)
|
self.typeLabel.setText(UiStrings().Preview)
|
||||||
self.split = 0
|
self.split = 0
|
||||||
self.typePrefix = u'preview'
|
self.typePrefix = u'preview'
|
||||||
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
|
self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
|
||||||
@ -161,18 +161,18 @@ class SlideController(QtGui.QWidget):
|
|||||||
translate('OpenLP.SlideController', 'Hide'), self.toolbar))
|
translate('OpenLP.SlideController', 'Hide'), self.toolbar))
|
||||||
self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen',
|
self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen',
|
||||||
[QtCore.Qt.Key_Period], self.onBlankDisplay,
|
[QtCore.Qt.Key_Period], self.onBlankDisplay,
|
||||||
u':/slides/slide_blank.png', False, UiStrings.LiveToolbar)
|
u':/slides/slide_blank.png', False, UiStrings().LiveToolbar)
|
||||||
self.blankScreen.setText(
|
self.blankScreen.setText(
|
||||||
translate('OpenLP.SlideController', 'Blank Screen'))
|
translate('OpenLP.SlideController', 'Blank Screen'))
|
||||||
self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen',
|
self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen',
|
||||||
[QtGui.QKeySequence(u'T')], self.onThemeDisplay,
|
[QtGui.QKeySequence(u'T')], self.onThemeDisplay,
|
||||||
u':/slides/slide_theme.png', False, UiStrings.LiveToolbar)
|
u':/slides/slide_theme.png', False, UiStrings().LiveToolbar)
|
||||||
self.themeScreen.setText(
|
self.themeScreen.setText(
|
||||||
translate('OpenLP.SlideController', 'Blank to Theme'))
|
translate('OpenLP.SlideController', 'Blank to Theme'))
|
||||||
self.desktopScreen = shortcut_action(self.hideMenu,
|
self.desktopScreen = shortcut_action(self.hideMenu,
|
||||||
u'desktopScreen', [QtGui.QKeySequence(u'D')],
|
u'desktopScreen', [QtGui.QKeySequence(u'D')],
|
||||||
self.onHideDisplay, u':/slides/slide_desktop.png', False,
|
self.onHideDisplay, u':/slides/slide_desktop.png', False,
|
||||||
UiStrings.LiveToolbar)
|
UiStrings().LiveToolbar)
|
||||||
self.desktopScreen.setText(
|
self.desktopScreen.setText(
|
||||||
translate('OpenLP.SlideController', 'Show Desktop'))
|
translate('OpenLP.SlideController', 'Show Desktop'))
|
||||||
self.hideMenu.setDefaultAction(self.blankScreen)
|
self.hideMenu.setDefaultAction(self.blankScreen)
|
||||||
@ -180,21 +180,30 @@ class SlideController(QtGui.QWidget):
|
|||||||
self.hideMenu.menu().addAction(self.themeScreen)
|
self.hideMenu.menu().addAction(self.themeScreen)
|
||||||
self.hideMenu.menu().addAction(self.desktopScreen)
|
self.hideMenu.menu().addAction(self.desktopScreen)
|
||||||
self.toolbar.addToolbarSeparator(u'Loop Separator')
|
self.toolbar.addToolbarSeparator(u'Loop Separator')
|
||||||
self.toolbar.addToolbarButton(
|
startLoop = self.toolbar.addToolbarButton(
|
||||||
# Does not need translating - control string.
|
# Does not need translating - control string.
|
||||||
u'Start Loop', u':/media/media_time.png',
|
u'Start Loop', u':/media/media_time.png',
|
||||||
translate('OpenLP.SlideController', 'Start continuous loop'),
|
translate('OpenLP.SlideController', 'Start continuous loop'),
|
||||||
self.onStartLoop)
|
self.onStartLoop)
|
||||||
self.toolbar.addToolbarButton(
|
action_list = ActionList.get_instance()
|
||||||
|
action_list.add_action(startLoop, UiStrings().LiveToolbar)
|
||||||
|
stopLoop = self.toolbar.addToolbarButton(
|
||||||
# Does not need translating - control string.
|
# Does not need translating - control string.
|
||||||
u'Stop Loop', u':/media/media_stop.png',
|
u'Stop Loop', u':/media/media_stop.png',
|
||||||
translate('OpenLP.SlideController', 'Stop continuous loop'),
|
translate('OpenLP.SlideController', 'Stop continuous loop'),
|
||||||
self.onStopLoop)
|
self.onStopLoop)
|
||||||
|
action_list.add_action(stopLoop, UiStrings().LiveToolbar)
|
||||||
|
self.toogleLoop = shortcut_action(self, u'toogleLoop',
|
||||||
|
[QtGui.QKeySequence(u'L')], self.onToggleLoop,
|
||||||
|
category=UiStrings().LiveToolbar)
|
||||||
|
self.toogleLoop.setText(translate('OpenLP.SlideController',
|
||||||
|
'Start/Stop continuous loop'))
|
||||||
|
self.addAction(self.toogleLoop)
|
||||||
self.delaySpinBox = QtGui.QSpinBox()
|
self.delaySpinBox = QtGui.QSpinBox()
|
||||||
self.delaySpinBox.setMinimum(1)
|
self.delaySpinBox.setMinimum(1)
|
||||||
self.delaySpinBox.setMaximum(180)
|
self.delaySpinBox.setMaximum(180)
|
||||||
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
|
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
|
||||||
self.delaySpinBox.setSuffix(UiStrings.Seconds)
|
self.delaySpinBox.setSuffix(UiStrings().Seconds)
|
||||||
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
|
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
|
||||||
'Delay between slides in seconds'))
|
'Delay between slides in seconds'))
|
||||||
else:
|
else:
|
||||||
@ -376,22 +385,25 @@ class SlideController(QtGui.QWidget):
|
|||||||
self.nextItem.setObjectName(u'nextItemLive')
|
self.nextItem.setObjectName(u'nextItemLive')
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_category(
|
action_list.add_category(
|
||||||
UiStrings.LiveToolbar, CategoryOrder.standardToolbar)
|
UiStrings().LiveToolbar, CategoryOrder.standardToolbar)
|
||||||
action_list.add_action(self.previousItem)
|
action_list.add_action(self.previousItem)
|
||||||
action_list.add_action(self.nextItem)
|
action_list.add_action(self.nextItem)
|
||||||
self.previousService = shortcut_action(parent, u'previousService',
|
self.previousService = shortcut_action(parent, u'previousService',
|
||||||
[QtCore.Qt.Key_Left], self.servicePrevious, UiStrings.LiveToolbar)
|
[QtCore.Qt.Key_Left], self.servicePrevious,
|
||||||
self.previousService.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
|
category=UiStrings().LiveToolbar,
|
||||||
|
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||||
self.previousService.setText(
|
self.previousService.setText(
|
||||||
translate('OpenLP.SlideController', 'Previous Service'))
|
translate('OpenLP.SlideController', 'Previous Service'))
|
||||||
self.nextService = shortcut_action(parent, 'nextService',
|
self.nextService = shortcut_action(parent, 'nextService',
|
||||||
[QtCore.Qt.Key_Right], self.serviceNext, UiStrings.LiveToolbar)
|
[QtCore.Qt.Key_Right], self.serviceNext,
|
||||||
self.nextService.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
|
category=UiStrings().LiveToolbar,
|
||||||
|
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||||
self.nextService.setText(
|
self.nextService.setText(
|
||||||
translate('OpenLP.SlideController', 'Next Service'))
|
translate('OpenLP.SlideController', 'Next Service'))
|
||||||
self.escapeItem = shortcut_action(parent, 'escapeItem',
|
self.escapeItem = shortcut_action(parent, 'escapeItem',
|
||||||
[QtCore.Qt.Key_Escape], self.liveEscape, UiStrings.LiveToolbar)
|
[QtCore.Qt.Key_Escape], self.liveEscape,
|
||||||
self.escapeItem.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
|
category=UiStrings().LiveToolbar,
|
||||||
|
context=QtCore.Qt.WidgetWithChildrenShortcut)
|
||||||
self.escapeItem.setText(
|
self.escapeItem.setText(
|
||||||
translate('OpenLP.SlideController', 'Escape Item'))
|
translate('OpenLP.SlideController', 'Escape Item'))
|
||||||
|
|
||||||
@ -412,7 +424,7 @@ class SlideController(QtGui.QWidget):
|
|||||||
"""
|
"""
|
||||||
# rebuild display as screen size changed
|
# rebuild display as screen size changed
|
||||||
self.display = MainDisplay(self, self.screens, self.isLive)
|
self.display = MainDisplay(self, self.screens, self.isLive)
|
||||||
self.display.imageManager = self.parent.renderManager.image_manager
|
self.display.imageManager = self.parent.renderer.image_manager
|
||||||
self.display.alertTab = self.alertTab
|
self.display.alertTab = self.alertTab
|
||||||
self.display.setup()
|
self.display.setup()
|
||||||
if self.isLive:
|
if self.isLive:
|
||||||
@ -491,6 +503,9 @@ class SlideController(QtGui.QWidget):
|
|||||||
self.mediabar.setVisible(False)
|
self.mediabar.setVisible(False)
|
||||||
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
||||||
self.toolbar.makeWidgetsInvisible(self.loopList)
|
self.toolbar.makeWidgetsInvisible(self.loopList)
|
||||||
|
self.toogleLoop.setEnabled(False)
|
||||||
|
self.toolbar.actions[u'Start Loop'].setEnabled(False)
|
||||||
|
self.toolbar.actions[u'Stop Loop'].setEnabled(False)
|
||||||
self.toolbar.actions[u'Stop Loop'].setVisible(False)
|
self.toolbar.actions[u'Stop Loop'].setVisible(False)
|
||||||
if item.is_text():
|
if item.is_text():
|
||||||
if QtCore.QSettings().value(
|
if QtCore.QSettings().value(
|
||||||
@ -500,6 +515,9 @@ class SlideController(QtGui.QWidget):
|
|||||||
if item.is_capable(ItemCapabilities.AllowsLoop) and \
|
if item.is_capable(ItemCapabilities.AllowsLoop) and \
|
||||||
len(item.get_frames()) > 1:
|
len(item.get_frames()) > 1:
|
||||||
self.toolbar.makeWidgetsVisible(self.loopList)
|
self.toolbar.makeWidgetsVisible(self.loopList)
|
||||||
|
self.toogleLoop.setEnabled(True)
|
||||||
|
self.toolbar.actions[u'Start Loop'].setEnabled(True)
|
||||||
|
self.toolbar.actions[u'Stop Loop'].setEnabled(True)
|
||||||
if item.is_media():
|
if item.is_media():
|
||||||
self.toolbar.setVisible(False)
|
self.toolbar.setVisible(False)
|
||||||
self.mediabar.setVisible(True)
|
self.mediabar.setVisible(True)
|
||||||
@ -614,19 +632,19 @@ class SlideController(QtGui.QWidget):
|
|||||||
label.setScaledContents(True)
|
label.setScaledContents(True)
|
||||||
if self.serviceItem.is_command():
|
if self.serviceItem.is_command():
|
||||||
image = resize_image(frame[u'image'],
|
image = resize_image(frame[u'image'],
|
||||||
self.parent.renderManager.width,
|
self.parent.renderer.width,
|
||||||
self.parent.renderManager.height)
|
self.parent.renderer.height)
|
||||||
else:
|
else:
|
||||||
# If current slide set background to image
|
# If current slide set background to image
|
||||||
if framenumber == slideno:
|
if framenumber == slideno:
|
||||||
self.serviceItem.bg_image_bytes = \
|
self.serviceItem.bg_image_bytes = \
|
||||||
self.parent.renderManager.image_manager. \
|
self.parent.renderer.image_manager. \
|
||||||
get_image_bytes(frame[u'title'])
|
get_image_bytes(frame[u'title'])
|
||||||
image = self.parent.renderManager.image_manager. \
|
image = self.parent.renderer.image_manager. \
|
||||||
get_image(frame[u'title'])
|
get_image(frame[u'title'])
|
||||||
label.setPixmap(QtGui.QPixmap.fromImage(image))
|
label.setPixmap(QtGui.QPixmap.fromImage(image))
|
||||||
self.previewListWidget.setCellWidget(framenumber, 0, label)
|
self.previewListWidget.setCellWidget(framenumber, 0, label)
|
||||||
slideHeight = width * self.parent.renderManager.screen_ratio
|
slideHeight = width * self.parent.renderer.screen_ratio
|
||||||
row += 1
|
row += 1
|
||||||
text.append(unicode(row))
|
text.append(unicode(row))
|
||||||
self.previewListWidget.setItem(framenumber, 0, item)
|
self.previewListWidget.setItem(framenumber, 0, item)
|
||||||
@ -992,6 +1010,15 @@ class SlideController(QtGui.QWidget):
|
|||||||
self.previewListWidget.rowCount() - 1)
|
self.previewListWidget.rowCount() - 1)
|
||||||
self.slideSelected()
|
self.slideSelected()
|
||||||
|
|
||||||
|
def onToggleLoop(self, toggled):
|
||||||
|
"""
|
||||||
|
Toggles the loop state.
|
||||||
|
"""
|
||||||
|
if self.toolbar.actions[u'Start Loop'].isVisible():
|
||||||
|
self.onStartLoop()
|
||||||
|
else:
|
||||||
|
self.onStopLoop()
|
||||||
|
|
||||||
def onStartLoop(self):
|
def onStartLoop(self):
|
||||||
"""
|
"""
|
||||||
Start the timer loop running and store the timer id
|
Start the timer loop running and store the timer id
|
||||||
|
@ -107,15 +107,15 @@ class Ui_StartTimeDialog(object):
|
|||||||
def retranslateUi(self, StartTimeDialog):
|
def retranslateUi(self, StartTimeDialog):
|
||||||
self.setWindowTitle(translate('OpenLP.StartTimeForm',
|
self.setWindowTitle(translate('OpenLP.StartTimeForm',
|
||||||
'Item Start and Finish Time'))
|
'Item Start and Finish Time'))
|
||||||
self.hourSpinBox.setSuffix(UiStrings.Hours)
|
self.hourSpinBox.setSuffix(UiStrings().Hours)
|
||||||
self.minuteSpinBox.setSuffix(UiStrings.Minutes)
|
self.minuteSpinBox.setSuffix(UiStrings().Minutes)
|
||||||
self.secondSpinBox.setSuffix(UiStrings.Seconds)
|
self.secondSpinBox.setSuffix(UiStrings().Seconds)
|
||||||
self.hourFinishSpinBox.setSuffix(UiStrings.Hours)
|
self.hourFinishSpinBox.setSuffix(UiStrings().Hours)
|
||||||
self.minuteFinishSpinBox.setSuffix(UiStrings.Minutes)
|
self.minuteFinishSpinBox.setSuffix(UiStrings().Minutes)
|
||||||
self.secondFinishSpinBox.setSuffix(UiStrings.Seconds)
|
self.secondFinishSpinBox.setSuffix(UiStrings().Seconds)
|
||||||
self.hourLabel.setText(translate('OpenLP.StartTimeForm', 'Hours:'))
|
self.hourLabel.setText(translate('OpenLP.StartTimeForm', 'Hours:'))
|
||||||
self.minuteLabel.setText(translate('OpenLP.StartTimeForm', 'Minutes:'))
|
self.minuteLabel.setText(translate('OpenLP.StartTimeForm', 'Minutes:'))
|
||||||
self.secondLabel.setText(translate('OpenLP.StartTimeForm', 'Seconds:'))
|
self.secondLabel.setText(translate('OpenLP.StartTimeForm', 'Seconds:'))
|
||||||
self.startLabel.setText(translate('OpenLP.StartTimeForm', 'Start'))
|
self.startLabel.setText(translate('OpenLP.StartTimeForm', 'Start'))
|
||||||
self.finishLabel.setText(translate('OpenLP.StartTimeForm', 'Finish'))
|
self.finishLabel.setText(translate('OpenLP.StartTimeForm', 'Finish'))
|
||||||
self.lengthLabel.setText(translate('OpenLP.StartTimeForm', 'Length'))
|
self.lengthLabel.setText(translate('OpenLP.StartTimeForm', 'Length'))
|
@ -53,11 +53,12 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
|
|||||||
self.hourFinishSpinBox.setValue(hours)
|
self.hourFinishSpinBox.setValue(hours)
|
||||||
self.minuteFinishSpinBox.setValue(minutes)
|
self.minuteFinishSpinBox.setValue(minutes)
|
||||||
self.secondFinishSpinBox.setValue(seconds)
|
self.secondFinishSpinBox.setValue(seconds)
|
||||||
self.hourFinishLabel.setText(u'%s%s' % (unicode(hour), UiStrings.Hours))
|
self.hourFinishLabel.setText(u'%s%s' % (unicode(hour),
|
||||||
|
UiStrings().Hours))
|
||||||
self.minuteFinishLabel.setText(u'%s%s' %
|
self.minuteFinishLabel.setText(u'%s%s' %
|
||||||
(unicode(minutes), UiStrings.Minutes))
|
(unicode(minutes), UiStrings().Minutes))
|
||||||
self.secondFinishLabel.setText(u'%s%s' %
|
self.secondFinishLabel.setText(u'%s%s' %
|
||||||
(unicode(seconds), UiStrings.Seconds))
|
(unicode(seconds), UiStrings().Seconds))
|
||||||
return QtGui.QDialog.exec_(self)
|
return QtGui.QDialog.exec_(self)
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
|
@ -56,6 +56,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.registerFields()
|
self.registerFields()
|
||||||
self.updateThemeAllowed = True
|
self.updateThemeAllowed = True
|
||||||
|
self.temp_background_filename = u''
|
||||||
QtCore.QObject.connect(self.backgroundComboBox,
|
QtCore.QObject.connect(self.backgroundComboBox,
|
||||||
QtCore.SIGNAL(u'currentIndexChanged(int)'),
|
QtCore.SIGNAL(u'currentIndexChanged(int)'),
|
||||||
self.onBackgroundComboBoxCurrentIndexChanged)
|
self.onBackgroundComboBoxCurrentIndexChanged)
|
||||||
@ -279,6 +280,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||||||
Run the wizard.
|
Run the wizard.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Editing theme %s' % self.theme.theme_name)
|
log.debug(u'Editing theme %s' % self.theme.theme_name)
|
||||||
|
self.temp_background_filename = u''
|
||||||
self.updateThemeAllowed = False
|
self.updateThemeAllowed = False
|
||||||
self.setDefaults()
|
self.setDefaults()
|
||||||
self.updateThemeAllowed = True
|
self.updateThemeAllowed = True
|
||||||
@ -290,7 +292,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||||||
'Edit Theme - %s')) % self.theme.theme_name)
|
'Edit Theme - %s')) % self.theme.theme_name)
|
||||||
self.next()
|
self.next()
|
||||||
else:
|
else:
|
||||||
self.setWindowTitle(UiStrings.NewTheme)
|
self.setWindowTitle(UiStrings().NewTheme)
|
||||||
return QtGui.QWizard.exec_(self)
|
return QtGui.QWizard.exec_(self)
|
||||||
|
|
||||||
def initializePage(self, id):
|
def initializePage(self, id):
|
||||||
@ -432,6 +434,16 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||||||
# do not allow updates when screen is building for the first time.
|
# do not allow updates when screen is building for the first time.
|
||||||
if self.updateThemeAllowed:
|
if self.updateThemeAllowed:
|
||||||
self.theme.background_type = BackgroundType.to_string(index)
|
self.theme.background_type = BackgroundType.to_string(index)
|
||||||
|
if self.theme.background_type != \
|
||||||
|
BackgroundType.to_string(BackgroundType.Image) and \
|
||||||
|
self.temp_background_filename == u'':
|
||||||
|
self.temp_background_filename = self.theme.background_filename
|
||||||
|
self.theme.background_filename = u''
|
||||||
|
if self.theme.background_type == \
|
||||||
|
BackgroundType.to_string(BackgroundType.Image) and \
|
||||||
|
self.temp_background_filename != u'':
|
||||||
|
self.theme.background_filename = self.temp_background_filename
|
||||||
|
self.temp_background_filename = u''
|
||||||
self.setBackgroundPageValues()
|
self.setBackgroundPageValues()
|
||||||
|
|
||||||
def onGradientComboBoxCurrentIndexChanged(self, index):
|
def onGradientComboBoxCurrentIndexChanged(self, index):
|
||||||
@ -473,7 +485,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
|||||||
"""
|
"""
|
||||||
images_filter = get_images_filter()
|
images_filter = get_images_filter()
|
||||||
images_filter = u'%s;;%s (*.*) (*)' % (
|
images_filter = u'%s;;%s (*.*) (*)' % (
|
||||||
images_filter, UiStrings.AllFiles)
|
images_filter, UiStrings().AllFiles)
|
||||||
filename = QtGui.QFileDialog.getOpenFileName(self,
|
filename = QtGui.QFileDialog.getOpenFileName(self,
|
||||||
translate('OpenLP.ThemeForm', 'Select Image'), u'',
|
translate('OpenLP.ThemeForm', 'Select Image'), u'',
|
||||||
images_filter)
|
images_filter)
|
||||||
|
@ -63,7 +63,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self.layout.setMargin(0)
|
self.layout.setMargin(0)
|
||||||
self.layout.setObjectName(u'layout')
|
self.layout.setObjectName(u'layout')
|
||||||
self.toolbar = OpenLPToolbar(self)
|
self.toolbar = OpenLPToolbar(self)
|
||||||
self.toolbar.addToolbarButton(UiStrings.NewTheme,
|
self.toolbar.addToolbarButton(UiStrings().NewTheme,
|
||||||
u':/themes/theme_new.png',
|
u':/themes/theme_new.png',
|
||||||
translate('OpenLP.ThemeManager', 'Create a new theme.'),
|
translate('OpenLP.ThemeManager', 'Create a new theme.'),
|
||||||
self.onAddTheme)
|
self.onAddTheme)
|
||||||
@ -280,6 +280,8 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self.fileRenameForm.fileNameEdit.setText(oldThemeName)
|
self.fileRenameForm.fileNameEdit.setText(oldThemeName)
|
||||||
if self.fileRenameForm.exec_():
|
if self.fileRenameForm.exec_():
|
||||||
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
|
newThemeName = unicode(self.fileRenameForm.fileNameEdit.text())
|
||||||
|
if oldThemeName == newThemeName:
|
||||||
|
return
|
||||||
if self.checkIfThemeExists(newThemeName):
|
if self.checkIfThemeExists(newThemeName):
|
||||||
oldThemeData = self.getThemeData(oldThemeName)
|
oldThemeData = self.getThemeData(oldThemeName)
|
||||||
self.cloneThemeData(oldThemeData, newThemeName)
|
self.cloneThemeData(oldThemeData, newThemeName)
|
||||||
@ -333,6 +335,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self.oldBackgroundImage = theme.background_filename
|
self.oldBackgroundImage = theme.background_filename
|
||||||
self.themeForm.theme = theme
|
self.themeForm.theme = theme
|
||||||
self.themeForm.exec_(True)
|
self.themeForm.exec_(True)
|
||||||
|
self.oldBackgroundImage = None
|
||||||
|
|
||||||
def onDeleteTheme(self):
|
def onDeleteTheme(self):
|
||||||
"""
|
"""
|
||||||
@ -449,7 +452,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
# No themes have been found so create one
|
# No themes have been found so create one
|
||||||
if len(files) == 0:
|
if len(files) == 0:
|
||||||
theme = ThemeXML()
|
theme = ThemeXML()
|
||||||
theme.theme_name = UiStrings.Default
|
theme.theme_name = UiStrings().Default
|
||||||
self._writeTheme(theme, None, None)
|
self._writeTheme(theme, None, None)
|
||||||
QtCore.QSettings().setValue(
|
QtCore.QSettings().setValue(
|
||||||
self.settingsSection + u'/global theme',
|
self.settingsSection + u'/global theme',
|
||||||
@ -657,7 +660,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
|
|
||||||
def generateImage(self, themeData, forcePage=False):
|
def generateImage(self, themeData, forcePage=False):
|
||||||
"""
|
"""
|
||||||
Call the RenderManager to build a Sample Image
|
Call the renderer to build a Sample Image
|
||||||
|
|
||||||
``themeData``
|
``themeData``
|
||||||
The theme to generated a preview for.
|
The theme to generated a preview for.
|
||||||
@ -666,7 +669,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
Flag to tell message lines per page need to be generated.
|
Flag to tell message lines per page need to be generated.
|
||||||
"""
|
"""
|
||||||
log.debug(u'generateImage \n%s ', themeData)
|
log.debug(u'generateImage \n%s ', themeData)
|
||||||
return self.mainwindow.renderManager.generate_preview(
|
return self.mainwindow.renderer.generate_preview(
|
||||||
themeData, forcePage)
|
themeData, forcePage)
|
||||||
|
|
||||||
def getPreviewImage(self, theme):
|
def getPreviewImage(self, theme):
|
||||||
@ -803,4 +806,4 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
vAlignCorrection = VerticalType.Bottom
|
vAlignCorrection = VerticalType.Bottom
|
||||||
newtheme.display_horizontal_align = theme.HorizontalAlign
|
newtheme.display_horizontal_align = theme.HorizontalAlign
|
||||||
newtheme.display_vertical_align = vAlignCorrection
|
newtheme.display_vertical_align = vAlignCorrection
|
||||||
return newtheme.extract_xml()
|
return newtheme.extract_xml()
|
@ -102,7 +102,7 @@ class ThemesTab(SettingsTab):
|
|||||||
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
|
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.tabTitleVisible = UiStrings.Themes
|
self.tabTitleVisible = UiStrings().Themes
|
||||||
self.GlobalGroupBox.setTitle(
|
self.GlobalGroupBox.setTitle(
|
||||||
translate('OpenLP.ThemesTab', 'Global Theme'))
|
translate('OpenLP.ThemesTab', 'Global Theme'))
|
||||||
self.LevelGroupBox.setTitle(
|
self.LevelGroupBox.setTitle(
|
||||||
@ -149,7 +149,7 @@ class ThemesTab(SettingsTab):
|
|||||||
settings.setValue(u'global theme',
|
settings.setValue(u'global theme',
|
||||||
QtCore.QVariant(self.global_theme))
|
QtCore.QVariant(self.global_theme))
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
self.mainwindow.renderManager.set_global_theme(
|
self.mainwindow.renderer.set_global_theme(
|
||||||
self.global_theme, self.theme_level)
|
self.global_theme, self.theme_level)
|
||||||
Receiver.send_message(u'theme_update_global', self.global_theme)
|
Receiver.send_message(u'theme_update_global', self.global_theme)
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ class ThemesTab(SettingsTab):
|
|||||||
|
|
||||||
def onDefaultComboBoxChanged(self, value):
|
def onDefaultComboBoxChanged(self, value):
|
||||||
self.global_theme = unicode(self.DefaultComboBox.currentText())
|
self.global_theme = unicode(self.DefaultComboBox.currentText())
|
||||||
self.mainwindow.renderManager.set_global_theme(
|
self.mainwindow.renderer.set_global_theme(
|
||||||
self.global_theme, self.theme_level)
|
self.global_theme, self.theme_level)
|
||||||
self.__previewGlobalTheme()
|
self.__previewGlobalTheme()
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ class ThemesTab(SettingsTab):
|
|||||||
for theme in theme_list:
|
for theme in theme_list:
|
||||||
self.DefaultComboBox.addItem(theme)
|
self.DefaultComboBox.addItem(theme)
|
||||||
find_and_set_in_combo_box(self.DefaultComboBox, self.global_theme)
|
find_and_set_in_combo_box(self.DefaultComboBox, self.global_theme)
|
||||||
self.mainwindow.renderManager.set_global_theme(
|
self.mainwindow.renderer.set_global_theme(
|
||||||
self.global_theme, self.theme_level)
|
self.global_theme, self.theme_level)
|
||||||
if self.global_theme is not u'':
|
if self.global_theme is not u'':
|
||||||
self.__previewGlobalTheme()
|
self.__previewGlobalTheme()
|
||||||
|
@ -424,7 +424,7 @@ class Ui_ThemeWizard(object):
|
|||||||
self.backgroundComboBox.setItemText(BackgroundType.Gradient,
|
self.backgroundComboBox.setItemText(BackgroundType.Gradient,
|
||||||
translate('OpenLP.ThemeWizard', 'Gradient'))
|
translate('OpenLP.ThemeWizard', 'Gradient'))
|
||||||
self.backgroundComboBox.setItemText(
|
self.backgroundComboBox.setItemText(
|
||||||
BackgroundType.Image, UiStrings.Image)
|
BackgroundType.Image, UiStrings().Image)
|
||||||
self.colorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
self.colorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
||||||
self.gradientStartLabel.setText(
|
self.gradientStartLabel.setText(
|
||||||
translate(u'OpenLP.ThemeWizard', 'Starting color:'))
|
translate(u'OpenLP.ThemeWizard', 'Starting color:'))
|
||||||
@ -442,7 +442,7 @@ class Ui_ThemeWizard(object):
|
|||||||
translate('OpenLP.ThemeWizard', 'Top Left - Bottom Right'))
|
translate('OpenLP.ThemeWizard', 'Top Left - Bottom Right'))
|
||||||
self.gradientComboBox.setItemText(BackgroundGradientType.LeftBottom,
|
self.gradientComboBox.setItemText(BackgroundGradientType.LeftBottom,
|
||||||
translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
|
translate('OpenLP.ThemeWizard', 'Bottom Left - Top Right'))
|
||||||
self.imageLabel.setText(u'%s:' % UiStrings.Image)
|
self.imageLabel.setText(u'%s:' % UiStrings().Image)
|
||||||
self.mainAreaPage.setTitle(
|
self.mainAreaPage.setTitle(
|
||||||
translate('OpenLP.ThemeWizard', 'Main Area Font Details'))
|
translate('OpenLP.ThemeWizard', 'Main Area Font Details'))
|
||||||
self.mainAreaPage.setSubTitle(
|
self.mainAreaPage.setSubTitle(
|
||||||
@ -451,17 +451,17 @@ class Ui_ThemeWizard(object):
|
|||||||
self.mainFontLabel.setText(translate('OpenLP.ThemeWizard', 'Font:'))
|
self.mainFontLabel.setText(translate('OpenLP.ThemeWizard', 'Font:'))
|
||||||
self.mainColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
self.mainColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
||||||
self.mainSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
self.mainSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
||||||
self.mainSizeSpinBox.setSuffix(UiStrings.FontSizePtUnit)
|
self.mainSizeSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
||||||
self.lineSpacingLabel.setText(
|
self.lineSpacingLabel.setText(
|
||||||
translate('OpenLP.ThemeWizard', 'Line Spacing:'))
|
translate('OpenLP.ThemeWizard', 'Line Spacing:'))
|
||||||
self.lineSpacingSpinBox.setSuffix(UiStrings.FontSizePtUnit)
|
self.lineSpacingSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
||||||
self.outlineCheckBox.setText(
|
self.outlineCheckBox.setText(
|
||||||
translate('OpenLP.ThemeWizard', '&Outline:'))
|
translate('OpenLP.ThemeWizard', '&Outline:'))
|
||||||
self.outlineSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
self.outlineSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
||||||
self.outlineSizeSpinBox.setSuffix(UiStrings.FontSizePtUnit)
|
self.outlineSizeSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
||||||
self.shadowCheckBox.setText(translate('OpenLP.ThemeWizard', '&Shadow:'))
|
self.shadowCheckBox.setText(translate('OpenLP.ThemeWizard', '&Shadow:'))
|
||||||
self.shadowSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
self.shadowSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
||||||
self.shadowSizeSpinBox.setSuffix(UiStrings.FontSizePtUnit)
|
self.shadowSizeSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
||||||
self.mainBoldCheckBox.setText(translate('OpenLP.ThemeWizard', 'Bold'))
|
self.mainBoldCheckBox.setText(translate('OpenLP.ThemeWizard', 'Bold'))
|
||||||
self.mainItalicsCheckBox.setText(
|
self.mainItalicsCheckBox.setText(
|
||||||
translate('OpenLP.ThemeWizard', 'Italic'))
|
translate('OpenLP.ThemeWizard', 'Italic'))
|
||||||
@ -473,7 +473,7 @@ class Ui_ThemeWizard(object):
|
|||||||
self.footerFontLabel.setText(translate('OpenLP.ThemeWizard', 'Font:'))
|
self.footerFontLabel.setText(translate('OpenLP.ThemeWizard', 'Font:'))
|
||||||
self.footerColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
self.footerColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
||||||
self.footerSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
self.footerSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:'))
|
||||||
self.footerSizeSpinBox.setSuffix(UiStrings.FontSizePtUnit)
|
self.footerSizeSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
||||||
self.alignmentPage.setTitle(
|
self.alignmentPage.setTitle(
|
||||||
translate('OpenLP.ThemeWizard', 'Text Formatting Details'))
|
translate('OpenLP.ThemeWizard', 'Text Formatting Details'))
|
||||||
self.alignmentPage.setSubTitle(
|
self.alignmentPage.setSubTitle(
|
||||||
@ -537,4 +537,4 @@ class Ui_ThemeWizard(object):
|
|||||||
labelWidth = max(self.backgroundLabel.minimumSizeHint().width(),
|
labelWidth = max(self.backgroundLabel.minimumSizeHint().width(),
|
||||||
self.horizontalLabel.minimumSizeHint().width())
|
self.horizontalLabel.minimumSizeHint().width())
|
||||||
self.spacer.changeSize(labelWidth, 0,
|
self.spacer.changeSize(labelWidth, 0,
|
||||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
@ -95,6 +95,10 @@ class OpenLPWizard(QtGui.QWizard):
|
|||||||
self.customSignals()
|
self.customSignals()
|
||||||
QtCore.QObject.connect(self, QtCore.SIGNAL(u'currentIdChanged(int)'),
|
QtCore.QObject.connect(self, QtCore.SIGNAL(u'currentIdChanged(int)'),
|
||||||
self.onCurrentIdChanged)
|
self.onCurrentIdChanged)
|
||||||
|
QtCore.QObject.connect(self.errorCopyToButton,
|
||||||
|
QtCore.SIGNAL(u'clicked()'), self.onErrorCopyToButtonClicked)
|
||||||
|
QtCore.QObject.connect(self.errorSaveToButton,
|
||||||
|
QtCore.SIGNAL(u'clicked()'), self.onErrorSaveToButtonClicked)
|
||||||
|
|
||||||
def setupUi(self, image):
|
def setupUi(self, image):
|
||||||
"""
|
"""
|
||||||
@ -129,10 +133,36 @@ class OpenLPWizard(QtGui.QWizard):
|
|||||||
self.progressLayout.setObjectName(u'progressLayout')
|
self.progressLayout.setObjectName(u'progressLayout')
|
||||||
self.progressLabel = QtGui.QLabel(self.progressPage)
|
self.progressLabel = QtGui.QLabel(self.progressPage)
|
||||||
self.progressLabel.setObjectName(u'progressLabel')
|
self.progressLabel.setObjectName(u'progressLabel')
|
||||||
|
self.progressLabel.setWordWrap(True)
|
||||||
self.progressLayout.addWidget(self.progressLabel)
|
self.progressLayout.addWidget(self.progressLabel)
|
||||||
self.progressBar = QtGui.QProgressBar(self.progressPage)
|
self.progressBar = QtGui.QProgressBar(self.progressPage)
|
||||||
self.progressBar.setObjectName(u'progressBar')
|
self.progressBar.setObjectName(u'progressBar')
|
||||||
self.progressLayout.addWidget(self.progressBar)
|
self.progressLayout.addWidget(self.progressBar)
|
||||||
|
# Add a QTextEdit and a copy to file and copy to clipboard button to be
|
||||||
|
# able to provide feedback to the user. Hidden by default.
|
||||||
|
self.errorReportTextEdit = QtGui.QTextEdit(self.progressPage)
|
||||||
|
self.errorReportTextEdit.setObjectName(u'progresserrorReportTextEdit')
|
||||||
|
self.errorReportTextEdit.setHidden(True)
|
||||||
|
self.errorReportTextEdit.setReadOnly(True)
|
||||||
|
self.progressLayout.addWidget(self.errorReportTextEdit)
|
||||||
|
self.errorButtonLayout = QtGui.QHBoxLayout()
|
||||||
|
self.errorButtonLayout.setObjectName(u'errorButtonLayout')
|
||||||
|
spacer = QtGui.QSpacerItem(40, 20,
|
||||||
|
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||||
|
self.errorButtonLayout.addItem(spacer)
|
||||||
|
self.errorCopyToButton = QtGui.QPushButton(self.progressPage)
|
||||||
|
self.errorCopyToButton.setObjectName(u'errorCopyToButton')
|
||||||
|
self.errorCopyToButton.setHidden(True)
|
||||||
|
self.errorCopyToButton.setIcon(
|
||||||
|
build_icon(u':/system/system_edit_copy.png'))
|
||||||
|
self.errorButtonLayout.addWidget(self.errorCopyToButton)
|
||||||
|
self.errorSaveToButton = QtGui.QPushButton(self.progressPage)
|
||||||
|
self.errorSaveToButton.setObjectName(u'errorSaveToButton')
|
||||||
|
self.errorSaveToButton.setHidden(True)
|
||||||
|
self.errorSaveToButton.setIcon(
|
||||||
|
build_icon(u':/general/general_save.png'))
|
||||||
|
self.errorButtonLayout.addWidget(self.errorSaveToButton)
|
||||||
|
self.progressLayout.addLayout(self.errorButtonLayout)
|
||||||
self.addPage(self.progressPage)
|
self.addPage(self.progressPage)
|
||||||
|
|
||||||
def exec_(self):
|
def exec_(self):
|
||||||
@ -160,6 +190,18 @@ class OpenLPWizard(QtGui.QWizard):
|
|||||||
self.performWizard()
|
self.performWizard()
|
||||||
self.postWizard()
|
self.postWizard()
|
||||||
|
|
||||||
|
def onErrorCopyToButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Called when the ``onErrorCopyToButtonClicked`` has been clicked.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def onErrorSaveToButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Called when the ``onErrorSaveToButtonClicked`` has been clicked.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
def incrementProgressBar(self, status_text, increment=1):
|
def incrementProgressBar(self, status_text, increment=1):
|
||||||
"""
|
"""
|
||||||
Update the wizard progress page.
|
Update the wizard progress page.
|
||||||
@ -212,7 +254,7 @@ class OpenLPWizard(QtGui.QWizard):
|
|||||||
"""
|
"""
|
||||||
if filters:
|
if filters:
|
||||||
filters += u';;'
|
filters += u';;'
|
||||||
filters += u'%s (*)' % UiStrings.AllFiles
|
filters += u'%s (*)' % UiStrings().AllFiles
|
||||||
filename = QtGui.QFileDialog.getOpenFileName(self, title,
|
filename = QtGui.QFileDialog.getOpenFileName(self, title,
|
||||||
os.path.dirname(SettingsManager.get_last_dir(
|
os.path.dirname(SettingsManager.get_last_dir(
|
||||||
self.plugin.settingsSection, 1)), filters)
|
self.plugin.settingsSection, 1)), filters)
|
||||||
@ -220,3 +262,4 @@ class OpenLPWizard(QtGui.QWizard):
|
|||||||
editbox.setText(filename)
|
editbox.setText(filename)
|
||||||
SettingsManager.set_last_dir(self.plugin.settingsSection,
|
SettingsManager.set_last_dir(self.plugin.settingsSection,
|
||||||
filename, 1)
|
filename, 1)
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ class AlertsPlugin(Plugin):
|
|||||||
Plugin.initialise(self)
|
Plugin.initialise(self)
|
||||||
self.toolsAlertItem.setVisible(True)
|
self.toolsAlertItem.setVisible(True)
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_action(self.toolsAlertItem, UiStrings.Tools)
|
action_list.add_action(self.toolsAlertItem, UiStrings().Tools)
|
||||||
self.liveController.alertTab = self.settings_tab
|
self.liveController.alertTab = self.settings_tab
|
||||||
|
|
||||||
def finalise(self):
|
def finalise(self):
|
||||||
@ -118,4 +118,4 @@ class AlertsPlugin(Plugin):
|
|||||||
## Name for MediaDockManager, SettingsManager ##
|
## Name for MediaDockManager, SettingsManager ##
|
||||||
self.textStrings[StringContent.VisibleName] = {
|
self.textStrings[StringContent.VisibleName] = {
|
||||||
u'title': translate('AlertsPlugin', 'Alerts', 'container title')
|
u'title': translate('AlertsPlugin', 'Alerts', 'container title')
|
||||||
}
|
}
|
@ -61,6 +61,12 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
|||||||
QtCore.QObject.connect(self.alertListWidget,
|
QtCore.QObject.connect(self.alertListWidget,
|
||||||
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
|
QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged)
|
||||||
|
|
||||||
|
def exec_(self):
|
||||||
|
self.displayButton.setEnabled(False)
|
||||||
|
self.displayCloseButton.setEnabled(False)
|
||||||
|
self.alertTextEdit.setText(u'')
|
||||||
|
return QtGui.QDialog.exec_(self)
|
||||||
|
|
||||||
def loadList(self):
|
def loadList(self):
|
||||||
"""
|
"""
|
||||||
Loads the list with alerts.
|
Loads the list with alerts.
|
||||||
@ -125,6 +131,12 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
|||||||
# Only enable the button, if we are editing an item.
|
# Only enable the button, if we are editing an item.
|
||||||
if self.item_id:
|
if self.item_id:
|
||||||
self.saveButton.setEnabled(True)
|
self.saveButton.setEnabled(True)
|
||||||
|
if self.alertTextEdit.text():
|
||||||
|
self.displayButton.setEnabled(True)
|
||||||
|
self.displayCloseButton.setEnabled(True)
|
||||||
|
else:
|
||||||
|
self.displayButton.setEnabled(False)
|
||||||
|
self.displayCloseButton.setEnabled(False)
|
||||||
|
|
||||||
def onDoubleClick(self):
|
def onDoubleClick(self):
|
||||||
"""
|
"""
|
||||||
|
@ -109,12 +109,12 @@ class AlertsTab(SettingsTab):
|
|||||||
translate('AlertsPlugin.AlertsTab', 'Background color:'))
|
translate('AlertsPlugin.AlertsTab', 'Background color:'))
|
||||||
self.FontSizeLabel.setText(
|
self.FontSizeLabel.setText(
|
||||||
translate('AlertsPlugin.AlertsTab', 'Font size:'))
|
translate('AlertsPlugin.AlertsTab', 'Font size:'))
|
||||||
self.FontSizeSpinBox.setSuffix(UiStrings.FontSizePtUnit)
|
self.FontSizeSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
||||||
self.TimeoutLabel.setText(
|
self.TimeoutLabel.setText(
|
||||||
translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
|
translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
|
||||||
self.TimeoutSpinBox.setSuffix(UiStrings.Seconds)
|
self.TimeoutSpinBox.setSuffix(UiStrings().Seconds)
|
||||||
self.PreviewGroupBox.setTitle(UiStrings.Preview)
|
self.PreviewGroupBox.setTitle(UiStrings().Preview)
|
||||||
self.FontPreview.setText(UiStrings.OLPV2)
|
self.FontPreview.setText(UiStrings().OLPV2)
|
||||||
|
|
||||||
def onBackgroundColorButtonClicked(self):
|
def onBackgroundColorButtonClicked(self):
|
||||||
new_color = QtGui.QColorDialog.getColor(
|
new_color = QtGui.QColorDialog.getColor(
|
||||||
@ -191,4 +191,4 @@ class AlertsTab(SettingsTab):
|
|||||||
font.setPointSize(self.font_size)
|
font.setPointSize(self.font_size)
|
||||||
self.FontPreview.setFont(font)
|
self.FontPreview.setFont(font)
|
||||||
self.FontPreview.setStyleSheet(u'background-color: %s; color: %s' %
|
self.FontPreview.setStyleSheet(u'background-color: %s; color: %s' %
|
||||||
(self.bg_color, self.font_color))
|
(self.bg_color, self.font_color))
|
@ -53,9 +53,9 @@ class BiblePlugin(Plugin):
|
|||||||
Plugin.initialise(self)
|
Plugin.initialise(self)
|
||||||
self.importBibleItem.setVisible(True)
|
self.importBibleItem.setVisible(True)
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_action(self.importBibleItem, UiStrings.Import)
|
action_list.add_action(self.importBibleItem, UiStrings().Import)
|
||||||
# Do not add the action to the list yet.
|
# Do not add the action to the list yet.
|
||||||
#action_list.add_action(self.exportBibleItem, UiStrings.Export)
|
#action_list.add_action(self.exportBibleItem, UiStrings().Export)
|
||||||
# Set to invisible until we can export bibles
|
# Set to invisible until we can export bibles
|
||||||
self.exportBibleItem.setVisible(False)
|
self.exportBibleItem.setVisible(False)
|
||||||
|
|
||||||
@ -67,9 +67,9 @@ class BiblePlugin(Plugin):
|
|||||||
self.manager.finalise()
|
self.manager.finalise()
|
||||||
Plugin.finalise(self)
|
Plugin.finalise(self)
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.remove_action(self.importBibleItem, UiStrings.Import)
|
action_list.remove_action(self.importBibleItem, UiStrings().Import)
|
||||||
self.importBibleItem.setVisible(False)
|
self.importBibleItem.setVisible(False)
|
||||||
#action_list.remove_action(self.exportBibleItem, UiStrings.Export)
|
#action_list.remove_action(self.exportBibleItem, UiStrings().Export)
|
||||||
self.exportBibleItem.setVisible(False)
|
self.exportBibleItem.setVisible(False)
|
||||||
|
|
||||||
def addImportMenuItem(self, import_menu):
|
def addImportMenuItem(self, import_menu):
|
||||||
@ -146,4 +146,4 @@ class BiblePlugin(Plugin):
|
|||||||
u'service': translate('BiblesPlugin',
|
u'service': translate('BiblesPlugin',
|
||||||
'Add the selected Bible to the service')
|
'Add the selected Bible to the service')
|
||||||
}
|
}
|
||||||
self.setPluginUiTextStrings(tooltips)
|
self.setPluginUiTextStrings(tooltips)
|
@ -377,7 +377,7 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
self.formatComboBox.setItemText(BibleFormat.OpenSong, WizardStrings.OS)
|
self.formatComboBox.setItemText(BibleFormat.OpenSong, WizardStrings.OS)
|
||||||
self.formatComboBox.setItemText(BibleFormat.WebDownload,
|
self.formatComboBox.setItemText(BibleFormat.WebDownload,
|
||||||
translate('BiblesPlugin.ImportWizardForm', 'Web Download'))
|
translate('BiblesPlugin.ImportWizardForm', 'Web Download'))
|
||||||
self.formatComboBox.setItemText(BibleFormat.OpenLP1, UiStrings.OLPV1)
|
self.formatComboBox.setItemText(BibleFormat.OpenLP1, UiStrings().OLPV1)
|
||||||
self.openlp1FileLabel.setText(
|
self.openlp1FileLabel.setText(
|
||||||
translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
|
||||||
self.osisFileLabel.setText(
|
self.osisFileLabel.setText(
|
||||||
@ -451,13 +451,13 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
elif self.currentPage() == self.selectPage:
|
elif self.currentPage() == self.selectPage:
|
||||||
if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS:
|
if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS:
|
||||||
if not self.field(u'osis_location').toString():
|
if not self.field(u'osis_location').toString():
|
||||||
critical_error_message_box(UiStrings.NFSs,
|
critical_error_message_box(UiStrings().NFSs,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.OSIS)
|
WizardStrings.YouSpecifyFile % WizardStrings.OSIS)
|
||||||
self.osisFileEdit.setFocus()
|
self.osisFileEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
|
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
|
||||||
if not self.field(u'csv_testamentsfile').toString():
|
if not self.field(u'csv_testamentsfile').toString():
|
||||||
answer = critical_error_message_box(UiStrings.NFSs,
|
answer = critical_error_message_box(UiStrings().NFSs,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'You have not specified a testaments file. Do you '
|
'You have not specified a testaments file. Do you '
|
||||||
'want to proceed with the import?'), question=True)
|
'want to proceed with the import?'), question=True)
|
||||||
@ -465,14 +465,14 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
self.csvTestamentsEdit.setFocus()
|
self.csvTestamentsEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
if not self.field(u'csv_booksfile').toString():
|
if not self.field(u'csv_booksfile').toString():
|
||||||
critical_error_message_box(UiStrings.NFSs,
|
critical_error_message_box(UiStrings().NFSs,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'You need to specify a file with books of '
|
'You need to specify a file with books of '
|
||||||
'the Bible to use in the import.'))
|
'the Bible to use in the import.'))
|
||||||
self.csvBooksEdit.setFocus()
|
self.csvBooksEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif not self.field(u'csv_versefile').toString():
|
elif not self.field(u'csv_versefile').toString():
|
||||||
critical_error_message_box(UiStrings.NFSs,
|
critical_error_message_box(UiStrings().NFSs,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'You need to specify a file of Bible '
|
'You need to specify a file of Bible '
|
||||||
'verses to import.'))
|
'verses to import.'))
|
||||||
@ -481,14 +481,14 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
elif self.field(u'source_format').toInt()[0] == \
|
elif self.field(u'source_format').toInt()[0] == \
|
||||||
BibleFormat.OpenSong:
|
BibleFormat.OpenSong:
|
||||||
if not self.field(u'opensong_file').toString():
|
if not self.field(u'opensong_file').toString():
|
||||||
critical_error_message_box(UiStrings.NFSs,
|
critical_error_message_box(UiStrings().NFSs,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.OS)
|
WizardStrings.YouSpecifyFile % WizardStrings.OS)
|
||||||
self.openSongFileEdit.setFocus()
|
self.openSongFileEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1:
|
elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1:
|
||||||
if not self.field(u'openlp1_location').toString():
|
if not self.field(u'openlp1_location').toString():
|
||||||
critical_error_message_box(UiStrings.NFSs,
|
critical_error_message_box(UiStrings().NFSs,
|
||||||
WizardStrings.YouSpecifyFile % UiStrings.OLPV1)
|
WizardStrings.YouSpecifyFile % UiStrings().OLPV1)
|
||||||
self.openlp1FileEdit.setFocus()
|
self.openlp1FileEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
@ -497,13 +497,13 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
license_copyright = \
|
license_copyright = \
|
||||||
unicode(self.field(u'license_copyright').toString())
|
unicode(self.field(u'license_copyright').toString())
|
||||||
if not license_version:
|
if not license_version:
|
||||||
critical_error_message_box(UiStrings.EmptyField,
|
critical_error_message_box(UiStrings().EmptyField,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'You need to specify a version name for your Bible.'))
|
'You need to specify a version name for your Bible.'))
|
||||||
self.versionNameEdit.setFocus()
|
self.versionNameEdit.setFocus()
|
||||||
return False
|
return False
|
||||||
elif not license_copyright:
|
elif not license_copyright:
|
||||||
critical_error_message_box(UiStrings.EmptyField,
|
critical_error_message_box(UiStrings().EmptyField,
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'You need to set a copyright for your Bible. '
|
'You need to set a copyright for your Bible. '
|
||||||
'Bibles in the Public Domain need to be marked as such.'))
|
'Bibles in the Public Domain need to be marked as such.'))
|
||||||
@ -576,7 +576,7 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
"""
|
"""
|
||||||
Show the file open dialog for the openlp.org 1.x file.
|
Show the file open dialog for the openlp.org 1.x file.
|
||||||
"""
|
"""
|
||||||
self.getFileName(WizardStrings.OpenTypeFile % UiStrings.OLPV1,
|
self.getFileName(WizardStrings.OpenTypeFile % UiStrings().OLPV1,
|
||||||
self.openlp1FileEdit, u'%s (*.bible)' %
|
self.openlp1FileEdit, u'%s (*.bible)' %
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'openlp.org 1.x Bible Files'))
|
'openlp.org 1.x Bible Files'))
|
||||||
@ -765,4 +765,4 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
self.progressLabel.setText(translate(
|
self.progressLabel.setText(translate(
|
||||||
'BiblesPlugin.ImportWizardForm', 'Your Bible import failed.'))
|
'BiblesPlugin.ImportWizardForm', 'Your Bible import failed.'))
|
||||||
del self.manager.db_cache[importer.name]
|
del self.manager.db_cache[importer.name]
|
||||||
delete_database(self.plugin.settingsSection, importer.file)
|
delete_database(self.plugin.settingsSection, importer.file)
|
@ -118,16 +118,16 @@ class BiblesTab(SettingsTab):
|
|||||||
self.newChaptersCheckBox.setText(
|
self.newChaptersCheckBox.setText(
|
||||||
translate('BiblesPlugin.BiblesTab',
|
translate('BiblesPlugin.BiblesTab',
|
||||||
'Only show new chapter numbers'))
|
'Only show new chapter numbers'))
|
||||||
self.layoutStyleLabel.setText(UiStrings.LayoutStyle)
|
self.layoutStyleLabel.setText(UiStrings().LayoutStyle)
|
||||||
self.displayStyleLabel.setText(UiStrings.DisplayStyle)
|
self.displayStyleLabel.setText(UiStrings().DisplayStyle)
|
||||||
self.bibleThemeLabel.setText(
|
self.bibleThemeLabel.setText(
|
||||||
translate('BiblesPlugin.BiblesTab', 'Bible theme:'))
|
translate('BiblesPlugin.BiblesTab', 'Bible theme:'))
|
||||||
self.layoutStyleComboBox.setItemText(LayoutStyle.VersePerSlide,
|
self.layoutStyleComboBox.setItemText(LayoutStyle.VersePerSlide,
|
||||||
UiStrings.VersePerSlide)
|
UiStrings().VersePerSlide)
|
||||||
self.layoutStyleComboBox.setItemText(LayoutStyle.VersePerLine,
|
self.layoutStyleComboBox.setItemText(LayoutStyle.VersePerLine,
|
||||||
UiStrings.VersePerLine)
|
UiStrings().VersePerLine)
|
||||||
self.layoutStyleComboBox.setItemText(LayoutStyle.Continuous,
|
self.layoutStyleComboBox.setItemText(LayoutStyle.Continuous,
|
||||||
UiStrings.Continuous)
|
UiStrings().Continuous)
|
||||||
self.displayStyleComboBox.setItemText(DisplayStyle.NoBrackets,
|
self.displayStyleComboBox.setItemText(DisplayStyle.NoBrackets,
|
||||||
translate('BiblesPlugin.BiblesTab', 'No Brackets'))
|
translate('BiblesPlugin.BiblesTab', 'No Brackets'))
|
||||||
self.displayStyleComboBox.setItemText(DisplayStyle.Round,
|
self.displayStyleComboBox.setItemText(DisplayStyle.Round,
|
||||||
@ -207,4 +207,4 @@ class BiblesTab(SettingsTab):
|
|||||||
self.bibleThemeComboBox.addItem(u'')
|
self.bibleThemeComboBox.addItem(u'')
|
||||||
for theme in theme_list:
|
for theme in theme_list:
|
||||||
self.bibleThemeComboBox.addItem(theme)
|
self.bibleThemeComboBox.addItem(theme)
|
||||||
find_and_set_in_combo_box(self.bibleThemeComboBox, self.bible_theme)
|
find_and_set_in_combo_box(self.bibleThemeComboBox, self.bible_theme)
|
@ -193,7 +193,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
self.advancedSearchButtonLayout.addWidget(self.advancedSearchButton)
|
self.advancedSearchButtonLayout.addWidget(self.advancedSearchButton)
|
||||||
self.advancedLayout.addLayout(
|
self.advancedLayout.addLayout(
|
||||||
self.advancedSearchButtonLayout, 7, 0, 1, 3)
|
self.advancedSearchButtonLayout, 7, 0, 1, 3)
|
||||||
self.searchTabWidget.addTab(self.advancedTab, UiStrings.Advanced)
|
self.searchTabWidget.addTab(self.advancedTab, UiStrings().Advanced)
|
||||||
# Add the search tab widget to the page layout.
|
# Add the search tab widget to the page layout.
|
||||||
self.pageLayout.addWidget(self.searchTabWidget)
|
self.pageLayout.addWidget(self.searchTabWidget)
|
||||||
# Combo Boxes
|
# Combo Boxes
|
||||||
@ -242,15 +242,15 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
log.debug(u'retranslateUi')
|
log.debug(u'retranslateUi')
|
||||||
self.quickVersionLabel.setText(u'%s:' % UiStrings.Version)
|
self.quickVersionLabel.setText(u'%s:' % UiStrings().Version)
|
||||||
self.quickSecondLabel.setText(
|
self.quickSecondLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Second:'))
|
translate('BiblesPlugin.MediaItem', 'Second:'))
|
||||||
self.quickSearchLabel.setText(
|
self.quickSearchLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Find:'))
|
translate('BiblesPlugin.MediaItem', 'Find:'))
|
||||||
self.quickSearchButton.setText(UiStrings.Search)
|
self.quickSearchButton.setText(UiStrings().Search)
|
||||||
self.quickClearLabel.setText(
|
self.quickClearLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Results:'))
|
translate('BiblesPlugin.MediaItem', 'Results:'))
|
||||||
self.advancedVersionLabel.setText(u'%s:' % UiStrings.Version)
|
self.advancedVersionLabel.setText(u'%s:' % UiStrings().Version)
|
||||||
self.advancedSecondLabel.setText(
|
self.advancedSecondLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Second:'))
|
translate('BiblesPlugin.MediaItem', 'Second:'))
|
||||||
self.advancedBookLabel.setText(
|
self.advancedBookLabel.setText(
|
||||||
@ -265,7 +265,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
translate('BiblesPlugin.MediaItem', 'To:'))
|
translate('BiblesPlugin.MediaItem', 'To:'))
|
||||||
self.advancedClearLabel.setText(
|
self.advancedClearLabel.setText(
|
||||||
translate('BiblesPlugin.MediaItem', 'Results:'))
|
translate('BiblesPlugin.MediaItem', 'Results:'))
|
||||||
self.advancedSearchButton.setText(UiStrings.Search)
|
self.advancedSearchButton.setText(UiStrings().Search)
|
||||||
self.quickClearComboBox.addItem(
|
self.quickClearComboBox.addItem(
|
||||||
translate('BiblesPlugin.MediaItem', 'Clear'))
|
translate('BiblesPlugin.MediaItem', 'Clear'))
|
||||||
self.quickClearComboBox.addItem(
|
self.quickClearComboBox.addItem(
|
||||||
@ -274,13 +274,13 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
translate('BiblesPlugin.MediaItem', 'Clear'))
|
translate('BiblesPlugin.MediaItem', 'Clear'))
|
||||||
self.advancedClearComboBox.addItem(
|
self.advancedClearComboBox.addItem(
|
||||||
translate('BiblesPlugin.MediaItem', 'Keep'))
|
translate('BiblesPlugin.MediaItem', 'Keep'))
|
||||||
self.quickLayoutLabel.setText(UiStrings.LayoutStyle)
|
self.quickLayoutLabel.setText(UiStrings().LayoutStyle)
|
||||||
self.quickLayoutComboBox.setItemText(LayoutStyle.VersePerSlide,
|
self.quickLayoutComboBox.setItemText(LayoutStyle.VersePerSlide,
|
||||||
UiStrings.VersePerSlide)
|
UiStrings().VersePerSlide)
|
||||||
self.quickLayoutComboBox.setItemText(LayoutStyle.VersePerLine,
|
self.quickLayoutComboBox.setItemText(LayoutStyle.VersePerLine,
|
||||||
UiStrings.VersePerLine)
|
UiStrings().VersePerLine)
|
||||||
self.quickLayoutComboBox.setItemText(LayoutStyle.Continuous,
|
self.quickLayoutComboBox.setItemText(LayoutStyle.Continuous,
|
||||||
UiStrings.Continuous)
|
UiStrings().Continuous)
|
||||||
|
|
||||||
def initialise(self):
|
def initialise(self):
|
||||||
log.debug(u'bible manager initialise')
|
log.debug(u'bible manager initialise')
|
||||||
@ -723,6 +723,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
service_item.add_capability(ItemCapabilities.NoLineBreaks)
|
service_item.add_capability(ItemCapabilities.NoLineBreaks)
|
||||||
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
||||||
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
||||||
|
service_item.add_capability(ItemCapabilities.AllowsWordSplit)
|
||||||
# Service Item: Title
|
# Service Item: Title
|
||||||
service_item.title = u', '.join(raw_title)
|
service_item.title = u', '.join(raw_title)
|
||||||
# Service Item: Theme
|
# Service Item: Theme
|
||||||
|
@ -37,6 +37,9 @@ from openlp.plugins.bibles.lib.db import BibleDB
|
|||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def replacement(match):
|
||||||
|
return match.group(2).upper()
|
||||||
|
|
||||||
class OSISBible(BibleDB):
|
class OSISBible(BibleDB):
|
||||||
"""
|
"""
|
||||||
`OSIS <http://www.bibletechnologies.net/>`_ Bible format importer class.
|
`OSIS <http://www.bibletechnologies.net/>`_ Bible format importer class.
|
||||||
@ -60,6 +63,7 @@ class OSISBible(BibleDB):
|
|||||||
self.lg_regex = re.compile(r'<lg(.*?)>')
|
self.lg_regex = re.compile(r'<lg(.*?)>')
|
||||||
self.l_regex = re.compile(r'<l (.*?)>')
|
self.l_regex = re.compile(r'<l (.*?)>')
|
||||||
self.w_regex = re.compile(r'<w (.*?)>')
|
self.w_regex = re.compile(r'<w (.*?)>')
|
||||||
|
self.q_regex = re.compile(r'<q(.*?)>')
|
||||||
self.q1_regex = re.compile(r'<q(.*?)level="1"(.*?)>')
|
self.q1_regex = re.compile(r'<q(.*?)level="1"(.*?)>')
|
||||||
self.q2_regex = re.compile(r'<q(.*?)level="2"(.*?)>')
|
self.q2_regex = re.compile(r'<q(.*?)level="2"(.*?)>')
|
||||||
self.trans_regex = re.compile(r'<transChange(.*?)>(.*?)</transChange>')
|
self.trans_regex = re.compile(r'<transChange(.*?)>(.*?)</transChange>')
|
||||||
@ -106,6 +110,7 @@ class OSISBible(BibleDB):
|
|||||||
detect_file.close()
|
detect_file.close()
|
||||||
try:
|
try:
|
||||||
osis = codecs.open(self.filename, u'r', details['encoding'])
|
osis = codecs.open(self.filename, u'r', details['encoding'])
|
||||||
|
repl = replacement
|
||||||
for file_record in osis:
|
for file_record in osis:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
break
|
break
|
||||||
@ -148,12 +153,13 @@ class OSISBible(BibleDB):
|
|||||||
verse_text = self.rf_regex.sub(u'', verse_text)
|
verse_text = self.rf_regex.sub(u'', verse_text)
|
||||||
verse_text = self.lb_regex.sub(u' ', verse_text)
|
verse_text = self.lb_regex.sub(u' ', verse_text)
|
||||||
verse_text = self.lg_regex.sub(u'', verse_text)
|
verse_text = self.lg_regex.sub(u'', verse_text)
|
||||||
verse_text = self.l_regex.sub(u'', verse_text)
|
verse_text = self.l_regex.sub(u' ', verse_text)
|
||||||
verse_text = self.w_regex.sub(u'', verse_text)
|
verse_text = self.w_regex.sub(u'', verse_text)
|
||||||
verse_text = self.q1_regex.sub(u'"', verse_text)
|
verse_text = self.q1_regex.sub(u'"', verse_text)
|
||||||
verse_text = self.q2_regex.sub(u'\'', verse_text)
|
verse_text = self.q2_regex.sub(u'\'', verse_text)
|
||||||
|
verse_text = self.q_regex.sub(u'', verse_text)
|
||||||
|
verse_text = self.divine_name_regex.sub(repl, verse_text)
|
||||||
verse_text = self.trans_regex.sub(u'', verse_text)
|
verse_text = self.trans_regex.sub(u'', verse_text)
|
||||||
verse_text = self.divine_name_regex.sub(u'', verse_text)
|
|
||||||
verse_text = verse_text.replace(u'</lb>', u'')\
|
verse_text = verse_text.replace(u'</lb>', u'')\
|
||||||
.replace(u'</l>', u'').replace(u'<lg>', u'')\
|
.replace(u'</l>', u'').replace(u'<lg>', u'')\
|
||||||
.replace(u'</lg>', u'').replace(u'</q>', u'')\
|
.replace(u'</lg>', u'').replace(u'</q>', u'')\
|
||||||
|
@ -107,11 +107,11 @@ class Ui_CustomEditDialog(object):
|
|||||||
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
|
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
|
||||||
self.titleLabel.setText(
|
self.titleLabel.setText(
|
||||||
translate('CustomPlugin.EditCustomForm', '&Title:'))
|
translate('CustomPlugin.EditCustomForm', '&Title:'))
|
||||||
self.addButton.setText(UiStrings.Add)
|
self.addButton.setText(UiStrings().Add)
|
||||||
self.addButton.setToolTip(
|
self.addButton.setToolTip(
|
||||||
translate('CustomPlugin.EditCustomForm', 'Add a new slide at '
|
translate('CustomPlugin.EditCustomForm', 'Add a new slide at '
|
||||||
'bottom.'))
|
'bottom.'))
|
||||||
self.editButton.setText(UiStrings.Edit)
|
self.editButton.setText(UiStrings().Edit)
|
||||||
self.editButton.setToolTip(
|
self.editButton.setToolTip(
|
||||||
translate('CustomPlugin.EditCustomForm', 'Edit the selected '
|
translate('CustomPlugin.EditCustomForm', 'Edit the selected '
|
||||||
'slide.'))
|
'slide.'))
|
||||||
@ -124,4 +124,4 @@ class Ui_CustomEditDialog(object):
|
|||||||
translate('CustomPlugin.EditCustomForm', 'The&me:'))
|
translate('CustomPlugin.EditCustomForm', 'The&me:'))
|
||||||
self.creditLabel.setText(
|
self.creditLabel.setText(
|
||||||
translate('CustomPlugin.EditCustomForm', '&Credits:'))
|
translate('CustomPlugin.EditCustomForm', '&Credits:'))
|
||||||
self.previewButton.setText(UiStrings.SaveAndPreview)
|
self.previewButton.setText(UiStrings().SaveAndPreview)
|
@ -169,7 +169,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
|||||||
item = self.slideListView.item(row)
|
item = self.slideListView.item(row)
|
||||||
slide_list += item.text()
|
slide_list += item.text()
|
||||||
if row != self.slideListView.count() - 1:
|
if row != self.slideListView.count() - 1:
|
||||||
slide_list += u'\n[---]\n'
|
slide_list += u'\n[===]\n'
|
||||||
self.editSlideForm.setText(slide_list)
|
self.editSlideForm.setText(slide_list)
|
||||||
if self.editSlideForm.exec_():
|
if self.editSlideForm.exec_():
|
||||||
self.updateSlideList(self.editSlideForm.getText(), True)
|
self.updateSlideList(self.editSlideForm.getText(), True)
|
||||||
|
@ -63,7 +63,7 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
|
|||||||
"""
|
"""
|
||||||
Returns a list with all slides.
|
Returns a list with all slides.
|
||||||
"""
|
"""
|
||||||
return self.slideTextEdit.toPlainText().split(u'\n[---]\n')
|
return self.slideTextEdit.toPlainText().split(u'\n[===]\n')
|
||||||
|
|
||||||
def onSplitButtonPressed(self):
|
def onSplitButtonPressed(self):
|
||||||
"""
|
"""
|
||||||
@ -71,5 +71,5 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
|
|||||||
"""
|
"""
|
||||||
if self.slideTextEdit.textCursor().columnNumber() != 0:
|
if self.slideTextEdit.textCursor().columnNumber() != 0:
|
||||||
self.slideTextEdit.insertPlainText(u'\n')
|
self.slideTextEdit.insertPlainText(u'\n')
|
||||||
self.slideTextEdit.insertPlainText(u'[---]\n')
|
self.slideTextEdit.insertPlainText(u'[===]\n')
|
||||||
self.slideTextEdit.setFocus()
|
self.slideTextEdit.setFocus()
|
||||||
|
@ -110,7 +110,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
"""
|
"""
|
||||||
Edit a custom item
|
Edit a custom item
|
||||||
"""
|
"""
|
||||||
if check_item_selected(self.listView, UiStrings.SelectEdit):
|
if check_item_selected(self.listView, UiStrings().SelectEdit):
|
||||||
item = self.listView.currentItem()
|
item = self.listView.currentItem()
|
||||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||||
self.parent.edit_custom_form.loadCustom(item_id, False)
|
self.parent.edit_custom_form.loadCustom(item_id, False)
|
||||||
@ -121,7 +121,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
"""
|
"""
|
||||||
Remove a custom item from the list and database
|
Remove a custom item from the list and database
|
||||||
"""
|
"""
|
||||||
if check_item_selected(self.listView, UiStrings.SelectDelete):
|
if check_item_selected(self.listView, UiStrings().SelectDelete):
|
||||||
row_list = [item.row() for item in self.listView.selectedIndexes()]
|
row_list = [item.row() for item in self.listView.selectedIndexes()]
|
||||||
row_list.sort(reverse=True)
|
row_list.sort(reverse=True)
|
||||||
id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0]
|
id_list = [(item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||||
@ -140,6 +140,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
service_item.add_capability(ItemCapabilities.AllowsEdit)
|
service_item.add_capability(ItemCapabilities.AllowsEdit)
|
||||||
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
service_item.add_capability(ItemCapabilities.AllowsPreview)
|
||||||
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
||||||
|
service_item.add_capability(ItemCapabilities.AllowsVirtualSplit)
|
||||||
customSlide = self.parent.manager.get_object(CustomSlide, item_id)
|
customSlide = self.parent.manager.get_object(CustomSlide, item_id)
|
||||||
title = customSlide.title
|
title = customSlide.title
|
||||||
credit = customSlide.credits
|
credit = customSlide.credits
|
||||||
@ -160,4 +161,4 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
else:
|
else:
|
||||||
raw_footer.append(u'')
|
raw_footer.append(u'')
|
||||||
service_item.raw_footer = raw_footer
|
service_item.raw_footer = raw_footer
|
||||||
return True
|
return True
|
@ -55,11 +55,11 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
'Select Image(s)')
|
'Select Image(s)')
|
||||||
file_formats = get_images_filter()
|
file_formats = get_images_filter()
|
||||||
self.onNewFileMasks = u'%s;;%s (*.*) (*)' % (file_formats,
|
self.onNewFileMasks = u'%s;;%s (*.*) (*)' % (file_formats,
|
||||||
UiStrings.AllFiles)
|
UiStrings().AllFiles)
|
||||||
self.replaceAction.setText(UiStrings.ReplaceBG)
|
self.replaceAction.setText(UiStrings().ReplaceBG)
|
||||||
self.replaceAction.setToolTip(UiStrings.ReplaceLiveBG)
|
self.replaceAction.setToolTip(UiStrings().ReplaceLiveBG)
|
||||||
self.resetAction.setText(UiStrings.ResetBG)
|
self.resetAction.setText(UiStrings().ResetBG)
|
||||||
self.resetAction.setToolTip(UiStrings.ResetLiveBG)
|
self.resetAction.setToolTip(UiStrings().ResetLiveBG)
|
||||||
|
|
||||||
def requiredIcons(self):
|
def requiredIcons(self):
|
||||||
MediaManagerItem.requiredIcons(self)
|
MediaManagerItem.requiredIcons(self)
|
||||||
@ -198,7 +198,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
self.parent.liveController.display.directImage(name, filename)
|
self.parent.liveController.display.directImage(name, filename)
|
||||||
self.resetAction.setVisible(True)
|
self.resetAction.setVisible(True)
|
||||||
else:
|
else:
|
||||||
critical_error_message_box(UiStrings.LiveBGError,
|
critical_error_message_box(UiStrings().LiveBGError,
|
||||||
unicode(translate('ImagePlugin.MediaItem',
|
unicode(translate('ImagePlugin.MediaItem',
|
||||||
'There was a problem replacing your background, '
|
'There was a problem replacing your background, '
|
||||||
'the image file "%s" no longer exists.')) % filename)
|
'the image file "%s" no longer exists.')) % filename)
|
@ -60,11 +60,11 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
self.onNewFileMasks = unicode(translate('MediaPlugin.MediaItem',
|
self.onNewFileMasks = unicode(translate('MediaPlugin.MediaItem',
|
||||||
'Videos (%s);;Audio (%s);;%s (*)')) % (
|
'Videos (%s);;Audio (%s);;%s (*)')) % (
|
||||||
u' '.join(self.parent.video_extensions_list),
|
u' '.join(self.parent.video_extensions_list),
|
||||||
u' '.join(self.parent.audio_extensions_list), UiStrings.AllFiles)
|
u' '.join(self.parent.audio_extensions_list), UiStrings().AllFiles)
|
||||||
self.replaceAction.setText(UiStrings.ReplaceBG)
|
self.replaceAction.setText(UiStrings().ReplaceBG)
|
||||||
self.replaceAction.setToolTip(UiStrings.ReplaceLiveBG)
|
self.replaceAction.setToolTip(UiStrings().ReplaceLiveBG)
|
||||||
self.resetAction.setText(UiStrings.ResetBG)
|
self.resetAction.setText(UiStrings().ResetBG)
|
||||||
self.resetAction.setToolTip(UiStrings.ResetLiveBG)
|
self.resetAction.setToolTip(UiStrings().ResetLiveBG)
|
||||||
|
|
||||||
def requiredIcons(self):
|
def requiredIcons(self):
|
||||||
MediaManagerItem.requiredIcons(self)
|
MediaManagerItem.requiredIcons(self)
|
||||||
@ -111,7 +111,7 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
self.parent.liveController.display.video(filename, 0, True)
|
self.parent.liveController.display.video(filename, 0, True)
|
||||||
self.resetAction.setVisible(True)
|
self.resetAction.setVisible(True)
|
||||||
else:
|
else:
|
||||||
critical_error_message_box(UiStrings.LiveBGError,
|
critical_error_message_box(UiStrings().LiveBGError,
|
||||||
unicode(translate('MediaPlugin.MediaItem',
|
unicode(translate('MediaPlugin.MediaItem',
|
||||||
'There was a problem replacing your background, '
|
'There was a problem replacing your background, '
|
||||||
'the media file "%s" no longer exists.')) % filename)
|
'the media file "%s" no longer exists.')) % filename)
|
||||||
@ -209,4 +209,4 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
img = QtGui.QPixmap(u':/media/media_video.png').toImage()
|
img = QtGui.QPixmap(u':/media/media_video.png').toImage()
|
||||||
item_name.setIcon(build_icon(img))
|
item_name.setIcon(build_icon(img))
|
||||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
||||||
self.listView.addItem(item_name)
|
self.listView.addItem(item_name)
|
@ -244,7 +244,7 @@ class ImpressDocument(PresentationDocument):
|
|||||||
return False
|
return False
|
||||||
self.presentation = self.document.getPresentation()
|
self.presentation = self.document.getPresentation()
|
||||||
self.presentation.Display = \
|
self.presentation.Display = \
|
||||||
self.controller.plugin.renderManager.screens.current_display + 1
|
self.controller.plugin.renderer.screens.current_display + 1
|
||||||
self.control = None
|
self.control = None
|
||||||
self.create_thumbnails()
|
self.create_thumbnails()
|
||||||
return True
|
return True
|
||||||
@ -463,4 +463,4 @@ class ImpressDocument(PresentationDocument):
|
|||||||
shape = page.getByIndex(idx)
|
shape = page.getByIndex(idx)
|
||||||
if shape.supportsService("com.sun.star.drawing.Text"):
|
if shape.supportsService("com.sun.star.drawing.Text"):
|
||||||
text += shape.getString() + '\n'
|
text += shape.getString() + '\n'
|
||||||
return text
|
return text
|
@ -203,7 +203,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
"""
|
"""
|
||||||
Remove a presentation item from the list
|
Remove a presentation item from the list
|
||||||
"""
|
"""
|
||||||
if check_item_selected(self.listView, UiStrings.SelectDelete):
|
if check_item_selected(self.listView, UiStrings().SelectDelete):
|
||||||
items = self.listView.selectedIndexes()
|
items = self.listView.selectedIndexes()
|
||||||
row_list = [item.row() for item in items]
|
row_list = [item.row() for item in items]
|
||||||
row_list.sort(reverse=True)
|
row_list.sort(reverse=True)
|
||||||
@ -296,4 +296,4 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
if self.controllers[controller].enabled():
|
if self.controllers[controller].enabled():
|
||||||
if filetype in self.controllers[controller].alsosupports:
|
if filetype in self.controllers[controller].alsosupports:
|
||||||
return controller
|
return controller
|
||||||
return None
|
return None
|
@ -251,14 +251,15 @@ class PowerpointDocument(PresentationDocument):
|
|||||||
win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88)
|
win32ui.GetForegroundWindow().GetDC().GetDeviceCaps(88)
|
||||||
except win32ui.error:
|
except win32ui.error:
|
||||||
dpi = 96
|
dpi = 96
|
||||||
rendermanager = self.controller.plugin.renderManager
|
renderer = self.controller.plugin.renderer
|
||||||
rect = rendermanager.screens.current[u'size']
|
rect = renderer.screens.current[u'size']
|
||||||
ppt_window = self.presentation.SlideShowSettings.Run()
|
ppt_window = self.presentation.SlideShowSettings.Run()
|
||||||
ppt_window.Top = rect.y() * 72 / dpi
|
ppt_window.Top = rect.y() * 72 / dpi
|
||||||
ppt_window.Height = rect.height() * 72 / dpi
|
ppt_window.Height = rect.height() * 72 / dpi
|
||||||
ppt_window.Left = rect.x() * 72 / dpi
|
ppt_window.Left = rect.x() * 72 / dpi
|
||||||
ppt_window.Width = rect.width() * 72 / dpi
|
ppt_window.Width = rect.width() * 72 / dpi
|
||||||
|
|
||||||
|
|
||||||
def get_slide_number(self):
|
def get_slide_number(self):
|
||||||
"""
|
"""
|
||||||
Returns the current slide number.
|
Returns the current slide number.
|
||||||
|
@ -121,8 +121,8 @@ class PptviewDocument(PresentationDocument):
|
|||||||
The file name of the presentations to run.
|
The file name of the presentations to run.
|
||||||
"""
|
"""
|
||||||
log.debug(u'LoadPresentation')
|
log.debug(u'LoadPresentation')
|
||||||
rendermanager = self.controller.plugin.renderManager
|
renderer = self.controller.plugin.renderer
|
||||||
rect = rendermanager.screens.current[u'size']
|
rect = renderer.screens.current[u'size']
|
||||||
rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom())
|
rect = RECT(rect.x(), rect.y(), rect.right(), rect.bottom())
|
||||||
filepath = str(self.filepath.replace(u'/', u'\\'))
|
filepath = str(self.filepath.replace(u'/', u'\\'))
|
||||||
if not os.path.isdir(self.get_temp_folder()):
|
if not os.path.isdir(self.get_temp_folder()):
|
||||||
@ -244,4 +244,4 @@ class PptviewDocument(PresentationDocument):
|
|||||||
"""
|
"""
|
||||||
Triggers the previous slide on the running presentation
|
Triggers the previous slide on the running presentation
|
||||||
"""
|
"""
|
||||||
self.controller.process.PrevStep(self.pptid)
|
self.controller.process.PrevStep(self.pptid)
|
@ -27,6 +27,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <direct.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -88,7 +90,12 @@ DllExport BOOL CheckInstalled()
|
|||||||
char cmdLine[MAX_PATH * 2];
|
char cmdLine[MAX_PATH * 2];
|
||||||
|
|
||||||
DEBUG("CheckInstalled\n");
|
DEBUG("CheckInstalled\n");
|
||||||
return GetPPTViewerPath(cmdLine, sizeof(cmdLine));
|
BOOL found = GetPPTViewerPath(cmdLine, sizeof(cmdLine));
|
||||||
|
if(found)
|
||||||
|
{
|
||||||
|
DEBUG("Exe: %s\n", cmdLine);
|
||||||
|
}
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the PointPoint, count the slides and take a snapshot of each slide
|
// Open the PointPoint, count the slides and take a snapshot of each slide
|
||||||
@ -160,7 +167,7 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||||||
pptView[id].rect.bottom = rect.bottom;
|
pptView[id].rect.bottom = rect.bottom;
|
||||||
pptView[id].rect.right = rect.right;
|
pptView[id].rect.right = rect.right;
|
||||||
}
|
}
|
||||||
strcat_s(cmdLine, MAX_PATH * 2, "/F /S \"");
|
strcat_s(cmdLine, MAX_PATH * 2, " /F /S \"");
|
||||||
strcat_s(cmdLine, MAX_PATH * 2, filename);
|
strcat_s(cmdLine, MAX_PATH * 2, filename);
|
||||||
strcat_s(cmdLine, MAX_PATH * 2, "\"");
|
strcat_s(cmdLine, MAX_PATH * 2, "\"");
|
||||||
memset(&si, 0, sizeof(si));
|
memset(&si, 0, sizeof(si));
|
||||||
@ -189,7 +196,7 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect,
|
|||||||
Sleep(10);
|
Sleep(10);
|
||||||
if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi))
|
if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi))
|
||||||
{
|
{
|
||||||
DEBUG("OpenPPT: CreateProcess failed\n");
|
DEBUG("OpenPPT: CreateProcess failed: %s\n", cmdLine);
|
||||||
ClosePPT(id);
|
ClosePPT(id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -344,16 +351,71 @@ BOOL SavePPTInfo(int id)
|
|||||||
|
|
||||||
// Get the path of the PowerPoint viewer from the registry
|
// Get the path of the PowerPoint viewer from the registry
|
||||||
BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize)
|
BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize)
|
||||||
|
{
|
||||||
|
char cwd[MAX_PATH];
|
||||||
|
|
||||||
|
DEBUG("GetPPTViewerPath: start\n");
|
||||||
|
if(GetPPTViewerPathFromReg(pptViewerPath, stringSize))
|
||||||
|
{
|
||||||
|
if(_access(pptViewerPath, 0) != -1)
|
||||||
|
{
|
||||||
|
DEBUG("GetPPTViewerPath: exit registry\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This is where it gets ugly. PPT2007 it seems no longer stores its
|
||||||
|
// location in the registry. So we have to use the defaults which will
|
||||||
|
// upset those who like to put things somewhere else
|
||||||
|
|
||||||
|
// Viewer 2007 in 64bit Windows:
|
||||||
|
if(_access("C:\\Program Files (x86)\\Microsoft Office\\Office12\\PPTVIEW.EXE",
|
||||||
|
0) != -1)
|
||||||
|
{
|
||||||
|
strcpy_s(
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Office\\Office12\\PPTVIEW.EXE",
|
||||||
|
stringSize, pptViewerPath);
|
||||||
|
DEBUG("GetPPTViewerPath: exit 64bit 2007\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
// Viewer 2007 in 32bit Windows:
|
||||||
|
if(_access("C:\\Program Files\\Microsoft Office\\Office12\\PPTVIEW.EXE", 0)
|
||||||
|
!= -1)
|
||||||
|
{
|
||||||
|
strcpy_s("C:\\Program Files\\Microsoft Office\\Office12\\PPTVIEW.EXE",
|
||||||
|
stringSize, pptViewerPath);
|
||||||
|
DEBUG("GetPPTViewerPath: exit 32bit 2007\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
// Give them the opportunity to place it in the same folder as the app
|
||||||
|
_getcwd(cwd, MAX_PATH);
|
||||||
|
strcat_s(cwd, MAX_PATH, "\\PPTVIEW.EXE");
|
||||||
|
if(_access(cwd, 0) != -1)
|
||||||
|
{
|
||||||
|
strcpy_s(pptViewerPath, stringSize, cwd);
|
||||||
|
DEBUG("GetPPTViewerPath: exit local\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
DEBUG("GetPPTViewerPath: exit fail\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
BOOL GetPPTViewerPathFromReg(char *pptViewerPath, int stringSize)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
DWORD dwType, dwSize;
|
DWORD dwType, dwSize;
|
||||||
LRESULT lResult;
|
LRESULT lResult;
|
||||||
|
|
||||||
DEBUG("GetPPTViewerPath: start\n");
|
// The following registry settings are for, respectively, (I think)
|
||||||
|
// PPT Viewer 2007 (older versions. Latest not in registry) & PPT Viewer 2010
|
||||||
|
// PPT Viewer 2003 (recent versions)
|
||||||
|
// PPT Viewer 2003 (older versions)
|
||||||
|
// PPT Viewer 97
|
||||||
if ((RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
if ((RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
||||||
"PowerPointViewer.Show.12\\shell\\Show\\command", 0, KEY_READ, &hKey)
|
"PowerPointViewer.Show.12\\shell\\Show\\command", 0, KEY_READ, &hKey)
|
||||||
!= ERROR_SUCCESS)
|
!= ERROR_SUCCESS)
|
||||||
&& (RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
&& (RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
||||||
|
"PowerPointViewer.Show.11\\shell\\Show\\command", 0, KEY_READ, &hKey)
|
||||||
|
!= ERROR_SUCCESS)
|
||||||
|
&& (RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
||||||
"Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hKey)
|
"Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hKey)
|
||||||
!= ERROR_SUCCESS)
|
!= ERROR_SUCCESS)
|
||||||
&& (RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
&& (RegOpenKeyEx(HKEY_CLASSES_ROOT,
|
||||||
@ -373,7 +435,6 @@ BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize)
|
|||||||
}
|
}
|
||||||
// remove "%1" from end of key value
|
// remove "%1" from end of key value
|
||||||
pptViewerPath[strlen(pptViewerPath) - 4] = '\0';
|
pptViewerPath[strlen(pptViewerPath) - 4] = '\0';
|
||||||
DEBUG("GetPPTViewerPath: exit ok\n");
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam);
|
|||||||
LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam);
|
LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||||
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
|
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||||
BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize);
|
BOOL GetPPTViewerPath(char *pptViewerPath, int stringSize);
|
||||||
|
BOOL GetPPTViewerPathFromReg(char *pptViewerPath, int stringSize);
|
||||||
HBITMAP CaptureWindow(HWND hWnd);
|
HBITMAP CaptureWindow(HWND hWnd);
|
||||||
VOID SaveBitmap(CHAR* filename, HBITMAP hBmp) ;
|
VOID SaveBitmap(CHAR* filename, HBITMAP hBmp) ;
|
||||||
VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename);
|
VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename);
|
||||||
|
@ -86,7 +86,7 @@ class PresentationTab(SettingsTab):
|
|||||||
checkbox.setText(
|
checkbox.setText(
|
||||||
unicode(translate('PresentationPlugin.PresentationTab',
|
unicode(translate('PresentationPlugin.PresentationTab',
|
||||||
'%s (unavailable)')) % controller.name)
|
'%s (unavailable)')) % controller.name)
|
||||||
self.AdvancedGroupBox.setTitle(UiStrings.Advanced)
|
self.AdvancedGroupBox.setTitle(UiStrings().Advanced)
|
||||||
self.OverrideAppCheckBox.setText(
|
self.OverrideAppCheckBox.setText(
|
||||||
translate('PresentationPlugin.PresentationTab',
|
translate('PresentationPlugin.PresentationTab',
|
||||||
'Allow presentation application to be overriden'))
|
'Allow presentation application to be overriden'))
|
||||||
@ -131,4 +131,4 @@ class PresentationTab(SettingsTab):
|
|||||||
QtCore.QVariant(self.OverrideAppCheckBox.checkState()))
|
QtCore.QVariant(self.OverrideAppCheckBox.checkState()))
|
||||||
changed = True
|
changed = True
|
||||||
if changed:
|
if changed:
|
||||||
Receiver.send_message(u'mediaitem_presentation_rebuild')
|
Receiver.send_message(u'mediaitem_presentation_rebuild')
|
@ -260,11 +260,11 @@ class Ui_EditSongDialog(object):
|
|||||||
translate('SongsPlugin.EditSongForm', '&Lyrics:'))
|
translate('SongsPlugin.EditSongForm', '&Lyrics:'))
|
||||||
self.verseOrderLabel.setText(
|
self.verseOrderLabel.setText(
|
||||||
translate('SongsPlugin.EditSongForm', '&Verse order:'))
|
translate('SongsPlugin.EditSongForm', '&Verse order:'))
|
||||||
self.verseAddButton.setText(UiStrings.Add)
|
self.verseAddButton.setText(UiStrings().Add)
|
||||||
self.verseEditButton.setText(UiStrings.Edit)
|
self.verseEditButton.setText(UiStrings().Edit)
|
||||||
self.verseEditAllButton.setText(
|
self.verseEditAllButton.setText(
|
||||||
translate('SongsPlugin.EditSongForm', 'Ed&it All'))
|
translate('SongsPlugin.EditSongForm', 'Ed&it All'))
|
||||||
self.verseDeleteButton.setText(UiStrings.Delete)
|
self.verseDeleteButton.setText(UiStrings().Delete)
|
||||||
self.songTabWidget.setTabText(
|
self.songTabWidget.setTabText(
|
||||||
self.songTabWidget.indexOf(self.lyricsTab),
|
self.songTabWidget.indexOf(self.lyricsTab),
|
||||||
translate('SongsPlugin.EditSongForm', 'Title && Lyrics'))
|
translate('SongsPlugin.EditSongForm', 'Title && Lyrics'))
|
||||||
@ -289,13 +289,13 @@ class Ui_EditSongDialog(object):
|
|||||||
self.songTabWidget.indexOf(self.authorsTab),
|
self.songTabWidget.indexOf(self.authorsTab),
|
||||||
translate('SongsPlugin.EditSongForm',
|
translate('SongsPlugin.EditSongForm',
|
||||||
'Authors, Topics && Song Book'))
|
'Authors, Topics && Song Book'))
|
||||||
self.themeGroupBox.setTitle(UiStrings.Theme)
|
self.themeGroupBox.setTitle(UiStrings().Theme)
|
||||||
self.themeAddButton.setText(
|
self.themeAddButton.setText(
|
||||||
translate('SongsPlugin.EditSongForm', 'New &Theme'))
|
translate('SongsPlugin.EditSongForm', 'New &Theme'))
|
||||||
self.rightsGroupBox.setTitle(
|
self.rightsGroupBox.setTitle(
|
||||||
translate('SongsPlugin.EditSongForm', 'Copyright Information'))
|
translate('SongsPlugin.EditSongForm', 'Copyright Information'))
|
||||||
self.copyrightInsertButton.setText(SongStrings.CopyrightSymbol)
|
self.copyrightInsertButton.setText(SongStrings.CopyrightSymbol)
|
||||||
self.CCLILabel.setText(UiStrings.CCLINumberLabel)
|
self.CCLILabel.setText(UiStrings().CCLINumberLabel)
|
||||||
self.commentsGroupBox.setTitle(
|
self.commentsGroupBox.setTitle(
|
||||||
translate('SongsPlugin.EditSongForm', 'Comments'))
|
translate('SongsPlugin.EditSongForm', 'Comments'))
|
||||||
self.songTabWidget.setTabText(
|
self.songTabWidget.setTabText(
|
||||||
@ -313,4 +313,4 @@ def editSongDialogComboBox(parent, name):
|
|||||||
comboBox.setEditable(True)
|
comboBox.setEditable(True)
|
||||||
comboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
|
comboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
|
||||||
comboBox.setObjectName(name)
|
comboBox.setObjectName(name)
|
||||||
return comboBox
|
return comboBox
|
@ -89,14 +89,14 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
self.onVerseListViewPressed)
|
self.onVerseListViewPressed)
|
||||||
QtCore.QObject.connect(self.themeAddButton,
|
QtCore.QObject.connect(self.themeAddButton,
|
||||||
QtCore.SIGNAL(u'clicked()'),
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
self.parent.parent.renderManager.theme_manager.onAddTheme)
|
self.parent.parent.renderer.theme_manager.onAddTheme)
|
||||||
QtCore.QObject.connect(self.maintenanceButton,
|
QtCore.QObject.connect(self.maintenanceButton,
|
||||||
QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
|
QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
|
QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
|
||||||
self.previewButton = QtGui.QPushButton()
|
self.previewButton = QtGui.QPushButton()
|
||||||
self.previewButton.setObjectName(u'previewButton')
|
self.previewButton.setObjectName(u'previewButton')
|
||||||
self.previewButton.setText(UiStrings.SaveAndPreview)
|
self.previewButton.setText(UiStrings().SaveAndPreview)
|
||||||
self.buttonBox.addButton(
|
self.buttonBox.addButton(
|
||||||
self.previewButton, QtGui.QDialogButtonBox.ActionRole)
|
self.previewButton, QtGui.QDialogButtonBox.ActionRole)
|
||||||
QtCore.QObject.connect(self.buttonBox,
|
QtCore.QObject.connect(self.buttonBox,
|
||||||
@ -355,7 +355,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
self.__addAuthorToList(author)
|
self.__addAuthorToList(author)
|
||||||
self.authorsComboBox.setCurrentIndex(0)
|
self.authorsComboBox.setCurrentIndex(0)
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.warning(self, UiStrings.NISs,
|
QtGui.QMessageBox.warning(self, UiStrings().NISs,
|
||||||
translate('SongsPlugin.EditSongForm', 'You have not selected '
|
translate('SongsPlugin.EditSongForm', 'You have not selected '
|
||||||
'a valid author. Either select an author from the list, '
|
'a valid author. Either select an author from the list, '
|
||||||
'or type in a new author and click the "Add Author to '
|
'or type in a new author and click the "Add Author to '
|
||||||
@ -414,7 +414,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
self.topicsListView.addItem(topic_item)
|
self.topicsListView.addItem(topic_item)
|
||||||
self.topicsComboBox.setCurrentIndex(0)
|
self.topicsComboBox.setCurrentIndex(0)
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.warning(self, UiStrings.NISs,
|
QtGui.QMessageBox.warning(self, UiStrings().NISs,
|
||||||
translate('SongsPlugin.EditSongForm', 'You have not selected '
|
translate('SongsPlugin.EditSongForm', 'You have not selected '
|
||||||
'a valid topic. Either select a topic from the list, or '
|
'a valid topic. Either select a topic from the list, or '
|
||||||
'type in a new topic and click the "Add Topic to Song" '
|
'type in a new topic and click the "Add Topic to Song" '
|
||||||
@ -576,11 +576,13 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
if verse_index is not None:
|
if verse_index is not None:
|
||||||
order.append(VerseType.Tags[verse_index] + u'1')
|
order.append(VerseType.Tags[verse_index] + u'1')
|
||||||
else:
|
else:
|
||||||
order.append(u'') # it matches no verses anyway
|
# it matches no verses anyway
|
||||||
|
order.append(u'')
|
||||||
else:
|
else:
|
||||||
verse_index = VerseType.from_translated_tag(item[0])
|
verse_index = VerseType.from_translated_tag(item[0])
|
||||||
if verse_index is None:
|
if verse_index is None:
|
||||||
order.append(u'') # same as above
|
# it matches no verses anyway
|
||||||
|
order.append(u'')
|
||||||
else:
|
else:
|
||||||
verse_tag = VerseType.Tags[verse_index]
|
verse_tag = VerseType.Tags[verse_index]
|
||||||
verse_num = item[1:].lower()
|
verse_num = item[1:].lower()
|
||||||
@ -779,4 +781,4 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
self.song.verse_order)
|
self.song.verse_order)
|
||||||
except:
|
except:
|
||||||
log.exception(u'Problem processing song Lyrics \n%s',
|
log.exception(u'Problem processing song Lyrics \n%s',
|
||||||
sxml.dump_xml())
|
sxml.dump_xml())
|
||||||
|
@ -175,7 +175,7 @@ class SongExportForm(OpenLPWizard):
|
|||||||
self.availableSongsPage.setSubTitle(
|
self.availableSongsPage.setSubTitle(
|
||||||
translate('SongsPlugin.ExportWizardForm',
|
translate('SongsPlugin.ExportWizardForm',
|
||||||
'Check the songs you want to export.'))
|
'Check the songs you want to export.'))
|
||||||
self.searchLabel.setText(u'%s:' % UiStrings.Search)
|
self.searchLabel.setText(u'%s:' % UiStrings().Search)
|
||||||
self.uncheckButton.setText(
|
self.uncheckButton.setText(
|
||||||
translate('SongsPlugin.ExportWizardForm', 'Uncheck All'))
|
translate('SongsPlugin.ExportWizardForm', 'Uncheck All'))
|
||||||
self.checkButton.setText(
|
self.checkButton.setText(
|
||||||
@ -207,7 +207,7 @@ class SongExportForm(OpenLPWizard):
|
|||||||
self.availableListWidget) if item.checkState()
|
self.availableListWidget) if item.checkState()
|
||||||
]
|
]
|
||||||
if not items:
|
if not items:
|
||||||
critical_error_message_box(UiStrings.NISp,
|
critical_error_message_box(UiStrings().NISp,
|
||||||
translate('SongsPlugin.ExportWizardForm',
|
translate('SongsPlugin.ExportWizardForm',
|
||||||
'You need to add at least one Song to export.'))
|
'You need to add at least one Song to export.'))
|
||||||
return False
|
return False
|
||||||
@ -360,4 +360,4 @@ class SongExportForm(OpenLPWizard):
|
|||||||
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
|
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
|
||||||
options=QtGui.QFileDialog.ShowDirsOnly))
|
options=QtGui.QFileDialog.ShowDirsOnly))
|
||||||
SettingsManager.set_last_dir(self.plugin.settingsSection, path, 1)
|
SettingsManager.set_last_dir(self.plugin.settingsSection, path, 1)
|
||||||
self.directoryLineEdit.setText(path)
|
self.directoryLineEdit.setText(path)
|
@ -26,6 +26,7 @@
|
|||||||
"""
|
"""
|
||||||
The song import functions for OpenLP.
|
The song import functions for OpenLP.
|
||||||
"""
|
"""
|
||||||
|
import codecs
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ class SongImportForm(OpenLPWizard):
|
|||||||
``plugin``
|
``plugin``
|
||||||
The songs plugin.
|
The songs plugin.
|
||||||
"""
|
"""
|
||||||
|
self.clipboard = plugin.formparent.clipboard
|
||||||
OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard',
|
OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard',
|
||||||
u':/wizards/wizard_importsong.bmp')
|
u':/wizards/wizard_importsong.bmp')
|
||||||
|
|
||||||
@ -235,8 +237,8 @@ class SongImportForm(OpenLPWizard):
|
|||||||
self.sourcePage.setTitle(WizardStrings.ImportSelect)
|
self.sourcePage.setTitle(WizardStrings.ImportSelect)
|
||||||
self.sourcePage.setSubTitle(WizardStrings.ImportSelectLong)
|
self.sourcePage.setSubTitle(WizardStrings.ImportSelectLong)
|
||||||
self.formatLabel.setText(WizardStrings.FormatLabel)
|
self.formatLabel.setText(WizardStrings.FormatLabel)
|
||||||
self.formatComboBox.setItemText(SongFormat.OpenLP2, UiStrings.OLPV2)
|
self.formatComboBox.setItemText(SongFormat.OpenLP2, UiStrings().OLPV2)
|
||||||
self.formatComboBox.setItemText(SongFormat.OpenLP1, UiStrings.OLPV1)
|
self.formatComboBox.setItemText(SongFormat.OpenLP1, UiStrings().OLPV1)
|
||||||
self.formatComboBox.setItemText(
|
self.formatComboBox.setItemText(
|
||||||
SongFormat.OpenLyrics, WizardStrings.OL)
|
SongFormat.OpenLyrics, WizardStrings.OL)
|
||||||
self.formatComboBox.setItemText(SongFormat.OpenSong, WizardStrings.OS)
|
self.formatComboBox.setItemText(SongFormat.OpenSong, WizardStrings.OS)
|
||||||
@ -261,10 +263,10 @@ class SongImportForm(OpenLPWizard):
|
|||||||
# self.formatComboBox.setItemText(SongFormat.CSV, WizardStrings.CSV)
|
# self.formatComboBox.setItemText(SongFormat.CSV, WizardStrings.CSV)
|
||||||
self.openLP2FilenameLabel.setText(
|
self.openLP2FilenameLabel.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
self.openLP2BrowseButton.setText(UiStrings.Browse)
|
self.openLP2BrowseButton.setText(UiStrings().Browse)
|
||||||
self.openLP1FilenameLabel.setText(
|
self.openLP1FilenameLabel.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
self.openLP1BrowseButton.setText(UiStrings.Browse)
|
self.openLP1BrowseButton.setText(UiStrings().Browse)
|
||||||
self.openLP1DisabledLabel.setText(WizardStrings.NoSqlite)
|
self.openLP1DisabledLabel.setText(WizardStrings.NoSqlite)
|
||||||
self.openLyricsAddButton.setText(
|
self.openLyricsAddButton.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||||
@ -305,10 +307,10 @@ class SongImportForm(OpenLPWizard):
|
|||||||
'find OpenOffice.org on your computer.'))
|
'find OpenOffice.org on your computer.'))
|
||||||
self.easiSlidesFilenameLabel.setText(
|
self.easiSlidesFilenameLabel.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
self.easiSlidesBrowseButton.setText(UiStrings.Browse)
|
self.easiSlidesBrowseButton.setText(UiStrings().Browse)
|
||||||
self.ewFilenameLabel.setText(
|
self.ewFilenameLabel.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
self.ewBrowseButton.setText(UiStrings.Browse)
|
self.ewBrowseButton.setText(UiStrings().Browse)
|
||||||
self.songBeamerAddButton.setText(
|
self.songBeamerAddButton.setText(
|
||||||
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||||
self.songBeamerRemoveButton.setText(
|
self.songBeamerRemoveButton.setText(
|
||||||
@ -323,13 +325,17 @@ class SongImportForm(OpenLPWizard):
|
|||||||
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
||||||
# self.csvFilenameLabel.setText(
|
# self.csvFilenameLabel.setText(
|
||||||
# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
# translate('SongsPlugin.ImportWizardForm', 'Filename:'))
|
||||||
# self.csvBrowseButton.setText(UiStrings.Browse)
|
# self.csvBrowseButton.setText(UiStrings().Browse)
|
||||||
self.progressPage.setTitle(WizardStrings.Importing)
|
self.progressPage.setTitle(WizardStrings.Importing)
|
||||||
self.progressPage.setSubTitle(
|
self.progressPage.setSubTitle(
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'Please wait while your songs are imported.'))
|
'Please wait while your songs are imported.'))
|
||||||
self.progressLabel.setText(WizardStrings.Ready)
|
self.progressLabel.setText(WizardStrings.Ready)
|
||||||
self.progressBar.setFormat(WizardStrings.PercentSymbolFormat)
|
self.progressBar.setFormat(WizardStrings.PercentSymbolFormat)
|
||||||
|
self.errorCopyToButton.setText(translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'Copy'))
|
||||||
|
self.errorSaveToButton.setText(translate('SongsPlugin.ImportWizardForm',
|
||||||
|
'Save to File'))
|
||||||
# Align all QFormLayouts towards each other.
|
# Align all QFormLayouts towards each other.
|
||||||
width = max(self.formatLabel.minimumSizeHint().width(),
|
width = max(self.formatLabel.minimumSizeHint().width(),
|
||||||
self.openLP2FilenameLabel.minimumSizeHint().width())
|
self.openLP2FilenameLabel.minimumSizeHint().width())
|
||||||
@ -346,49 +352,49 @@ class SongImportForm(OpenLPWizard):
|
|||||||
source_format = self.formatComboBox.currentIndex()
|
source_format = self.formatComboBox.currentIndex()
|
||||||
if source_format == SongFormat.OpenLP2:
|
if source_format == SongFormat.OpenLP2:
|
||||||
if self.openLP2FilenameEdit.text().isEmpty():
|
if self.openLP2FilenameEdit.text().isEmpty():
|
||||||
critical_error_message_box(UiStrings.NFSs,
|
critical_error_message_box(UiStrings().NFSs,
|
||||||
WizardStrings.YouSpecifyFile % UiStrings.OLPV2)
|
WizardStrings.YouSpecifyFile % UiStrings().OLPV2)
|
||||||
self.openLP2BrowseButton.setFocus()
|
self.openLP2BrowseButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.OpenLP1:
|
elif source_format == SongFormat.OpenLP1:
|
||||||
if self.openLP1FilenameEdit.text().isEmpty():
|
if self.openLP1FilenameEdit.text().isEmpty():
|
||||||
critical_error_message_box(UiStrings.NFSs,
|
critical_error_message_box(UiStrings().NFSs,
|
||||||
WizardStrings.YouSpecifyFile % UiStrings.OLPV1)
|
WizardStrings.YouSpecifyFile % UiStrings().OLPV1)
|
||||||
self.openLP1BrowseButton.setFocus()
|
self.openLP1BrowseButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.OpenLyrics:
|
elif source_format == SongFormat.OpenLyrics:
|
||||||
if self.openLyricsFileListWidget.count() == 0:
|
if self.openLyricsFileListWidget.count() == 0:
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.OL)
|
WizardStrings.YouSpecifyFile % WizardStrings.OL)
|
||||||
self.openLyricsAddButton.setFocus()
|
self.openLyricsAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.OpenSong:
|
elif source_format == SongFormat.OpenSong:
|
||||||
if self.openSongFileListWidget.count() == 0:
|
if self.openSongFileListWidget.count() == 0:
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.OS)
|
WizardStrings.YouSpecifyFile % WizardStrings.OS)
|
||||||
self.openSongAddButton.setFocus()
|
self.openSongAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.WordsOfWorship:
|
elif source_format == SongFormat.WordsOfWorship:
|
||||||
if self.wordsOfWorshipFileListWidget.count() == 0:
|
if self.wordsOfWorshipFileListWidget.count() == 0:
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.WoW)
|
WizardStrings.YouSpecifyFile % WizardStrings.WoW)
|
||||||
self.wordsOfWorshipAddButton.setFocus()
|
self.wordsOfWorshipAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.CCLI:
|
elif source_format == SongFormat.CCLI:
|
||||||
if self.ccliFileListWidget.count() == 0:
|
if self.ccliFileListWidget.count() == 0:
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.CCLI)
|
WizardStrings.YouSpecifyFile % WizardStrings.CCLI)
|
||||||
self.ccliAddButton.setFocus()
|
self.ccliAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.SongsOfFellowship:
|
elif source_format == SongFormat.SongsOfFellowship:
|
||||||
if self.songsOfFellowshipFileListWidget.count() == 0:
|
if self.songsOfFellowshipFileListWidget.count() == 0:
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.SoF)
|
WizardStrings.YouSpecifyFile % WizardStrings.SoF)
|
||||||
self.songsOfFellowshipAddButton.setFocus()
|
self.songsOfFellowshipAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.Generic:
|
elif source_format == SongFormat.Generic:
|
||||||
if self.genericFileListWidget.count() == 0:
|
if self.genericFileListWidget.count() == 0:
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
translate('SongsPlugin.ImportWizardForm',
|
translate('SongsPlugin.ImportWizardForm',
|
||||||
'You need to specify at least one document or '
|
'You need to specify at least one document or '
|
||||||
'presentation file to import from.'))
|
'presentation file to import from.'))
|
||||||
@ -396,31 +402,31 @@ class SongImportForm(OpenLPWizard):
|
|||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.EasiSlides:
|
elif source_format == SongFormat.EasiSlides:
|
||||||
if self.easiSlidesFilenameEdit.text().isEmpty():
|
if self.easiSlidesFilenameEdit.text().isEmpty():
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.ES)
|
WizardStrings.YouSpecifyFile % WizardStrings.ES)
|
||||||
self.easiSlidesBrowseButton.setFocus()
|
self.easiSlidesBrowseButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.EasyWorship:
|
elif source_format == SongFormat.EasyWorship:
|
||||||
if self.ewFilenameEdit.text().isEmpty():
|
if self.ewFilenameEdit.text().isEmpty():
|
||||||
critical_error_message_box(UiStrings.NFSs,
|
critical_error_message_box(UiStrings().NFSs,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.EW)
|
WizardStrings.YouSpecifyFile % WizardStrings.EW)
|
||||||
self.ewBrowseButton.setFocus()
|
self.ewBrowseButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.SongBeamer:
|
elif source_format == SongFormat.SongBeamer:
|
||||||
if self.songBeamerFileListWidget.count() == 0:
|
if self.songBeamerFileListWidget.count() == 0:
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.SB)
|
WizardStrings.YouSpecifyFile % WizardStrings.SB)
|
||||||
self.songBeamerAddButton.setFocus()
|
self.songBeamerAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.SongShowPlus:
|
elif source_format == SongFormat.SongShowPlus:
|
||||||
if self.songShowPlusFileListWidget.count() == 0:
|
if self.songShowPlusFileListWidget.count() == 0:
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.SSP)
|
WizardStrings.YouSpecifyFile % WizardStrings.SSP)
|
||||||
self.wordsOfWorshipAddButton.setFocus()
|
self.wordsOfWorshipAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
elif source_format == SongFormat.FoilPresenter:
|
elif source_format == SongFormat.FoilPresenter:
|
||||||
if self.foilPresenterFileListWidget.count() == 0:
|
if self.foilPresenterFileListWidget.count() == 0:
|
||||||
critical_error_message_box(UiStrings.NFSp,
|
critical_error_message_box(UiStrings().NFSp,
|
||||||
WizardStrings.YouSpecifyFile % WizardStrings.FP)
|
WizardStrings.YouSpecifyFile % WizardStrings.FP)
|
||||||
self.foilPresenterAddButton.setFocus()
|
self.foilPresenterAddButton.setFocus()
|
||||||
return False
|
return False
|
||||||
@ -446,7 +452,7 @@ class SongImportForm(OpenLPWizard):
|
|||||||
"""
|
"""
|
||||||
if filters:
|
if filters:
|
||||||
filters += u';;'
|
filters += u';;'
|
||||||
filters += u'%s (*)' % UiStrings.AllFiles
|
filters += u'%s (*)' % UiStrings().AllFiles
|
||||||
filenames = QtGui.QFileDialog.getOpenFileNames(self, title,
|
filenames = QtGui.QFileDialog.getOpenFileNames(self, title,
|
||||||
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
|
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
|
||||||
filters)
|
filters)
|
||||||
@ -459,10 +465,7 @@ class SongImportForm(OpenLPWizard):
|
|||||||
"""
|
"""
|
||||||
Return a list of file from the listbox
|
Return a list of file from the listbox
|
||||||
"""
|
"""
|
||||||
files = []
|
return [unicode(listbox.item(i).text()) for i in range(listbox.count())]
|
||||||
for row in range(0, listbox.count()):
|
|
||||||
files.append(unicode(listbox.item(row).text()))
|
|
||||||
return files
|
|
||||||
|
|
||||||
def removeSelectedItems(self, listbox):
|
def removeSelectedItems(self, listbox):
|
||||||
"""
|
"""
|
||||||
@ -476,7 +479,7 @@ class SongImportForm(OpenLPWizard):
|
|||||||
"""
|
"""
|
||||||
Get OpenLP v2 song database file
|
Get OpenLP v2 song database file
|
||||||
"""
|
"""
|
||||||
self.getFileName(WizardStrings.OpenTypeFile % UiStrings.OLPV2,
|
self.getFileName(WizardStrings.OpenTypeFile % UiStrings().OLPV2,
|
||||||
self.openLP2FilenameEdit, u'%s (*.sqlite)'
|
self.openLP2FilenameEdit, u'%s (*.sqlite)'
|
||||||
% (translate('SongsPlugin.ImportWizardForm',
|
% (translate('SongsPlugin.ImportWizardForm',
|
||||||
'OpenLP 2.0 Databases'))
|
'OpenLP 2.0 Databases'))
|
||||||
@ -486,7 +489,7 @@ class SongImportForm(OpenLPWizard):
|
|||||||
"""
|
"""
|
||||||
Get OpenLP v1 song database file
|
Get OpenLP v1 song database file
|
||||||
"""
|
"""
|
||||||
self.getFileName(WizardStrings.OpenTypeFile % UiStrings.OLPV1,
|
self.getFileName(WizardStrings.OpenTypeFile % UiStrings().OLPV1,
|
||||||
self.openLP1FilenameEdit, u'%s (*.olp)'
|
self.openLP1FilenameEdit, u'%s (*.olp)'
|
||||||
% translate('SongsPlugin.ImportWizardForm',
|
% translate('SongsPlugin.ImportWizardForm',
|
||||||
'openlp.org v1.x Databases')
|
'openlp.org v1.x Databases')
|
||||||
@ -659,6 +662,10 @@ class SongImportForm(OpenLPWizard):
|
|||||||
self.songShowPlusFileListWidget.clear()
|
self.songShowPlusFileListWidget.clear()
|
||||||
self.foilPresenterFileListWidget.clear()
|
self.foilPresenterFileListWidget.clear()
|
||||||
#self.csvFilenameEdit.setText(u'')
|
#self.csvFilenameEdit.setText(u'')
|
||||||
|
self.errorReportTextEdit.clear()
|
||||||
|
self.errorReportTextEdit.setHidden(True)
|
||||||
|
self.errorCopyToButton.setHidden(True)
|
||||||
|
self.errorSaveToButton.setHidden(True)
|
||||||
|
|
||||||
def preWizard(self):
|
def preWizard(self):
|
||||||
"""
|
"""
|
||||||
@ -743,12 +750,30 @@ class SongImportForm(OpenLPWizard):
|
|||||||
importer = self.plugin.importSongs(SongFormat.FoilPresenter,
|
importer = self.plugin.importSongs(SongFormat.FoilPresenter,
|
||||||
filenames=self.getListOfFiles(self.foilPresenterFileListWidget)
|
filenames=self.getListOfFiles(self.foilPresenterFileListWidget)
|
||||||
)
|
)
|
||||||
if importer.do_import():
|
importer.do_import()
|
||||||
self.progressLabel.setText(WizardStrings.FinishedImport)
|
if importer.error_log:
|
||||||
|
self.progressLabel.setText(translate(
|
||||||
|
'SongsPlugin.SongImportForm', 'Your song import failed.'))
|
||||||
else:
|
else:
|
||||||
self.progressLabel.setText(
|
self.progressLabel.setText(WizardStrings.FinishedImport)
|
||||||
translate('SongsPlugin.SongImportForm',
|
|
||||||
'Your song import failed.'))
|
def onErrorCopyToButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Copy the error report to the clipboard.
|
||||||
|
"""
|
||||||
|
self.clipboard.setText(self.errorReportTextEdit.toPlainText())
|
||||||
|
|
||||||
|
def onErrorSaveToButtonClicked(self):
|
||||||
|
"""
|
||||||
|
Save the error report to a file.
|
||||||
|
"""
|
||||||
|
filename = QtGui.QFileDialog.getSaveFileName(self,
|
||||||
|
SettingsManager.get_last_dir(self.plugin.settingsSection, 1))
|
||||||
|
if not filename:
|
||||||
|
return
|
||||||
|
file = codecs.open(filename, u'w', u'utf-8')
|
||||||
|
file.write(self.errorReportTextEdit.toPlainText())
|
||||||
|
file.close()
|
||||||
|
|
||||||
def addFileSelectItem(self, prefix, obj_prefix=None, can_disable=False,
|
def addFileSelectItem(self, prefix, obj_prefix=None, can_disable=False,
|
||||||
single_select=False):
|
single_select=False):
|
||||||
|
@ -149,17 +149,17 @@ class Ui_SongMaintenanceDialog(object):
|
|||||||
self.listItemAuthors.setText(SongStrings.Authors)
|
self.listItemAuthors.setText(SongStrings.Authors)
|
||||||
self.listItemTopics.setText(SongStrings.Topics)
|
self.listItemTopics.setText(SongStrings.Topics)
|
||||||
self.listItemBooks.setText(SongStrings.SongBooks)
|
self.listItemBooks.setText(SongStrings.SongBooks)
|
||||||
self.authorsAddButton.setText(UiStrings.Add)
|
self.authorsAddButton.setText(UiStrings().Add)
|
||||||
self.authorsEditButton.setText(UiStrings.Edit)
|
self.authorsEditButton.setText(UiStrings().Edit)
|
||||||
self.authorsDeleteButton.setText(UiStrings.Delete)
|
self.authorsDeleteButton.setText(UiStrings().Delete)
|
||||||
self.topicsAddButton.setText(UiStrings.Add)
|
self.topicsAddButton.setText(UiStrings().Add)
|
||||||
self.topicsEditButton.setText(UiStrings.Edit)
|
self.topicsEditButton.setText(UiStrings().Edit)
|
||||||
self.topicsDeleteButton.setText(UiStrings.Delete)
|
self.topicsDeleteButton.setText(UiStrings().Delete)
|
||||||
self.booksAddButton.setText(UiStrings.Add)
|
self.booksAddButton.setText(UiStrings().Add)
|
||||||
self.booksEditButton.setText(UiStrings.Edit)
|
self.booksEditButton.setText(UiStrings().Edit)
|
||||||
self.booksDeleteButton.setText(UiStrings.Delete)
|
self.booksDeleteButton.setText(UiStrings().Delete)
|
||||||
typeListWidth = max(self.fontMetrics().width(SongStrings.Authors),
|
typeListWidth = max(self.fontMetrics().width(SongStrings.Authors),
|
||||||
self.fontMetrics().width(SongStrings.Topics),
|
self.fontMetrics().width(SongStrings.Topics),
|
||||||
self.fontMetrics().width(SongStrings.SongBooks))
|
self.fontMetrics().width(SongStrings.SongBooks))
|
||||||
self.typeListWidget.setFixedWidth(typeListWidth +
|
self.typeListWidget.setFixedWidth(typeListWidth +
|
||||||
self.typeListWidget.iconSize().width() + 32)
|
self.typeListWidget.iconSize().width() + 32)
|
@ -115,7 +115,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||||||
else:
|
else:
|
||||||
critical_error_message_box(dlg_title, err_text)
|
critical_error_message_box(dlg_title, err_text)
|
||||||
else:
|
else:
|
||||||
critical_error_message_box(dlg_title, UiStrings.NISs)
|
critical_error_message_box(dlg_title, UiStrings().NISs)
|
||||||
|
|
||||||
def resetAuthors(self):
|
def resetAuthors(self):
|
||||||
"""
|
"""
|
||||||
@ -386,7 +386,8 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||||||
existing_author = self.manager.get_object_filtered(Author,
|
existing_author = self.manager.get_object_filtered(Author,
|
||||||
and_(Author.first_name == old_author.first_name,
|
and_(Author.first_name == old_author.first_name,
|
||||||
Author.last_name == old_author.last_name,
|
Author.last_name == old_author.last_name,
|
||||||
Author.display_name == old_author.display_name))
|
Author.display_name == old_author.display_name,
|
||||||
|
Author.id != old_author.id))
|
||||||
# Find the songs, which have the old_author as author.
|
# Find the songs, which have the old_author as author.
|
||||||
songs = self.manager.get_all_objects(Song,
|
songs = self.manager.get_all_objects(Song,
|
||||||
Song.authors.contains(old_author))
|
Song.authors.contains(old_author))
|
||||||
@ -408,7 +409,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||||||
"""
|
"""
|
||||||
# Find the duplicate.
|
# Find the duplicate.
|
||||||
existing_topic = self.manager.get_object_filtered(Topic,
|
existing_topic = self.manager.get_object_filtered(Topic,
|
||||||
Topic.name == old_topic.name)
|
and_(Topic.name == old_topic.name, Topic.id != old_topic.id))
|
||||||
# Find the songs, which have the old_topic as topic.
|
# Find the songs, which have the old_topic as topic.
|
||||||
songs = self.manager.get_all_objects(Song,
|
songs = self.manager.get_all_objects(Song,
|
||||||
Song.topics.contains(old_topic))
|
Song.topics.contains(old_topic))
|
||||||
@ -431,7 +432,8 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||||||
# Find the duplicate.
|
# Find the duplicate.
|
||||||
existing_book = self.manager.get_object_filtered(Book,
|
existing_book = self.manager.get_object_filtered(Book,
|
||||||
and_(Book.name == old_book.name,
|
and_(Book.name == old_book.name,
|
||||||
Book.publisher == old_book.publisher))
|
Book.publisher == old_book.publisher,
|
||||||
|
Book.id != old_book.id))
|
||||||
# Find the songs, which have the old_book as book.
|
# Find the songs, which have the old_book as book.
|
||||||
songs = self.manager.get_all_objects(Song,
|
songs = self.manager.get_all_objects(Song,
|
||||||
Song.song_book_id == old_book.id)
|
Song.song_book_id == old_book.id)
|
||||||
@ -504,3 +506,4 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||||||
else:
|
else:
|
||||||
deleteButton.setEnabled(True)
|
deleteButton.setEnabled(True)
|
||||||
editButton.setEnabled(True)
|
editButton.setEnabled(True)
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ def clean_song(manager, song):
|
|||||||
``song``
|
``song``
|
||||||
The song object.
|
The song object.
|
||||||
"""
|
"""
|
||||||
song.title = song.title.strip() if song.title else u''
|
song.title = song.title.rstrip() if song.title else u''
|
||||||
if song.alternate_title is None:
|
if song.alternate_title is None:
|
||||||
song.alternate_title = u''
|
song.alternate_title = u''
|
||||||
song.alternate_title = song.alternate_title.strip()
|
song.alternate_title = song.alternate_title.strip()
|
||||||
@ -278,24 +278,32 @@ def clean_song(manager, song):
|
|||||||
# List for later comparison.
|
# List for later comparison.
|
||||||
compare_order = []
|
compare_order = []
|
||||||
for verse in verses:
|
for verse in verses:
|
||||||
type = VerseType.Tags[VerseType.from_loose_input(verse[0][u'type'])]
|
verse_type = VerseType.Tags[VerseType.from_loose_input(
|
||||||
|
verse[0][u'type'])]
|
||||||
sxml.add_verse_to_lyrics(
|
sxml.add_verse_to_lyrics(
|
||||||
type,
|
verse_type,
|
||||||
verse[0][u'label'],
|
verse[0][u'label'],
|
||||||
verse[1],
|
verse[1],
|
||||||
verse[0][u'lang'] if verse[0].has_key(u'lang') else None
|
verse[0][u'lang'] if verse[0].has_key(u'lang') else None
|
||||||
)
|
)
|
||||||
compare_order.append((u'%s%s' % (type, verse[0][u'label'])).upper())
|
compare_order.append((u'%s%s' % (verse_type, verse[0][u'label'])
|
||||||
|
).upper())
|
||||||
|
if verse[0][u'label'] == u'1':
|
||||||
|
compare_order.append(verse_type.upper())
|
||||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||||
# Rebuild the verse order, to convert translated verse tags, which might
|
# Rebuild the verse order, to convert translated verse tags, which might
|
||||||
# have been added prior to 1.9.5.
|
# have been added prior to 1.9.5.
|
||||||
order = song.verse_order.strip().split()
|
if song.verse_order:
|
||||||
|
order = song.verse_order.strip().split()
|
||||||
|
else:
|
||||||
|
order = []
|
||||||
new_order = []
|
new_order = []
|
||||||
for verse_def in order:
|
for verse_def in order:
|
||||||
new_order.append((u'%s%s' % (
|
verse_type = VerseType.Tags[VerseType.from_loose_input(verse_def[0])]
|
||||||
VerseType.Tags[VerseType.from_loose_input(verse_def[0])],
|
if len(verse_def) > 1:
|
||||||
verse_def[1:])).upper()
|
new_order.append((u'%s%s' % (verse_type, verse_def[1:])).upper())
|
||||||
)
|
else:
|
||||||
|
new_order.append(verse_type.upper())
|
||||||
song.verse_order = u' '.join(new_order)
|
song.verse_order = u' '.join(new_order)
|
||||||
# Check if the verse order contains tags for verses which do not exist.
|
# Check if the verse order contains tags for verses which do not exist.
|
||||||
for order in new_order:
|
for order in new_order:
|
||||||
|
@ -59,16 +59,10 @@ class CCLIFileImport(SongImport):
|
|||||||
Import either a ``.usr`` or a ``.txt`` SongSelect file.
|
Import either a ``.usr`` or a ``.txt`` SongSelect file.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Starting CCLI File Import')
|
log.debug(u'Starting CCLI File Import')
|
||||||
song_total = len(self.import_source)
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
self.import_wizard.progressBar.setMaximum(song_total)
|
|
||||||
song_count = 1
|
|
||||||
for filename in self.import_source:
|
for filename in self.import_source:
|
||||||
self.import_wizard.incrementProgressBar(unicode(translate(
|
|
||||||
'SongsPlugin.CCLIFileImport', 'Importing song %d of %d')) %
|
|
||||||
(song_count, song_total))
|
|
||||||
filename = unicode(filename)
|
filename = unicode(filename)
|
||||||
log.debug(u'Importing CCLI File: %s', filename)
|
log.debug(u'Importing CCLI File: %s', filename)
|
||||||
self.set_defaults()
|
|
||||||
lines = []
|
lines = []
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
detect_file = open(filename, u'r')
|
detect_file = open(filename, u'r')
|
||||||
@ -81,19 +75,23 @@ class CCLIFileImport(SongImport):
|
|||||||
detect_file.close()
|
detect_file.close()
|
||||||
infile = codecs.open(filename, u'r', details['encoding'])
|
infile = codecs.open(filename, u'r', details['encoding'])
|
||||||
lines = infile.readlines()
|
lines = infile.readlines()
|
||||||
|
infile.close()
|
||||||
ext = os.path.splitext(filename)[1]
|
ext = os.path.splitext(filename)[1]
|
||||||
if ext.lower() == u'.usr':
|
if ext.lower() == u'.usr':
|
||||||
log.info(u'SongSelect .usr format file found: %s', filename)
|
log.info(u'SongSelect .usr format file found: %s', filename)
|
||||||
self.do_import_usr_file(lines)
|
if not self.do_import_usr_file(lines):
|
||||||
|
self.log_error(filename)
|
||||||
elif ext.lower() == u'.txt':
|
elif ext.lower() == u'.txt':
|
||||||
log.info(u'SongSelect .txt format file found: %s', filename)
|
log.info(u'SongSelect .txt format file found: %s', filename)
|
||||||
self.do_import_txt_file(lines)
|
if not self.do_import_txt_file(lines):
|
||||||
|
self.log_error(filename)
|
||||||
else:
|
else:
|
||||||
|
self.log_error(filename,
|
||||||
|
translate('SongsPlugin.CCLIFileImport',
|
||||||
|
'The file does not have a valid extension.'))
|
||||||
log.info(u'Extension %s is not valid', filename)
|
log.info(u'Extension %s is not valid', filename)
|
||||||
song_count += 1
|
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
return False
|
return
|
||||||
return True
|
|
||||||
|
|
||||||
def do_import_usr_file(self, textList):
|
def do_import_usr_file(self, textList):
|
||||||
"""
|
"""
|
||||||
@ -218,7 +216,7 @@ class CCLIFileImport(SongImport):
|
|||||||
else:
|
else:
|
||||||
self.add_author(author)
|
self.add_author(author)
|
||||||
self.topics = [topic.strip() for topic in song_topics.split(u'/t')]
|
self.topics = [topic.strip() for topic in song_topics.split(u'/t')]
|
||||||
self.finish()
|
return self.finish()
|
||||||
|
|
||||||
def do_import_txt_file(self, textList):
|
def do_import_txt_file(self, textList):
|
||||||
"""
|
"""
|
||||||
@ -334,6 +332,5 @@ class CCLIFileImport(SongImport):
|
|||||||
if len(author_list) < 2:
|
if len(author_list) < 2:
|
||||||
author_list = song_author.split(u'|')
|
author_list = song_author.split(u'|')
|
||||||
# Clean spaces before and after author names.
|
# Clean spaces before and after author names.
|
||||||
for author_name in author_list:
|
[self.add_author(author_name.strip()) for author_name in author_list]
|
||||||
self.add_author(author_name.strip())
|
return self.finish()
|
||||||
self.finish()
|
|
||||||
|
@ -26,11 +26,13 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from lxml import etree, objectify
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from lxml import etree, objectify
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -56,26 +58,16 @@ class EasiSlidesImport(SongImport):
|
|||||||
multiple opensong files. If `self.commit` is set False, the
|
multiple opensong files. If `self.commit` is set False, the
|
||||||
import will not be committed to the database (useful for test scripts).
|
import will not be committed to the database (useful for test scripts).
|
||||||
"""
|
"""
|
||||||
self.import_wizard.progressBar.setMaximum(1)
|
|
||||||
log.info(u'Importing EasiSlides XML file %s', self.import_source)
|
log.info(u'Importing EasiSlides XML file %s', self.import_source)
|
||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
file = etree.parse(self.import_source, parser)
|
file = etree.parse(self.import_source, parser)
|
||||||
xml = unicode(etree.tostring(file))
|
xml = unicode(etree.tostring(file))
|
||||||
song_xml = objectify.fromstring(xml)
|
song_xml = objectify.fromstring(xml)
|
||||||
self.import_wizard.incrementProgressBar(
|
|
||||||
WizardStrings.ImportingType % os.path.split(self.import_source)[-1])
|
|
||||||
self.import_wizard.progressBar.setMaximum(len(song_xml.Item))
|
self.import_wizard.progressBar.setMaximum(len(song_xml.Item))
|
||||||
for song in song_xml.Item:
|
for song in song_xml.Item:
|
||||||
self.import_wizard.incrementProgressBar(
|
if self.stop_import_flag:
|
||||||
unicode(translate('SongsPlugin.ImportWizardForm',
|
return
|
||||||
u'Importing %s, song %s...')) %
|
self._parse_song(song)
|
||||||
(os.path.split(self.import_source)[-1], song.Title1))
|
|
||||||
success = self._parse_song(song)
|
|
||||||
if not success or self.stop_import_flag:
|
|
||||||
return False
|
|
||||||
elif self.commit:
|
|
||||||
self.finish()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _parse_song(self, song):
|
def _parse_song(self, song):
|
||||||
self._success = True
|
self._success = True
|
||||||
@ -90,7 +82,11 @@ class EasiSlidesImport(SongImport):
|
|||||||
self._add_copyright(song.LicenceAdmin2)
|
self._add_copyright(song.LicenceAdmin2)
|
||||||
self._add_unicode_attribute(u'song_book_name', song.BookReference)
|
self._add_unicode_attribute(u'song_book_name', song.BookReference)
|
||||||
self._parse_and_add_lyrics(song)
|
self._parse_and_add_lyrics(song)
|
||||||
return self._success
|
if self._success:
|
||||||
|
if not self.finish():
|
||||||
|
self.log_error(song.Title1 if song.Title1 else u'')
|
||||||
|
else:
|
||||||
|
self.set_defaults()
|
||||||
|
|
||||||
def _add_unicode_attribute(self, self_attribute, import_attribute,
|
def _add_unicode_attribute(self, self_attribute, import_attribute,
|
||||||
mandatory=False):
|
mandatory=False):
|
||||||
@ -122,10 +118,8 @@ class EasiSlidesImport(SongImport):
|
|||||||
def _add_authors(self, song):
|
def _add_authors(self, song):
|
||||||
try:
|
try:
|
||||||
authors = unicode(song.Writer).split(u',')
|
authors = unicode(song.Writer).split(u',')
|
||||||
for author in authors:
|
self.authors = \
|
||||||
author = author.strip()
|
[author.strip() for author in authors if author.strip()]
|
||||||
if len(author):
|
|
||||||
self.authors.append(author)
|
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
log.exception(u'Unicode decode error while decoding Writer')
|
log.exception(u'Unicode decode error while decoding Writer')
|
||||||
self._success = False
|
self._success = False
|
||||||
@ -188,12 +182,13 @@ class EasiSlidesImport(SongImport):
|
|||||||
# if the regions are inside verses
|
# if the regions are inside verses
|
||||||
regionsInVerses = (regions and regionlines[regionlines.keys()[0]] > 1)
|
regionsInVerses = (regions and regionlines[regionlines.keys()[0]] > 1)
|
||||||
MarkTypes = {
|
MarkTypes = {
|
||||||
u'CHORUS': u'C',
|
u'CHORUS': VerseType.Tags[VerseType.Chorus],
|
||||||
u'VERSE': u'V',
|
u'VERSE': VerseType.Tags[VerseType.Verse],
|
||||||
u'INTRO': u'I',
|
u'INTRO': VerseType.Tags[VerseType.Intro],
|
||||||
u'ENDING': u'E',
|
u'ENDING': VerseType.Tags[VerseType.Ending],
|
||||||
u'BRIDGE': u'B',
|
u'BRIDGE': VerseType.Tags[VerseType.Bridge],
|
||||||
u'PRECHORUS': u'P'}
|
u'PRECHORUS': VerseType.Tags[VerseType.PreChorus]
|
||||||
|
}
|
||||||
verses = {}
|
verses = {}
|
||||||
# list as [region, versetype, versenum, instance]
|
# list as [region, versetype, versenum, instance]
|
||||||
our_verse_order = []
|
our_verse_order = []
|
||||||
|
@ -33,6 +33,7 @@ import struct
|
|||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib import retrieve_windows_encoding
|
from openlp.plugins.songs.lib import retrieve_windows_encoding
|
||||||
from songimport import SongImport
|
from songimport import SongImport
|
||||||
|
|
||||||
@ -142,12 +143,12 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
# Open the DB and MB files if they exist
|
# Open the DB and MB files if they exist
|
||||||
import_source_mb = self.import_source.replace('.DB', '.MB')
|
import_source_mb = self.import_source.replace('.DB', '.MB')
|
||||||
if not os.path.isfile(self.import_source):
|
if not os.path.isfile(self.import_source):
|
||||||
return False
|
return
|
||||||
if not os.path.isfile(import_source_mb):
|
if not os.path.isfile(import_source_mb):
|
||||||
return False
|
return
|
||||||
db_size = os.path.getsize(self.import_source)
|
db_size = os.path.getsize(self.import_source)
|
||||||
if db_size < 0x800:
|
if db_size < 0x800:
|
||||||
return False
|
return
|
||||||
db_file = open(self.import_source, 'rb')
|
db_file = open(self.import_source, 'rb')
|
||||||
self.memo_file = open(import_source_mb, 'rb')
|
self.memo_file = open(import_source_mb, 'rb')
|
||||||
# Don't accept files that are clearly not paradox files
|
# Don't accept files that are clearly not paradox files
|
||||||
@ -156,7 +157,7 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
if header_size != 0x800 or block_size < 1 or block_size > 4:
|
if header_size != 0x800 or block_size < 1 or block_size > 4:
|
||||||
db_file.close()
|
db_file.close()
|
||||||
self.memo_file.close()
|
self.memo_file.close()
|
||||||
return False
|
return
|
||||||
# Take a stab at how text is encoded
|
# Take a stab at how text is encoded
|
||||||
self.encoding = u'cp1252'
|
self.encoding = u'cp1252'
|
||||||
db_file.seek(106)
|
db_file.seek(106)
|
||||||
@ -183,7 +184,7 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
self.encoding = u'cp874'
|
self.encoding = u'cp874'
|
||||||
self.encoding = retrieve_windows_encoding(self.encoding)
|
self.encoding = retrieve_windows_encoding(self.encoding)
|
||||||
if not self.encoding:
|
if not self.encoding:
|
||||||
return False
|
return
|
||||||
# There does not appear to be a _reliable_ way of getting the number
|
# There does not appear to be a _reliable_ way of getting the number
|
||||||
# of songs/records, so let's use file blocks for measuring progress.
|
# of songs/records, so let's use file blocks for measuring progress.
|
||||||
total_blocks = (db_size - header_size) / (block_size * 1024)
|
total_blocks = (db_size - header_size) / (block_size * 1024)
|
||||||
@ -203,8 +204,8 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
field_size))
|
field_size))
|
||||||
self.set_record_struct(field_descs)
|
self.set_record_struct(field_descs)
|
||||||
# Pick out the field description indexes we will need
|
# Pick out the field description indexes we will need
|
||||||
success = True
|
|
||||||
try:
|
try:
|
||||||
|
success = True
|
||||||
fi_title = self.find_field(u'Title')
|
fi_title = self.find_field(u'Title')
|
||||||
fi_author = self.find_field(u'Author')
|
fi_author = self.find_field(u'Author')
|
||||||
fi_copy = self.find_field(u'Copyright')
|
fi_copy = self.find_field(u'Copyright')
|
||||||
@ -223,31 +224,25 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
# Loop through each record within the current block
|
# Loop through each record within the current block
|
||||||
for i in range(rec_count):
|
for i in range(rec_count):
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
success = False
|
|
||||||
break
|
break
|
||||||
raw_record = db_file.read(record_size)
|
raw_record = db_file.read(record_size)
|
||||||
self.fields = self.record_struct.unpack(raw_record)
|
self.fields = self.record_struct.unpack(raw_record)
|
||||||
self.set_defaults()
|
self.set_defaults()
|
||||||
# Get title and update progress bar message
|
self.title = self.get_field(fi_title)
|
||||||
title = self.get_field(fi_title)
|
# Get remaining fields.
|
||||||
if title:
|
|
||||||
self.import_wizard.incrementProgressBar(
|
|
||||||
WizardStrings.ImportingType % title, 0)
|
|
||||||
self.title = title
|
|
||||||
# Get remaining fields
|
|
||||||
copy = self.get_field(fi_copy)
|
copy = self.get_field(fi_copy)
|
||||||
admin = self.get_field(fi_admin)
|
admin = self.get_field(fi_admin)
|
||||||
ccli = self.get_field(fi_ccli)
|
ccli = self.get_field(fi_ccli)
|
||||||
authors = self.get_field(fi_author)
|
authors = self.get_field(fi_author)
|
||||||
words = self.get_field(fi_words)
|
words = self.get_field(fi_words)
|
||||||
# Set the SongImport object members
|
# Set the SongImport object members.
|
||||||
if copy:
|
if copy:
|
||||||
self.copyright = copy
|
self.copyright = copy
|
||||||
if admin:
|
if admin:
|
||||||
if copy:
|
if copy:
|
||||||
self.copyright += u', '
|
self.copyright += u', '
|
||||||
self.copyright += \
|
self.copyright += \
|
||||||
unicode(translate('SongsPlugin.ImportWizardForm',
|
unicode(translate('SongsPlugin.EasyWorshipSongImport',
|
||||||
'Administered by %s')) % admin
|
'Administered by %s')) % admin
|
||||||
if ccli:
|
if ccli:
|
||||||
self.ccli_number = ccli
|
self.ccli_number = ccli
|
||||||
@ -264,19 +259,17 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
# Format the lyrics
|
# Format the lyrics
|
||||||
words = strip_rtf(words, self.encoding)
|
words = strip_rtf(words, self.encoding)
|
||||||
for verse in words.split(u'\n\n'):
|
for verse in words.split(u'\n\n'):
|
||||||
self.add_verse(verse.strip(), u'V')
|
self.add_verse(
|
||||||
|
verse.strip(), VerseType.Tags[VerseType.Verse])
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
success = False
|
|
||||||
break
|
break
|
||||||
self.finish()
|
if not self.finish():
|
||||||
if not self.stop_import_flag:
|
self.log_error(self.import_source)
|
||||||
self.import_wizard.incrementProgressBar(u'')
|
|
||||||
db_file.close()
|
db_file.close()
|
||||||
self.memo_file.close()
|
self.memo_file.close()
|
||||||
return success
|
|
||||||
|
|
||||||
def find_field(self, field_name):
|
def find_field(self, field_name):
|
||||||
return [i for i, x in enumerate(self.field_descs) \
|
return [i for i, x in enumerate(self.field_descs)
|
||||||
if x.name == field_name][0]
|
if x.name == field_name][0]
|
||||||
|
|
||||||
def set_record_struct(self, field_descs):
|
def set_record_struct(self, field_descs):
|
||||||
|
@ -97,6 +97,7 @@ from openlp.core.ui.wizard import WizardStrings
|
|||||||
from openlp.plugins.songs.lib import clean_song, VerseType
|
from openlp.plugins.songs.lib import clean_song, VerseType
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic
|
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic
|
||||||
|
from openlp.plugins.songs.lib.ui import SongStrings
|
||||||
from openlp.plugins.songs.lib.xml import SongXML
|
from openlp.plugins.songs.lib.xml import SongXML
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -121,17 +122,16 @@ class FoilPresenterImport(SongImport):
|
|||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
for file_path in self.import_source:
|
for file_path in self.import_source:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
return False
|
return
|
||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % os.path.basename(file_path))
|
WizardStrings.ImportingType % os.path.basename(file_path))
|
||||||
try:
|
try:
|
||||||
parsed_file = etree.parse(file_path, parser)
|
parsed_file = etree.parse(file_path, parser)
|
||||||
xml = unicode(etree.tostring(parsed_file))
|
xml = unicode(etree.tostring(parsed_file))
|
||||||
if self.FoilPresenter.xml_to_song(xml) is None:
|
self.FoilPresenter.xml_to_song(xml)
|
||||||
log.debug(u'File could not be imported: %s' % file_path)
|
|
||||||
except etree.XMLSyntaxError:
|
except etree.XMLSyntaxError:
|
||||||
|
self.log_error(file_path, SongStrings.XMLSyntaxError)
|
||||||
log.exception(u'XML syntax error in file %s' % file_path)
|
log.exception(u'XML syntax error in file %s' % file_path)
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class FoilPresenter(object):
|
class FoilPresenter(object):
|
||||||
@ -211,7 +211,7 @@ class FoilPresenter(object):
|
|||||||
"""
|
"""
|
||||||
# No xml get out of here.
|
# No xml get out of here.
|
||||||
if not xml:
|
if not xml:
|
||||||
return None
|
return
|
||||||
if xml[:5] == u'<?xml':
|
if xml[:5] == u'<?xml':
|
||||||
xml = xml[38:]
|
xml = xml[38:]
|
||||||
song = Song()
|
song = Song()
|
||||||
@ -235,7 +235,6 @@ class FoilPresenter(object):
|
|||||||
self._process_topics(foilpresenterfolie, song)
|
self._process_topics(foilpresenterfolie, song)
|
||||||
clean_song(self.manager, song)
|
clean_song(self.manager, song)
|
||||||
self.manager.save_object(song)
|
self.manager.save_object(song)
|
||||||
return song.id
|
|
||||||
|
|
||||||
def _child(self, element):
|
def _child(self, element):
|
||||||
"""
|
"""
|
||||||
@ -305,9 +304,8 @@ class FoilPresenter(object):
|
|||||||
for marker in markers:
|
for marker in markers:
|
||||||
copyright = re.compile(marker).sub(u'<marker>', copyright, re.U)
|
copyright = re.compile(marker).sub(u'<marker>', copyright, re.U)
|
||||||
copyright = re.compile(u'(?<=<marker>) *:').sub(u'', copyright)
|
copyright = re.compile(u'(?<=<marker>) *:').sub(u'', copyright)
|
||||||
i = 0
|
|
||||||
x = 0
|
x = 0
|
||||||
while i != 1:
|
while True:
|
||||||
if copyright.find(u'<marker>') != -1:
|
if copyright.find(u'<marker>') != -1:
|
||||||
temp = copyright.partition(u'<marker>')
|
temp = copyright.partition(u'<marker>')
|
||||||
if temp[0].strip() and x > 0:
|
if temp[0].strip() and x > 0:
|
||||||
@ -316,9 +314,9 @@ class FoilPresenter(object):
|
|||||||
x += 1
|
x += 1
|
||||||
elif x > 0:
|
elif x > 0:
|
||||||
strings.append(copyright)
|
strings.append(copyright)
|
||||||
i = 1
|
break
|
||||||
else:
|
else:
|
||||||
i = 1
|
break
|
||||||
author_temp = []
|
author_temp = []
|
||||||
for author in strings:
|
for author in strings:
|
||||||
temp = re.split(u',(?=\D{2})|(?<=\D),|\/(?=\D{3,})|(?<=\D);',
|
temp = re.split(u',(?=\D{2})|(?<=\D),|\/(?=\D{3,})|(?<=\D);',
|
||||||
@ -349,8 +347,8 @@ class FoilPresenter(object):
|
|||||||
if author is None:
|
if author is None:
|
||||||
# We need to create a new author, as the author does not exist.
|
# We need to create a new author, as the author does not exist.
|
||||||
author = Author.populate(display_name=display_name,
|
author = Author.populate(display_name=display_name,
|
||||||
last_name = display_name.split(u' ')[-1],
|
last_name=display_name.split(u' ')[-1],
|
||||||
first_name = u' '.join(display_name.split(u' ')[:-1]))
|
first_name=u' '.join(display_name.split(u' ')[:-1]))
|
||||||
self.manager.save_object(author)
|
self.manager.save_object(author)
|
||||||
song.authors.append(author)
|
song.authors.append(author)
|
||||||
|
|
||||||
@ -414,8 +412,15 @@ class FoilPresenter(object):
|
|||||||
temp_verse_order_backup = []
|
temp_verse_order_backup = []
|
||||||
temp_sortnr_backup = 1
|
temp_sortnr_backup = 1
|
||||||
temp_sortnr_liste = []
|
temp_sortnr_liste = []
|
||||||
versenumber = {u'V': 1, u'C': 1, u'B': 1, u'E': 1, u'O': 1, u'I': 1,
|
versenumber = {
|
||||||
u'P': 1}
|
VerseType.Tags[VerseType.Verse]: 1,
|
||||||
|
VerseType.Tags[VerseType.Chorus]: 1,
|
||||||
|
VerseType.Tags[VerseType.Bridge]: 1,
|
||||||
|
VerseType.Tags[VerseType.Ending]: 1,
|
||||||
|
VerseType.Tags[VerseType.Other]: 1,
|
||||||
|
VerseType.Tags[VerseType.Intro]: 1,
|
||||||
|
VerseType.Tags[VerseType.PreChorus]: 1
|
||||||
|
}
|
||||||
for strophe in foilpresenterfolie.strophen.strophe:
|
for strophe in foilpresenterfolie.strophen.strophe:
|
||||||
text = self._child(strophe.text_)
|
text = self._child(strophe.text_)
|
||||||
verse_name = self._child(strophe.key)
|
verse_name = self._child(strophe.key)
|
||||||
@ -434,25 +439,25 @@ class FoilPresenter(object):
|
|||||||
temp_verse_name = re.compile(u'[0-9].*').sub(u'', verse_name)
|
temp_verse_name = re.compile(u'[0-9].*').sub(u'', verse_name)
|
||||||
temp_verse_name = temp_verse_name[:3].lower()
|
temp_verse_name = temp_verse_name[:3].lower()
|
||||||
if temp_verse_name == u'ref':
|
if temp_verse_name == u'ref':
|
||||||
verse_type = u'C'
|
verse_type = VerseType.Tags[VerseType.Chorus]
|
||||||
elif temp_verse_name == u'r':
|
elif temp_verse_name == u'r':
|
||||||
verse_type = u'C'
|
verse_type = VerseType.Tags[VerseType.Chorus]
|
||||||
elif temp_verse_name == u'':
|
elif temp_verse_name == u'':
|
||||||
verse_type = u'V'
|
verse_type = VerseType.Tags[VerseType.Verse]
|
||||||
elif temp_verse_name == u'v':
|
elif temp_verse_name == u'v':
|
||||||
verse_type = u'V'
|
verse_type = VerseType.Tags[VerseType.Verse]
|
||||||
elif temp_verse_name == u'bri':
|
elif temp_verse_name == u'bri':
|
||||||
verse_type = u'B'
|
verse_type = VerseType.Tags[VerseType.Bridge]
|
||||||
elif temp_verse_name == u'cod':
|
elif temp_verse_name == u'cod':
|
||||||
verse_type = u'E'
|
verse_type = VerseType.Tags[VerseType.Ending]
|
||||||
elif temp_verse_name == u'sch':
|
elif temp_verse_name == u'sch':
|
||||||
verse_type = u'E'
|
verse_type = VerseType.Tags[VerseType.Ending]
|
||||||
elif temp_verse_name == u'pre':
|
elif temp_verse_name == u'pre':
|
||||||
verse_type = u'P'
|
verse_type = VerseType.Tags[VerseType.PreChorus]
|
||||||
elif temp_verse_name == u'int':
|
elif temp_verse_name == u'int':
|
||||||
verse_type = u'I'
|
verse_type = VerseType.Tags[VerseType.Intro]
|
||||||
else:
|
else:
|
||||||
verse_type = u'O'
|
verse_type = VerseType.Tags[VerseType.Other]
|
||||||
verse_number = re.compile(u'[a-zA-Z.+-_ ]*').sub(u'', verse_name)
|
verse_number = re.compile(u'[a-zA-Z.+-_ ]*').sub(u'', verse_name)
|
||||||
# Foilpresenter allows e. g. "C", but we need "C1".
|
# Foilpresenter allows e. g. "C", but we need "C1".
|
||||||
if not verse_number:
|
if not verse_number:
|
||||||
@ -466,8 +471,8 @@ class FoilPresenter(object):
|
|||||||
verse_number = unicode(int(verse_number) + 1)
|
verse_number = unicode(int(verse_number) + 1)
|
||||||
verse_type_index = VerseType.from_tag(verse_type[0])
|
verse_type_index = VerseType.from_tag(verse_type[0])
|
||||||
verse_type = VerseType.Names[verse_type_index]
|
verse_type = VerseType.Names[verse_type_index]
|
||||||
temp_verse_order[verse_sortnr] = (u''.join((verse_type[0],
|
temp_verse_order[verse_sortnr] = u''.join((verse_type[0],
|
||||||
verse_number)))
|
verse_number))
|
||||||
temp_verse_order_backup.append(u''.join((verse_type[0],
|
temp_verse_order_backup.append(u''.join((verse_type[0],
|
||||||
verse_number)))
|
verse_number)))
|
||||||
sxml.add_verse_to_lyrics(verse_type, verse_number, text)
|
sxml.add_verse_to_lyrics(verse_type, verse_number, text)
|
||||||
|
@ -137,8 +137,8 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
QtCore.QVariant(u'True')).toBool()
|
QtCore.QVariant(u'True')).toBool()
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.searchTextLabel.setText(u'%s:' % UiStrings.Search)
|
self.searchTextLabel.setText(u'%s:' % UiStrings().Search)
|
||||||
self.searchTextButton.setText(UiStrings.Search)
|
self.searchTextButton.setText(UiStrings().Search)
|
||||||
self.maintenanceAction.setText(SongStrings.SongMaintenance)
|
self.maintenanceAction.setText(SongStrings.SongMaintenance)
|
||||||
self.maintenanceAction.setToolTip(translate('SongsPlugin.MediaItem',
|
self.maintenanceAction.setToolTip(translate('SongsPlugin.MediaItem',
|
||||||
'Maintain the lists of authors, topics and books'))
|
'Maintain the lists of authors, topics and books'))
|
||||||
@ -153,7 +153,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
translate('SongsPlugin.MediaItem', 'Lyrics')),
|
translate('SongsPlugin.MediaItem', 'Lyrics')),
|
||||||
(SongSearch.Authors, u':/songs/song_search_author.png',
|
(SongSearch.Authors, u':/songs/song_search_author.png',
|
||||||
SongStrings.Authors),
|
SongStrings.Authors),
|
||||||
(SongSearch.Themes, u':/slides/slide_theme.png', UiStrings.Themes)
|
(SongSearch.Themes, u':/slides/slide_theme.png', UiStrings().Themes)
|
||||||
])
|
])
|
||||||
self.searchTextEdit.setCurrentSearchType(QtCore.QSettings().value(
|
self.searchTextEdit.setCurrentSearchType(QtCore.QSettings().value(
|
||||||
u'%s/last search type' % self.settingsSection,
|
u'%s/last search type' % self.settingsSection,
|
||||||
@ -312,7 +312,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
Edit a song
|
Edit a song
|
||||||
"""
|
"""
|
||||||
log.debug(u'onEditClick')
|
log.debug(u'onEditClick')
|
||||||
if check_item_selected(self.listView, UiStrings.SelectEdit):
|
if check_item_selected(self.listView, UiStrings().SelectEdit):
|
||||||
self.editItem = self.listView.currentItem()
|
self.editItem = self.listView.currentItem()
|
||||||
item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0]
|
item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||||
self.edit_song_form.loadSong(item_id, False)
|
self.edit_song_form.loadSong(item_id, False)
|
||||||
@ -323,7 +323,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
"""
|
"""
|
||||||
Remove a song from the list and database
|
Remove a song from the list and database
|
||||||
"""
|
"""
|
||||||
if check_item_selected(self.listView, UiStrings.SelectDelete):
|
if check_item_selected(self.listView, UiStrings().SelectDelete):
|
||||||
items = self.listView.selectedIndexes()
|
items = self.listView.selectedIndexes()
|
||||||
if QtGui.QMessageBox.question(self,
|
if QtGui.QMessageBox.question(self,
|
||||||
translate('SongsPlugin.MediaItem', 'Delete Song(s)?'),
|
translate('SongsPlugin.MediaItem', 'Delete Song(s)?'),
|
||||||
@ -347,6 +347,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
service_item.add_capability(ItemCapabilities.AllowsLoop)
|
||||||
service_item.add_capability(ItemCapabilities.OnLoadUpdate)
|
service_item.add_capability(ItemCapabilities.OnLoadUpdate)
|
||||||
service_item.add_capability(ItemCapabilities.AddIfNewItem)
|
service_item.add_capability(ItemCapabilities.AddIfNewItem)
|
||||||
|
service_item.add_capability(ItemCapabilities.AllowsVirtualSplit)
|
||||||
song = self.parent.manager.get_object(Song, item_id)
|
song = self.parent.manager.get_object(Song, item_id)
|
||||||
service_item.theme = song.theme_name
|
service_item.theme = song.theme_name
|
||||||
service_item.edit_id = item_id
|
service_item.edit_id = item_id
|
||||||
@ -472,4 +473,4 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
Locale aware collation of song titles
|
Locale aware collation of song titles
|
||||||
"""
|
"""
|
||||||
return locale.strcoll(unicode(song_1.title.lower()),
|
return locale.strcoll(unicode(song_1.title.lower()),
|
||||||
unicode(song_2.title.lower()))
|
unicode(song_2.title.lower()))
|
@ -32,7 +32,7 @@ import logging
|
|||||||
from chardet.universaldetector import UniversalDetector
|
from chardet.universaldetector import UniversalDetector
|
||||||
import sqlite
|
import sqlite
|
||||||
|
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.core.lib import translate
|
||||||
from openlp.plugins.songs.lib import retrieve_windows_encoding
|
from openlp.plugins.songs.lib import retrieve_windows_encoding
|
||||||
from songimport import SongImport
|
from songimport import SongImport
|
||||||
|
|
||||||
@ -61,10 +61,15 @@ class OpenLP1SongImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
Run the import for an openlp.org 1.x song database.
|
Run the import for an openlp.org 1.x song database.
|
||||||
"""
|
"""
|
||||||
# Connect to the database
|
if not self.import_source.endswith(u'.olp'):
|
||||||
|
self.log_error(self.import_source,
|
||||||
|
translate('SongsPlugin.OpenLP1SongImport',
|
||||||
|
'Not a valid openlp.org 1.x song database.'))
|
||||||
|
return
|
||||||
encoding = self.get_encoding()
|
encoding = self.get_encoding()
|
||||||
if not encoding:
|
if not encoding:
|
||||||
return False
|
return
|
||||||
|
# Connect to the database
|
||||||
connection = sqlite.connect(self.import_source, mode=0444,
|
connection = sqlite.connect(self.import_source, mode=0444,
|
||||||
encoding=(encoding, 'replace'))
|
encoding=(encoding, 'replace'))
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
@ -72,12 +77,6 @@ class OpenLP1SongImport(SongImport):
|
|||||||
cursor.execute(u'SELECT name FROM sqlite_master '
|
cursor.execute(u'SELECT name FROM sqlite_master '
|
||||||
u'WHERE type = \'table\' AND name = \'tracks\'')
|
u'WHERE type = \'table\' AND name = \'tracks\'')
|
||||||
new_db = len(cursor.fetchall()) > 0
|
new_db = len(cursor.fetchall()) > 0
|
||||||
# Count the number of records we need to import, for the progress bar
|
|
||||||
cursor.execute(u'-- types int')
|
|
||||||
cursor.execute(u'SELECT COUNT(songid) FROM songs')
|
|
||||||
count = cursor.fetchone()[0]
|
|
||||||
success = True
|
|
||||||
self.import_wizard.progressBar.setMaximum(count)
|
|
||||||
# "cache" our list of authors
|
# "cache" our list of authors
|
||||||
cursor.execute(u'-- types int, unicode')
|
cursor.execute(u'-- types int, unicode')
|
||||||
cursor.execute(u'SELECT authorid, authorname FROM authors')
|
cursor.execute(u'SELECT authorid, authorname FROM authors')
|
||||||
@ -92,37 +91,29 @@ class OpenLP1SongImport(SongImport):
|
|||||||
cursor.execute(u'SELECT songid, songtitle, lyrics || \'\' AS lyrics, '
|
cursor.execute(u'SELECT songid, songtitle, lyrics || \'\' AS lyrics, '
|
||||||
u'copyrightinfo FROM songs')
|
u'copyrightinfo FROM songs')
|
||||||
songs = cursor.fetchall()
|
songs = cursor.fetchall()
|
||||||
|
self.import_wizard.progressBar.setMaximum(len(songs))
|
||||||
for song in songs:
|
for song in songs:
|
||||||
self.set_defaults()
|
self.set_defaults()
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
success = False
|
|
||||||
break
|
break
|
||||||
song_id = song[0]
|
song_id = song[0]
|
||||||
title = song[1]
|
self.title = song[1]
|
||||||
lyrics = song[2].replace(u'\r\n', u'\n')
|
lyrics = song[2].replace(u'\r\n', u'\n')
|
||||||
copyright = song[3]
|
self.add_copyright(song[3])
|
||||||
self.import_wizard.incrementProgressBar(
|
|
||||||
WizardStrings.ImportingType % title)
|
|
||||||
self.title = title
|
|
||||||
verses = lyrics.split(u'\n\n')
|
verses = lyrics.split(u'\n\n')
|
||||||
for verse in verses:
|
[self.add_verse(verse.strip()) for verse in verses if verse.strip()]
|
||||||
if verse.strip() != u'':
|
|
||||||
self.add_verse(verse.strip())
|
|
||||||
self.add_copyright(copyright)
|
|
||||||
cursor.execute(u'-- types int')
|
cursor.execute(u'-- types int')
|
||||||
cursor.execute(u'SELECT authorid FROM songauthors '
|
cursor.execute(u'SELECT authorid FROM songauthors '
|
||||||
u'WHERE songid = %s' % song_id)
|
u'WHERE songid = %s' % song_id)
|
||||||
author_ids = cursor.fetchall()
|
author_ids = cursor.fetchall()
|
||||||
for author_id in author_ids:
|
for author_id in author_ids:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
success = False
|
|
||||||
break
|
break
|
||||||
for author in authors:
|
for author in authors:
|
||||||
if author[0] == author_id[0]:
|
if author[0] == author_id[0]:
|
||||||
self.parse_author(author[1])
|
self.parse_author(author[1])
|
||||||
break
|
break
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
success = False
|
|
||||||
break
|
break
|
||||||
if new_db:
|
if new_db:
|
||||||
cursor.execute(u'-- types int')
|
cursor.execute(u'-- types int')
|
||||||
@ -131,17 +122,15 @@ class OpenLP1SongImport(SongImport):
|
|||||||
track_ids = cursor.fetchall()
|
track_ids = cursor.fetchall()
|
||||||
for track_id in track_ids:
|
for track_id in track_ids:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
success = False
|
|
||||||
break
|
break
|
||||||
for track in tracks:
|
for track in tracks:
|
||||||
if track[0] == track_id[0]:
|
if track[0] == track_id[0]:
|
||||||
self.add_media_file(track[1])
|
self.add_media_file(track[1])
|
||||||
break
|
break
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
success = False
|
|
||||||
break
|
break
|
||||||
self.finish()
|
if not self.finish():
|
||||||
return success
|
self.log_error(self.import_source)
|
||||||
|
|
||||||
def get_encoding(self):
|
def get_encoding(self):
|
||||||
"""
|
"""
|
||||||
|
@ -36,6 +36,7 @@ from sqlalchemy.orm.exc import UnmappedClassError
|
|||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.core.lib.db import BaseModel
|
from openlp.core.lib.db import BaseModel
|
||||||
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
from openlp.plugins.songs.lib import clean_song
|
from openlp.plugins.songs.lib import clean_song
|
||||||
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic #, MediaFile
|
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic #, MediaFile
|
||||||
from songimport import SongImport
|
from songimport import SongImport
|
||||||
@ -93,13 +94,18 @@ class OpenLPSongImport(SongImport):
|
|||||||
The database providing the data to import.
|
The database providing the data to import.
|
||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
self.import_source = u'sqlite:///%s' % self.import_source
|
|
||||||
self.source_session = None
|
self.source_session = None
|
||||||
|
|
||||||
def do_import(self):
|
def do_import(self):
|
||||||
"""
|
"""
|
||||||
Run the import for an OpenLP version 2 song database.
|
Run the import for an OpenLP version 2 song database.
|
||||||
"""
|
"""
|
||||||
|
if not self.import_source.endswith(u'.sqlite'):
|
||||||
|
self.log_error(self.import_source,
|
||||||
|
translate('SongsPlugin.OpenLPSongImport',
|
||||||
|
'Not a valid OpenLP 2.0 song database.'))
|
||||||
|
return
|
||||||
|
self.import_source = u'sqlite:///%s' % self.import_source
|
||||||
engine = create_engine(self.import_source)
|
engine = create_engine(self.import_source)
|
||||||
source_meta = MetaData()
|
source_meta = MetaData()
|
||||||
source_meta.reflect(engine)
|
source_meta.reflect(engine)
|
||||||
@ -124,10 +130,10 @@ class OpenLPSongImport(SongImport):
|
|||||||
mapper(OldMediaFile, source_media_files_table)
|
mapper(OldMediaFile, source_media_files_table)
|
||||||
song_props = {
|
song_props = {
|
||||||
'authors': relation(OldAuthor, backref='songs',
|
'authors': relation(OldAuthor, backref='songs',
|
||||||
secondary=source_authors_songs_table),
|
secondary=source_authors_songs_table),
|
||||||
'book': relation(OldBook, backref='songs'),
|
'book': relation(OldBook, backref='songs'),
|
||||||
'topics': relation(OldTopic, backref='songs',
|
'topics': relation(OldTopic, backref='songs',
|
||||||
secondary=source_songs_topics_table)
|
secondary=source_songs_topics_table)
|
||||||
}
|
}
|
||||||
if has_media_files:
|
if has_media_files:
|
||||||
song_props['media_files'] = relation(OldMediaFile, backref='songs',
|
song_props['media_files'] = relation(OldMediaFile, backref='songs',
|
||||||
@ -150,15 +156,9 @@ class OpenLPSongImport(SongImport):
|
|||||||
mapper(OldTopic, source_topics_table)
|
mapper(OldTopic, source_topics_table)
|
||||||
|
|
||||||
source_songs = self.source_session.query(OldSong).all()
|
source_songs = self.source_session.query(OldSong).all()
|
||||||
song_total = len(source_songs)
|
|
||||||
if self.import_wizard:
|
if self.import_wizard:
|
||||||
self.import_wizard.progressBar.setMaximum(song_total)
|
self.import_wizard.progressBar.setMaximum(len(source_songs))
|
||||||
song_count = 1
|
|
||||||
for song in source_songs:
|
for song in source_songs:
|
||||||
if self.import_wizard:
|
|
||||||
self.import_wizard.incrementProgressBar(
|
|
||||||
unicode(translate('SongsPlugin.OpenLPSongImport',
|
|
||||||
'Importing song %d of %d.')) % (song_count, song_total))
|
|
||||||
new_song = Song()
|
new_song = Song()
|
||||||
new_song.title = song.title
|
new_song.title = song.title
|
||||||
if has_media_files and hasattr(song, 'alternate_title'):
|
if has_media_files and hasattr(song, 'alternate_title'):
|
||||||
@ -213,8 +213,9 @@ class OpenLPSongImport(SongImport):
|
|||||||
# file_name=media_file.file_name))
|
# file_name=media_file.file_name))
|
||||||
clean_song(self.manager, new_song)
|
clean_song(self.manager, new_song)
|
||||||
self.manager.save_object(new_song)
|
self.manager.save_object(new_song)
|
||||||
song_count += 1
|
if self.import_wizard:
|
||||||
|
self.import_wizard.incrementProgressBar(
|
||||||
|
WizardStrings.ImportingType % new_song.title)
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
return False
|
break
|
||||||
engine.dispose()
|
engine.dispose()
|
||||||
return True
|
|
||||||
|
@ -56,13 +56,11 @@ class OooImport(SongImport):
|
|||||||
self.process_started = False
|
self.process_started = False
|
||||||
|
|
||||||
def do_import(self):
|
def do_import(self):
|
||||||
self.stop_import_flag = False
|
|
||||||
self.import_wizard.progressBar.setMaximum(0)
|
|
||||||
self.start_ooo()
|
self.start_ooo()
|
||||||
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
for filename in self.import_source:
|
for filename in self.import_source:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
|
break
|
||||||
return
|
|
||||||
filename = unicode(filename)
|
filename = unicode(filename)
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
self.open_ooo_file(filename)
|
self.open_ooo_file(filename)
|
||||||
@ -70,9 +68,6 @@ class OooImport(SongImport):
|
|||||||
self.process_ooo_document()
|
self.process_ooo_document()
|
||||||
self.close_ooo_file()
|
self.close_ooo_file()
|
||||||
self.close_ooo()
|
self.close_ooo()
|
||||||
self.import_wizard.progressBar.setMaximum(1)
|
|
||||||
self.import_wizard.incrementProgressBar(u'', 1)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def process_ooo_document(self):
|
def process_ooo_document(self):
|
||||||
"""
|
"""
|
||||||
|
@ -35,6 +35,7 @@ from lxml import etree
|
|||||||
|
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
from openlp.plugins.songs.lib.ui import SongStrings
|
||||||
from openlp.plugins.songs.lib import OpenLyrics
|
from openlp.plugins.songs.lib import OpenLyrics
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -59,7 +60,7 @@ class OpenLyricsImport(SongImport):
|
|||||||
parser = etree.XMLParser(remove_blank_text=True)
|
parser = etree.XMLParser(remove_blank_text=True)
|
||||||
for file_path in self.import_source:
|
for file_path in self.import_source:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
return False
|
return
|
||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % os.path.basename(file_path))
|
WizardStrings.ImportingType % os.path.basename(file_path))
|
||||||
try:
|
try:
|
||||||
@ -67,8 +68,7 @@ class OpenLyricsImport(SongImport):
|
|||||||
# special characters in the path (see lp:757673 and lp:744337).
|
# special characters in the path (see lp:757673 and lp:744337).
|
||||||
parsed_file = etree.parse(open(file_path, u'r'), parser)
|
parsed_file = etree.parse(open(file_path, u'r'), parser)
|
||||||
xml = unicode(etree.tostring(parsed_file))
|
xml = unicode(etree.tostring(parsed_file))
|
||||||
if self.openLyrics.xml_to_song(xml) is None:
|
self.openLyrics.xml_to_song(xml)
|
||||||
log.debug(u'File could not be imported: %s' % file_path)
|
|
||||||
except etree.XMLSyntaxError:
|
except etree.XMLSyntaxError:
|
||||||
log.exception(u'XML syntax error in file %s' % file_path)
|
log.exception(u'XML syntax error in file %s' % file_path)
|
||||||
return True
|
self.log_error(file_path, SongStrings.XMLSyntaxError)
|
||||||
|
@ -26,13 +26,15 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
from lxml import objectify
|
from lxml import objectify
|
||||||
from lxml.etree import Error, LxmlError
|
from lxml.etree import Error, LxmlError
|
||||||
import re
|
|
||||||
|
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
from openlp.plugins.songs.lib.ui import SongStrings
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -105,77 +107,62 @@ class OpenSongImport(SongImport):
|
|||||||
Initialise the class.
|
Initialise the class.
|
||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
self.commit = True
|
|
||||||
|
|
||||||
def do_import(self):
|
def do_import(self):
|
||||||
"""
|
"""
|
||||||
Import either each of the files in self.import_source - each element of
|
Import either each of the files in self.import_source - each element of
|
||||||
which can be either a single opensong file, or a zipfile containing
|
which can be either a single opensong file, or a zipfile containing
|
||||||
multiple opensong files. If `self.commit` is set False, the
|
multiple opensong files.
|
||||||
import will not be committed to the database (useful for test scripts).
|
|
||||||
"""
|
"""
|
||||||
success = True
|
|
||||||
numfiles = 0
|
numfiles = 0
|
||||||
for filename in self.import_source:
|
for filename in self.import_source:
|
||||||
ext = os.path.splitext(filename)[1]
|
ext = os.path.splitext(filename)[1]
|
||||||
if ext.lower() == u'.zip':
|
if ext.lower() == u'.zip':
|
||||||
z = ZipFile(filename, u'r')
|
z = ZipFile(filename, u'r')
|
||||||
numfiles += len(z.infolist())
|
numfiles += len(z.infolist())
|
||||||
|
z.close()
|
||||||
else:
|
else:
|
||||||
numfiles += 1
|
numfiles += 1
|
||||||
log.debug(u'Total number of files: %d', numfiles)
|
log.debug(u'Total number of files: %d', numfiles)
|
||||||
self.import_wizard.progressBar.setMaximum(numfiles)
|
self.import_wizard.progressBar.setMaximum(numfiles)
|
||||||
for filename in self.import_source:
|
for filename in self.import_source:
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
success = False
|
return
|
||||||
break
|
|
||||||
ext = os.path.splitext(filename)[1]
|
ext = os.path.splitext(filename)[1]
|
||||||
if ext.lower() == u'.zip':
|
if ext.lower() == u'.zip':
|
||||||
log.debug(u'Zipfile found %s', filename)
|
log.debug(u'Zipfile found %s', filename)
|
||||||
z = ZipFile(filename, u'r')
|
z = ZipFile(filename, u'r')
|
||||||
for song in z.infolist():
|
for song in z.infolist():
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
success = False
|
z.close()
|
||||||
break
|
return
|
||||||
parts = os.path.split(song.filename)
|
parts = os.path.split(song.filename)
|
||||||
if parts[-1] == u'':
|
if parts[-1] == u'':
|
||||||
#No final part => directory
|
# No final part => directory
|
||||||
continue
|
continue
|
||||||
log.info(u'Zip importing %s', parts[-1])
|
log.info(u'Zip importing %s', parts[-1])
|
||||||
self.import_wizard.incrementProgressBar(
|
song_file = z.open(song)
|
||||||
WizardStrings.ImportingType % parts[-1])
|
self.do_import_file(song_file)
|
||||||
songfile = z.open(song)
|
song_file.close()
|
||||||
if self.do_import_file(songfile) and self.commit and \
|
z.close()
|
||||||
not self.stop_import_flag:
|
|
||||||
self.finish()
|
|
||||||
else:
|
|
||||||
success = False
|
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
# not a zipfile
|
# not a zipfile
|
||||||
log.info(u'Direct import %s', filename)
|
log.info(u'Direct import %s', filename)
|
||||||
self.import_wizard.incrementProgressBar(
|
|
||||||
WizardStrings.ImportingType % os.path.split(filename)[-1])
|
|
||||||
song_file = open(filename)
|
song_file = open(filename)
|
||||||
if self.do_import_file(song_file) and self.commit and \
|
self.do_import_file(song_file)
|
||||||
not self.stop_import_flag:
|
song_file.close()
|
||||||
self.finish()
|
|
||||||
else:
|
|
||||||
success = False
|
|
||||||
break
|
|
||||||
return success
|
|
||||||
|
|
||||||
def do_import_file(self, file):
|
def do_import_file(self, file):
|
||||||
"""
|
"""
|
||||||
Process the OpenSong file - pass in a file-like object,
|
Process the OpenSong file - pass in a file-like object, not a file path.
|
||||||
not a filename
|
|
||||||
"""
|
"""
|
||||||
self.set_defaults()
|
self.set_defaults()
|
||||||
try:
|
try:
|
||||||
tree = objectify.parse(file)
|
tree = objectify.parse(file)
|
||||||
except (Error, LxmlError):
|
except (Error, LxmlError):
|
||||||
|
self.log_error(file.name, SongStrings.XMLSyntaxError)
|
||||||
log.exception(u'Error parsing XML')
|
log.exception(u'Error parsing XML')
|
||||||
return False
|
return
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
fields = dir(root)
|
fields = dir(root)
|
||||||
decode = {
|
decode = {
|
||||||
@ -193,9 +180,6 @@ class OpenSongImport(SongImport):
|
|||||||
setattr(self, fn_or_string, ustring)
|
setattr(self, fn_or_string, ustring)
|
||||||
else:
|
else:
|
||||||
fn_or_string(ustring)
|
fn_or_string(ustring)
|
||||||
if not len(self.title):
|
|
||||||
# to prevent creation of empty songs from wrong files
|
|
||||||
return False
|
|
||||||
if u'theme' in fields and unicode(root.theme) not in self.topics:
|
if u'theme' in fields and unicode(root.theme) not in self.topics:
|
||||||
self.topics.append(unicode(root.theme))
|
self.topics.append(unicode(root.theme))
|
||||||
if u'alttheme' in fields and unicode(root.alttheme) not in self.topics:
|
if u'alttheme' in fields and unicode(root.alttheme) not in self.topics:
|
||||||
@ -205,11 +189,14 @@ class OpenSongImport(SongImport):
|
|||||||
# keep track of verses appearance order
|
# keep track of verses appearance order
|
||||||
our_verse_order = []
|
our_verse_order = []
|
||||||
# default verse
|
# default verse
|
||||||
verse_tag = u'v'
|
verse_tag = VerseType.Tags[VerseType.Verse]
|
||||||
verse_num = u'1'
|
verse_num = u'1'
|
||||||
# for the case where song has several sections with same marker
|
# for the case where song has several sections with same marker
|
||||||
inst = 1
|
inst = 1
|
||||||
lyrics = unicode(root.lyrics)
|
if u'lyrics' in fields:
|
||||||
|
lyrics = unicode(root.lyrics)
|
||||||
|
else:
|
||||||
|
lyrics = u''
|
||||||
for this_line in lyrics.split(u'\n'):
|
for this_line in lyrics.split(u'\n'):
|
||||||
# remove comments
|
# remove comments
|
||||||
semicolon = this_line.find(u';')
|
semicolon = this_line.find(u';')
|
||||||
@ -230,7 +217,7 @@ class OpenSongImport(SongImport):
|
|||||||
# have we got any digits?
|
# have we got any digits?
|
||||||
# If so, verse number is everything from the digits
|
# If so, verse number is everything from the digits
|
||||||
# to the end (even if there are some alpha chars on the end)
|
# to the end (even if there are some alpha chars on the end)
|
||||||
match = re.match(u'(.*)(\d+.*)', content)
|
match = re.match(u'(\D*)(\d+.*)', content)
|
||||||
if match is not None:
|
if match is not None:
|
||||||
verse_tag = match.group(1)
|
verse_tag = match.group(1)
|
||||||
verse_num = match.group(2)
|
verse_num = match.group(2)
|
||||||
@ -239,12 +226,13 @@ class OpenSongImport(SongImport):
|
|||||||
# the verse tag
|
# the verse tag
|
||||||
verse_tag = content
|
verse_tag = content
|
||||||
verse_num = u'1'
|
verse_num = u'1'
|
||||||
|
verse_index = VerseType.from_loose_input(verse_tag)
|
||||||
|
verse_tag = VerseType.Tags[verse_index]
|
||||||
inst = 1
|
inst = 1
|
||||||
if [verse_tag, verse_num, inst] in our_verse_order \
|
if [verse_tag, verse_num, inst] in our_verse_order \
|
||||||
and verses.has_key(verse_tag) \
|
and verses.has_key(verse_tag) \
|
||||||
and verses[verse_tag].has_key(verse_num):
|
and verses[verse_tag].has_key(verse_num):
|
||||||
inst = len(verses[verse_tag][verse_num])+1
|
inst = len(verses[verse_tag][verse_num]) + 1
|
||||||
our_verse_order.append([verse_tag, verse_num, inst])
|
|
||||||
continue
|
continue
|
||||||
# number at start of line.. it's verse number
|
# number at start of line.. it's verse number
|
||||||
if this_line[0].isdigit():
|
if this_line[0].isdigit():
|
||||||
@ -257,6 +245,7 @@ class OpenSongImport(SongImport):
|
|||||||
verses[verse_tag][verse_num] = {}
|
verses[verse_tag][verse_num] = {}
|
||||||
if not verses[verse_tag][verse_num].has_key(inst):
|
if not verses[verse_tag][verse_num].has_key(inst):
|
||||||
verses[verse_tag][verse_num][inst] = []
|
verses[verse_tag][verse_num][inst] = []
|
||||||
|
our_verse_order.append([verse_tag, verse_num, inst])
|
||||||
# Tidy text and remove the ____s from extended words
|
# Tidy text and remove the ____s from extended words
|
||||||
this_line = self.tidy_text(this_line)
|
this_line = self.tidy_text(this_line)
|
||||||
this_line = this_line.replace(u'_', u'')
|
this_line = this_line.replace(u'_', u'')
|
||||||
@ -268,28 +257,31 @@ class OpenSongImport(SongImport):
|
|||||||
verse_def = u'%s%s' % (verse_tag, verse_num)
|
verse_def = u'%s%s' % (verse_tag, verse_num)
|
||||||
lines = u'\n'.join(verses[verse_tag][verse_num][inst])
|
lines = u'\n'.join(verses[verse_tag][verse_num][inst])
|
||||||
self.add_verse(lines, verse_def)
|
self.add_verse(lines, verse_def)
|
||||||
|
if not self.verses:
|
||||||
|
self.add_verse('')
|
||||||
# figure out the presentation order, if present
|
# figure out the presentation order, if present
|
||||||
if u'presentation' in fields and root.presentation != u'':
|
if u'presentation' in fields and root.presentation:
|
||||||
order = unicode(root.presentation)
|
order = unicode(root.presentation)
|
||||||
# We make all the tags in the lyrics lower case, so match that here
|
# We make all the tags in the lyrics lower case, so match that here
|
||||||
# and then split into a list on the whitespace
|
# and then split into a list on the whitespace
|
||||||
order = order.lower().split()
|
order = order.lower().split()
|
||||||
for verse_def in order:
|
for verse_def in order:
|
||||||
match = re.match(u'(.*)(\d+.*)', verse_def)
|
match = re.match(u'(\D*)(\d+.*)', verse_def)
|
||||||
if match is not None:
|
if match is not None:
|
||||||
verse_tag = match.group(1)
|
verse_tag = match.group(1)
|
||||||
verse_num = match.group(2)
|
verse_num = match.group(2)
|
||||||
if not len(verse_tag):
|
if not len(verse_tag):
|
||||||
verse_tag = u'v'
|
verse_tag = VerseType.Tags[VerseType.Verse]
|
||||||
else:
|
else:
|
||||||
# Assume it's no.1 if there are no digits
|
# Assume it's no.1 if there are no digits
|
||||||
verse_tag = verse_def
|
verse_tag = verse_def
|
||||||
verse_num = u'1'
|
verse_num = u'1'
|
||||||
verse_def = u'%s%s' % (verse_tag, verse_num)
|
verse_def = u'%s%s' % (verse_tag, verse_num)
|
||||||
if verses.has_key(verse_tag) \
|
if verses.has_key(verse_tag) and \
|
||||||
and verses[verse_tag].has_key(verse_num):
|
verses[verse_tag].has_key(verse_num):
|
||||||
self.verse_order_list.append(verse_def)
|
self.verse_order_list.append(verse_def)
|
||||||
else:
|
else:
|
||||||
log.info(u'Got order %s but not in verse tags, dropping'
|
log.info(u'Got order %s but not in verse tags, dropping'
|
||||||
u'this item from presentation order', verse_def)
|
u'this item from presentation order', verse_def)
|
||||||
return True
|
if not self.finish():
|
||||||
|
self.log_error(file.name)
|
||||||
|
@ -88,7 +88,6 @@ class SofImport(OooImport):
|
|||||||
paragraphs = self.document.getText().createEnumeration()
|
paragraphs = self.document.getText().createEnumeration()
|
||||||
while paragraphs.hasMoreElements():
|
while paragraphs.hasMoreElements():
|
||||||
if self.stop_import_flag:
|
if self.stop_import_flag:
|
||||||
self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
|
|
||||||
return
|
return
|
||||||
paragraph = paragraphs.nextElement()
|
paragraph = paragraphs.nextElement()
|
||||||
if paragraph.supportsService("com.sun.star.text.Paragraph"):
|
if paragraph.supportsService("com.sun.star.text.Paragraph"):
|
||||||
|
@ -33,9 +33,9 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
|
||||||
from openlp.plugins.songs.lib import VerseType
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
from openlp.plugins.songs.lib.ui import SongStrings
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -78,58 +78,55 @@ class SongBeamerImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
Receive a single file or a list of files to import.
|
Receive a single file or a list of files to import.
|
||||||
"""
|
"""
|
||||||
if isinstance(self.import_source, list):
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
self.import_wizard.progressBar.setMaximum(
|
if not isinstance(self.import_source, list):
|
||||||
len(self.import_source))
|
return
|
||||||
for file in self.import_source:
|
for file in self.import_source:
|
||||||
# TODO: check that it is a valid SongBeamer file
|
# TODO: check that it is a valid SongBeamer file
|
||||||
self.set_defaults()
|
if self.stop_import_flag:
|
||||||
self.current_verse = u''
|
return
|
||||||
self.current_verse_type = VerseType.Tags[VerseType.Verse]
|
self.set_defaults()
|
||||||
read_verses = False
|
self.current_verse = u''
|
||||||
file_name = os.path.split(file)[1]
|
self.current_verse_type = VerseType.Tags[VerseType.Verse]
|
||||||
self.import_wizard.incrementProgressBar(
|
read_verses = False
|
||||||
WizardStrings.ImportingType % file_name, 0)
|
file_name = os.path.split(file)[1]
|
||||||
if os.path.isfile(file):
|
if os.path.isfile(file):
|
||||||
detect_file = open(file, u'r')
|
detect_file = open(file, u'r')
|
||||||
details = chardet.detect(detect_file.read(2048))
|
details = chardet.detect(detect_file.read(2048))
|
||||||
detect_file.close()
|
detect_file.close()
|
||||||
infile = codecs.open(file, u'r', details['encoding'])
|
infile = codecs.open(file, u'r', details['encoding'])
|
||||||
songData = infile.readlines()
|
songData = infile.readlines()
|
||||||
infile.close()
|
infile.close()
|
||||||
else:
|
else:
|
||||||
return False
|
continue
|
||||||
self.title = file_name.split('.sng')[0]
|
self.title = file_name.split('.sng')[0]
|
||||||
read_verses = False
|
read_verses = False
|
||||||
for line in songData:
|
for line in songData:
|
||||||
# Just make sure that the line is of the type 'Unicode'.
|
# Just make sure that the line is of the type 'Unicode'.
|
||||||
line = unicode(line).strip()
|
line = unicode(line).strip()
|
||||||
if line.startswith(u'#') and not read_verses:
|
if line.startswith(u'#') and not read_verses:
|
||||||
self.parse_tags(line)
|
self.parse_tags(line)
|
||||||
elif line.startswith(u'---'):
|
elif line.startswith(u'---'):
|
||||||
if self.current_verse:
|
if self.current_verse:
|
||||||
self.replace_html_tags()
|
self.replace_html_tags()
|
||||||
self.add_verse(self.current_verse,
|
self.add_verse(self.current_verse,
|
||||||
self.current_verse_type)
|
self.current_verse_type)
|
||||||
self.current_verse = u''
|
self.current_verse = u''
|
||||||
self.current_verse_type = VerseType.Tags[VerseType.Verse]
|
self.current_verse_type = VerseType.Tags[VerseType.Verse]
|
||||||
read_verses = True
|
read_verses = True
|
||||||
verse_start = True
|
verse_start = True
|
||||||
elif read_verses:
|
elif read_verses:
|
||||||
if verse_start:
|
if verse_start:
|
||||||
verse_start = False
|
verse_start = False
|
||||||
if not self.check_verse_marks(line):
|
if not self.check_verse_marks(line):
|
||||||
self.current_verse = line + u'\n'
|
self.current_verse = line + u'\n'
|
||||||
else:
|
else:
|
||||||
self.current_verse += line + u'\n'
|
self.current_verse += line + u'\n'
|
||||||
if self.current_verse:
|
if self.current_verse:
|
||||||
self.replace_html_tags()
|
self.replace_html_tags()
|
||||||
self.add_verse(self.current_verse, self.current_verse_type)
|
self.add_verse(self.current_verse, self.current_verse_type)
|
||||||
if self.check_complete():
|
if not self.finish():
|
||||||
self.finish()
|
self.log_error(file)
|
||||||
self.import_wizard.incrementProgressBar(
|
|
||||||
WizardStrings.ImportingType % file_name)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def replace_html_tags(self):
|
def replace_html_tags(self):
|
||||||
"""
|
"""
|
||||||
@ -189,7 +186,7 @@ class SongBeamerImport(SongImport):
|
|||||||
elif tag_val[0] == u'#Bible':
|
elif tag_val[0] == u'#Bible':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == u'#Categories':
|
elif tag_val[0] == u'#Categories':
|
||||||
self.topics = line.split(',')
|
self.topics = tag_val[1].split(',')
|
||||||
elif tag_val[0] == u'#CCLI':
|
elif tag_val[0] == u'#CCLI':
|
||||||
self.ccli_number = tag_val[1]
|
self.ccli_number = tag_val[1]
|
||||||
elif tag_val[0] == u'#Chords':
|
elif tag_val[0] == u'#Chords':
|
||||||
@ -236,11 +233,12 @@ class SongBeamerImport(SongImport):
|
|||||||
pass
|
pass
|
||||||
elif tag_val[0] == u'#Rights':
|
elif tag_val[0] == u'#Rights':
|
||||||
song_book_pub = tag_val[1]
|
song_book_pub = tag_val[1]
|
||||||
elif tag_val[0] == u'#Songbook':
|
elif tag_val[0] == u'#Songbook' or tag_val[0] == u'#SongBook':
|
||||||
book_num = tag_val[1].split(' / ')
|
book_data = tag_val[1].split(u'/')
|
||||||
self.song_book_name = book_num[0]
|
self.song_book_name = book_data[0].strip()
|
||||||
if len(book_num) == book_num[1]:
|
if len(book_data) == 2:
|
||||||
self.song_number = u''
|
number = book_data[1].strip()
|
||||||
|
self.song_number = number if number.isdigit() else u''
|
||||||
elif tag_val[0] == u'#Speed':
|
elif tag_val[0] == u'#Speed':
|
||||||
pass
|
pass
|
||||||
elif tag_val[0] == u'Tempo':
|
elif tag_val[0] == u'Tempo':
|
||||||
@ -287,5 +285,4 @@ class SongBeamerImport(SongImport):
|
|||||||
if marks[1].isdigit():
|
if marks[1].isdigit():
|
||||||
self.current_verse_type += marks[1]
|
self.current_verse_type += marks[1]
|
||||||
return True
|
return True
|
||||||
else:
|
return False
|
||||||
return False
|
|
||||||
|
@ -23,12 +23,14 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
|
|
||||||
from openlp.core.lib import Receiver, translate
|
from openlp.core.lib import Receiver, translate, check_directory_exists
|
||||||
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
|
from openlp.core.utils import AppLocation
|
||||||
from openlp.plugins.songs.lib import clean_song, VerseType
|
from openlp.plugins.songs.lib import clean_song, VerseType
|
||||||
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile
|
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile
|
||||||
from openlp.plugins.songs.lib.ui import SongStrings
|
from openlp.plugins.songs.lib.ui import SongStrings
|
||||||
@ -66,6 +68,7 @@ class SongImport(QtCore.QObject):
|
|||||||
self.song = None
|
self.song = None
|
||||||
self.stop_import_flag = False
|
self.stop_import_flag = False
|
||||||
self.set_defaults()
|
self.set_defaults()
|
||||||
|
self.error_log = []
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
|
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
|
||||||
|
|
||||||
@ -94,6 +97,32 @@ class SongImport(QtCore.QObject):
|
|||||||
self.copyright_string = unicode(translate(
|
self.copyright_string = unicode(translate(
|
||||||
'SongsPlugin.SongImport', 'copyright'))
|
'SongsPlugin.SongImport', 'copyright'))
|
||||||
|
|
||||||
|
def log_error(self, filepath, reason=SongStrings.SongIncomplete):
|
||||||
|
"""
|
||||||
|
This should be called, when a song could not be imported.
|
||||||
|
|
||||||
|
``filepath``
|
||||||
|
This should be the file path if ``self.import_source`` is a list
|
||||||
|
with different files. If it is not a list, but a single file (for
|
||||||
|
instance a database), then this should be the song's title.
|
||||||
|
|
||||||
|
``reason``
|
||||||
|
The reason, why the import failed. The string should be as
|
||||||
|
informative as possible.
|
||||||
|
"""
|
||||||
|
self.set_defaults()
|
||||||
|
if self.import_wizard is None:
|
||||||
|
return
|
||||||
|
if self.import_wizard.errorReportTextEdit.isHidden():
|
||||||
|
self.import_wizard.errorReportTextEdit.setText(
|
||||||
|
translate('SongsPlugin.SongImport',
|
||||||
|
'The following songs could not be imported:'))
|
||||||
|
self.import_wizard.errorReportTextEdit.setVisible(True)
|
||||||
|
self.import_wizard.errorCopyToButton.setVisible(True)
|
||||||
|
self.import_wizard.errorSaveToButton.setVisible(True)
|
||||||
|
self.import_wizard.errorReportTextEdit.append(
|
||||||
|
u'- %s (%s)' % (filepath, reason))
|
||||||
|
|
||||||
def stop_import(self):
|
def stop_import(self):
|
||||||
"""
|
"""
|
||||||
Sets the flag for importers to stop their import
|
Sets the flag for importers to stop their import
|
||||||
@ -240,7 +269,7 @@ class SongImport(QtCore.QObject):
|
|||||||
Author not checked here, if no author then "Author unknown" is
|
Author not checked here, if no author then "Author unknown" is
|
||||||
automatically added
|
automatically added
|
||||||
"""
|
"""
|
||||||
if self.title == u'' or len(self.verses) == 0:
|
if not self.title or not len(self.verses):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
@ -249,9 +278,15 @@ class SongImport(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
All fields have been set to this song. Write the song to disk.
|
All fields have been set to this song. Write the song to disk.
|
||||||
"""
|
"""
|
||||||
|
if not self.check_complete():
|
||||||
|
self.set_defaults()
|
||||||
|
return False
|
||||||
log.info(u'committing song %s to database', self.title)
|
log.info(u'committing song %s to database', self.title)
|
||||||
song = Song()
|
song = Song()
|
||||||
song.title = self.title
|
song.title = self.title
|
||||||
|
if self.import_wizard is not None:
|
||||||
|
self.import_wizard.incrementProgressBar(
|
||||||
|
WizardStrings.ImportingType % song.title)
|
||||||
song.alternate_title = self.alternate_title
|
song.alternate_title = self.alternate_title
|
||||||
# Values will be set when cleaning the song.
|
# Values will be set when cleaning the song.
|
||||||
song.search_title = u''
|
song.search_title = u''
|
||||||
@ -308,7 +343,7 @@ class SongImport(QtCore.QObject):
|
|||||||
publisher=self.song_book_pub)
|
publisher=self.song_book_pub)
|
||||||
song.book = song_book
|
song.book = song_book
|
||||||
for topictext in self.topics:
|
for topictext in self.topics:
|
||||||
if len(topictext) == 0:
|
if not topictext:
|
||||||
continue
|
continue
|
||||||
topic = self.manager.get_object_filtered(Topic,
|
topic = self.manager.get_object_filtered(Topic,
|
||||||
Topic.name == topictext)
|
Topic.name == topictext)
|
||||||
@ -318,6 +353,7 @@ class SongImport(QtCore.QObject):
|
|||||||
clean_song(self.manager, song)
|
clean_song(self.manager, song)
|
||||||
self.manager.save_object(song)
|
self.manager.save_object(song)
|
||||||
self.set_defaults()
|
self.set_defaults()
|
||||||
|
return True
|
||||||
|
|
||||||
def print_song(self):
|
def print_song(self):
|
||||||
"""
|
"""
|
||||||
|
@ -32,6 +32,7 @@ import logging
|
|||||||
import struct
|
import struct
|
||||||
|
|
||||||
from openlp.core.ui.wizard import WizardStrings
|
from openlp.core.ui.wizard import WizardStrings
|
||||||
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib.songimport import SongImport
|
from openlp.plugins.songs.lib.songimport import SongImport
|
||||||
|
|
||||||
TITLE = 1
|
TITLE = 1
|
||||||
@ -97,83 +98,81 @@ class SongShowPlusImport(SongImport):
|
|||||||
Receive a single file or a list of files to import.
|
Receive a single file or a list of files to import.
|
||||||
"""
|
"""
|
||||||
if isinstance(self.import_source, list):
|
if isinstance(self.import_source, list):
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
return
|
||||||
for file in self.import_source:
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
author = u''
|
for file in self.import_source:
|
||||||
self.sspVerseOrderList = []
|
self.sspVerseOrderList = []
|
||||||
otherCount = 0
|
otherCount = 0
|
||||||
otherList = {}
|
otherList = {}
|
||||||
file_name = os.path.split(file)[1]
|
file_name = os.path.split(file)[1]
|
||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % file_name, 0)
|
WizardStrings.ImportingType % file_name, 0)
|
||||||
songData = open(file, 'rb')
|
songData = open(file, 'rb')
|
||||||
while (1):
|
while True:
|
||||||
blockKey, = struct.unpack("I", songData.read(4))
|
blockKey, = struct.unpack("I", songData.read(4))
|
||||||
# The file ends with 4 NUL's
|
# The file ends with 4 NUL's
|
||||||
if blockKey == 0:
|
if blockKey == 0:
|
||||||
break
|
break
|
||||||
nextBlockStarts, = struct.unpack("I", songData.read(4))
|
nextBlockStarts, = struct.unpack("I", songData.read(4))
|
||||||
if blockKey == VERSE or blockKey == CHORUS:
|
if blockKey == VERSE or blockKey == CHORUS:
|
||||||
null, verseNo, = struct.unpack("BB", songData.read(2))
|
null, verseNo, = struct.unpack("BB", songData.read(2))
|
||||||
elif blockKey == CUSTOM_VERSE:
|
elif blockKey == CUSTOM_VERSE:
|
||||||
null, verseNameLength, = struct.unpack("BB",
|
null, verseNameLength, = struct.unpack("BB",
|
||||||
songData.read(2))
|
songData.read(2))
|
||||||
verseName = songData.read(verseNameLength)
|
verseName = songData.read(verseNameLength)
|
||||||
lengthDescriptorSize, = struct.unpack("B", songData.read(1))
|
lengthDescriptorSize, = struct.unpack("B", songData.read(1))
|
||||||
# Detect if/how long the length descriptor is
|
# Detect if/how long the length descriptor is
|
||||||
if lengthDescriptorSize == 12:
|
if lengthDescriptorSize == 12:
|
||||||
lengthDescriptor, = struct.unpack("I", songData.read(4))
|
lengthDescriptor, = struct.unpack("I", songData.read(4))
|
||||||
elif lengthDescriptorSize == 2:
|
elif lengthDescriptorSize == 2:
|
||||||
lengthDescriptor = 1
|
lengthDescriptor = 1
|
||||||
elif lengthDescriptorSize == 9:
|
elif lengthDescriptorSize == 9:
|
||||||
lengthDescriptor = 0
|
lengthDescriptor = 0
|
||||||
else:
|
else:
|
||||||
lengthDescriptor, = struct.unpack("B", songData.read(1))
|
lengthDescriptor, = struct.unpack("B", songData.read(1))
|
||||||
data = songData.read(lengthDescriptor)
|
data = songData.read(lengthDescriptor)
|
||||||
if blockKey == TITLE:
|
if blockKey == TITLE:
|
||||||
self.title = unicode(data, u'cp1252')
|
self.title = unicode(data, u'cp1252')
|
||||||
elif blockKey == AUTHOR:
|
elif blockKey == AUTHOR:
|
||||||
authors = data.split(" / ")
|
authors = data.split(" / ")
|
||||||
for author in authors:
|
for author in authors:
|
||||||
if author.find(",") !=-1:
|
if author.find(",") !=-1:
|
||||||
authorParts = author.split(", ")
|
authorParts = author.split(", ")
|
||||||
author = authorParts[1] + " " + authorParts[0]
|
author = authorParts[1] + " " + authorParts[0]
|
||||||
self.parse_author(unicode(author, u'cp1252'))
|
self.parse_author(unicode(author, u'cp1252'))
|
||||||
elif blockKey == COPYRIGHT:
|
elif blockKey == COPYRIGHT:
|
||||||
self.add_copyright(unicode(data, u'cp1252'))
|
self.add_copyright(unicode(data, u'cp1252'))
|
||||||
elif blockKey == CCLI_NO:
|
elif blockKey == CCLI_NO:
|
||||||
self.ccli_number = int(data)
|
self.ccli_number = int(data)
|
||||||
elif blockKey == VERSE:
|
elif blockKey == VERSE:
|
||||||
self.add_verse(unicode(data, u'cp1252'),
|
self.add_verse(unicode(data, u'cp1252'),
|
||||||
"V%s" % verseNo)
|
"V%s" % verseNo)
|
||||||
elif blockKey == CHORUS:
|
elif blockKey == CHORUS:
|
||||||
self.add_verse(unicode(data, u'cp1252'),
|
self.add_verse(unicode(data, u'cp1252'),
|
||||||
"C%s" % verseNo)
|
"C%s" % verseNo)
|
||||||
elif blockKey == TOPIC:
|
elif blockKey == TOPIC:
|
||||||
self.topics.append(unicode(data, u'cp1252'))
|
self.topics.append(unicode(data, u'cp1252'))
|
||||||
elif blockKey == COMMENTS:
|
elif blockKey == COMMENTS:
|
||||||
self.comments = unicode(data, u'cp1252')
|
self.comments = unicode(data, u'cp1252')
|
||||||
elif blockKey == VERSE_ORDER:
|
elif blockKey == VERSE_ORDER:
|
||||||
verseTag = self.toOpenLPVerseTag(data, True)
|
verseTag = self.toOpenLPVerseTag(data, True)
|
||||||
if verseTag:
|
if verseTag:
|
||||||
self.sspVerseOrderList.append(unicode(verseTag,
|
self.sspVerseOrderList.append(unicode(verseTag,
|
||||||
u'cp1252'))
|
u'cp1252'))
|
||||||
elif blockKey == SONG_BOOK:
|
elif blockKey == SONG_BOOK:
|
||||||
self.song_book_name = unicode(data, u'cp1252')
|
self.song_book_name = unicode(data, u'cp1252')
|
||||||
elif blockKey == SONG_NUMBER:
|
elif blockKey == SONG_NUMBER:
|
||||||
self.song_number = ord(data)
|
self.song_number = ord(data)
|
||||||
elif blockKey == CUSTOM_VERSE:
|
elif blockKey == CUSTOM_VERSE:
|
||||||
verseTag = self.toOpenLPVerseTag(verseName)
|
verseTag = self.toOpenLPVerseTag(verseName)
|
||||||
self.add_verse(unicode(data, u'cp1252'), verseTag)
|
self.add_verse(unicode(data, u'cp1252'), verseTag)
|
||||||
else:
|
else:
|
||||||
log.debug("Unrecognised blockKey: %s, data: %s"
|
log.debug("Unrecognised blockKey: %s, data: %s"
|
||||||
%(blockKey, data))
|
% (blockKey, data))
|
||||||
self.verse_order_list = self.sspVerseOrderList
|
self.verse_order_list = self.sspVerseOrderList
|
||||||
songData.close()
|
songData.close()
|
||||||
self.finish()
|
if not self.finish():
|
||||||
self.import_wizard.incrementProgressBar(
|
self.log_error(file)
|
||||||
WizardStrings.ImportingType % file_name)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def toOpenLPVerseTag(self, verseName, ignoreUnique=False):
|
def toOpenLPVerseTag(self, verseName, ignoreUnique=False):
|
||||||
if verseName.find(" ") != -1:
|
if verseName.find(" ") != -1:
|
||||||
@ -185,22 +184,19 @@ class SongShowPlusImport(SongImport):
|
|||||||
verseNumber = "1"
|
verseNumber = "1"
|
||||||
verseType = verseType.lower()
|
verseType = verseType.lower()
|
||||||
if verseType == "verse":
|
if verseType == "verse":
|
||||||
verseTag = "V"
|
verseTag = VerseType.Tags[VerseType.Verse]
|
||||||
elif verseType == "chorus":
|
elif verseType == "chorus":
|
||||||
verseTag = "C"
|
verseTag = VerseType.Tags[VerseType.Chorus]
|
||||||
elif verseType == "bridge":
|
elif verseType == "bridge":
|
||||||
verseTag = "B"
|
verseTag = VerseType.Tags[VerseType.Bridge]
|
||||||
elif verseType == "pre-chorus":
|
elif verseType == "pre-chorus":
|
||||||
verseTag = "P"
|
verseTag = VerseType.Tags[VerseType.PreChorus]
|
||||||
elif verseType == "bridge":
|
|
||||||
verseTag = "B"
|
|
||||||
else:
|
else:
|
||||||
if not self.otherList.has_key(verseName):
|
if not self.otherList.has_key(verseName):
|
||||||
if ignoreUnique:
|
if ignoreUnique:
|
||||||
return None
|
return None
|
||||||
self.otherCount = self.otherCount + 1
|
self.otherCount = self.otherCount + 1
|
||||||
self.otherList[verseName] = str(self.otherCount)
|
self.otherList[verseName] = str(self.otherCount)
|
||||||
verseTag = "O"
|
verseTag = VerseType.Tags[VerseType.Other]
|
||||||
verseNumber = self.otherList[verseName]
|
verseNumber = self.otherList[verseName]
|
||||||
verseTag = verseTag + verseNumber
|
return verseTag + verseNumber
|
||||||
return verseTag
|
|
||||||
|
@ -40,6 +40,8 @@ class SongStrings(object):
|
|||||||
CopyrightSymbol = translate('OpenLP.Ui', '\xa9', 'Copyright symbol.')
|
CopyrightSymbol = translate('OpenLP.Ui', '\xa9', 'Copyright symbol.')
|
||||||
SongBook = translate('OpenLP.Ui', 'Song Book', 'Singular')
|
SongBook = translate('OpenLP.Ui', 'Song Book', 'Singular')
|
||||||
SongBooks = translate('OpenLP.Ui', 'Song Books', 'Plural')
|
SongBooks = translate('OpenLP.Ui', 'Song Books', 'Plural')
|
||||||
|
SongIncomplete = translate('OpenLP.Ui','Title and/or verses not found')
|
||||||
SongMaintenance = translate('OpenLP.Ui', 'Song Maintenance')
|
SongMaintenance = translate('OpenLP.Ui', 'Song Maintenance')
|
||||||
Topic = translate('OpenLP.Ui', 'Topic', 'Singular')
|
Topic = translate('OpenLP.Ui', 'Topic', 'Singular')
|
||||||
Topics = translate('OpenLP.Ui', 'Topics', 'Plural')
|
Topics = translate('OpenLP.Ui', 'Topics', 'Plural')
|
||||||
|
XMLSyntaxError = translate('OpenLP.Ui', 'XML syntax error')
|
||||||
|
@ -105,11 +105,7 @@ class WowImport(SongImport):
|
|||||||
if isinstance(self.import_source, list):
|
if isinstance(self.import_source, list):
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
for file in self.import_source:
|
for file in self.import_source:
|
||||||
author = u''
|
|
||||||
copyright = u''
|
|
||||||
file_name = os.path.split(file)[1]
|
file_name = os.path.split(file)[1]
|
||||||
self.import_wizard.incrementProgressBar(
|
|
||||||
WizardStrings.ImportingType % file_name, 0)
|
|
||||||
# Get the song title
|
# Get the song title
|
||||||
self.title = file_name.rpartition(u'.')[0]
|
self.title = file_name.rpartition(u'.')[0]
|
||||||
songData = open(file, 'rb')
|
songData = open(file, 'rb')
|
||||||
@ -129,7 +125,7 @@ class WowImport(SongImport):
|
|||||||
self.line_text = unicode(
|
self.line_text = unicode(
|
||||||
songData.read(ord(songData.read(1))), u'cp1252')
|
songData.read(ord(songData.read(1))), u'cp1252')
|
||||||
songData.seek(1, os.SEEK_CUR)
|
songData.seek(1, os.SEEK_CUR)
|
||||||
if block_text != u'':
|
if block_text:
|
||||||
block_text += u'\n'
|
block_text += u'\n'
|
||||||
block_text += self.line_text
|
block_text += self.line_text
|
||||||
self.lines_to_read -= 1
|
self.lines_to_read -= 1
|
||||||
@ -138,22 +134,19 @@ class WowImport(SongImport):
|
|||||||
songData.seek(3, os.SEEK_CUR)
|
songData.seek(3, os.SEEK_CUR)
|
||||||
# Blocks are seperated by 2 bytes, skip them, but not if
|
# Blocks are seperated by 2 bytes, skip them, but not if
|
||||||
# this is the last block!
|
# this is the last block!
|
||||||
if (block + 1) < no_of_blocks:
|
if block + 1 < no_of_blocks:
|
||||||
songData.seek(2, os.SEEK_CUR)
|
songData.seek(2, os.SEEK_CUR)
|
||||||
self.add_verse(block_text, block_type)
|
self.add_verse(block_text, block_type)
|
||||||
# Now to extract the author
|
# Now to extract the author
|
||||||
author_length = ord(songData.read(1))
|
author_length = ord(songData.read(1))
|
||||||
if author_length != 0:
|
if author_length:
|
||||||
author = unicode(songData.read(author_length), u'cp1252')
|
self.parse_author(
|
||||||
|
unicode(songData.read(author_length), u'cp1252'))
|
||||||
# Finally the copyright
|
# Finally the copyright
|
||||||
copyright_length = ord(songData.read(1))
|
copyright_length = ord(songData.read(1))
|
||||||
if copyright_length != 0:
|
if copyright_length:
|
||||||
copyright = unicode(
|
self.add_copyright(unicode(
|
||||||
songData.read(copyright_length), u'cp1252')
|
songData.read(copyright_length), u'cp1252'))
|
||||||
self.parse_author(author)
|
|
||||||
self.add_copyright(copyright)
|
|
||||||
songData.close()
|
songData.close()
|
||||||
self.finish()
|
if not self.finish():
|
||||||
self.import_wizard.incrementProgressBar(
|
self.log_error(file)
|
||||||
WizardStrings.ImportingType % file_name)
|
|
||||||
return True
|
|
||||||
|