fixing conflicts

This commit is contained in:
Wesley Stout 2010-10-18 13:20:38 -05:00
commit 957929829d
120 changed files with 3443 additions and 1608 deletions

View File

@ -1,19 +0,0 @@
# -*- mode: python -*-
a = Analysis([os.path.join(HOMEPATH,'support\\_mountzlib.py'), os.path.join(HOMEPATH,'support\\useUnicode.py'), 'openlp.pyw'],
pathex=[os.path.abspath('.')])
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
exclude_binaries=1,
name=os.path.join('build\\pyi.win32\\OpenLP', 'OpenLP.exe'),
debug=False,
strip=False,
upx=True,
console=False , icon='resources\\images\\OpenLP.ico')
coll = COLLECT( exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name=os.path.join('dist', 'OpenLP'))

View File

@ -17,7 +17,7 @@ import sys
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.append(os.path.abspath(os.path.join('..', '..')))
sys.path.insert(0, os.path.abspath(os.path.join('..', '..', '..')))
# -- General configuration -----------------------------------------------------
@ -39,7 +39,7 @@ master_doc = 'index'
# General information about the project.
project = u'OpenLP'
copyright = u'2009, Raoul Snyman'
copyright = u'2004-2010, Raoul Snyman'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@ -48,7 +48,7 @@ copyright = u'2009, Raoul Snyman'
# The short X.Y version.
version = '2.0'
# The full version, including alpha/beta/rc tags.
release = '2.0.pre'
release = '1.9.3'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -111,7 +111,7 @@ html_theme_options = {
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
html_title = 'OpenLP 2.0 Developer API'
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
@ -166,7 +166,7 @@ html_static_path = ['_static']
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'OpenLPdoc'
htmlhelp_basename = 'OpenLP-2.0-api'
# -- Options for LaTeX output --------------------------------------------------
@ -180,7 +180,7 @@ htmlhelp_basename = 'OpenLPdoc'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'OpenLP.tex', u'OpenLP Documentation',
('index', 'OpenLP.tex', u'OpenLP 2.0 Developer API',
u'Raoul Snyman', 'manual'),
]

View File

@ -60,12 +60,6 @@
.. autoclass:: openlp.core.lib.settingstab.SettingsTab
:members:
:mod:`ThemeXML`
---------------
.. autoclass:: openlp.core.lib.themexmlhandler.ThemeXML
:members:
:mod:`OpenLPToolbar`
--------------------

View File

@ -0,0 +1,55 @@
.. _plugins-bibles:
Bibles Plugin
=============
.. automodule:: openlp.plugins.bibles
:members:
Plugin Class
------------
.. autoclass:: openlp.plugins.bibles.bibleplugin.BiblePlugin
:members:
Forms
-----
.. automodule:: openlp.plugins.bibles.forms
:members:
.. autoclass:: openlp.plugins.bibles.forms.importwizardform.ImportWizardForm
:members:
Helper Classes & Functions
--------------------------
.. automodule:: openlp.plugins.bibles.lib
:members:
.. automodule:: openlp.plugins.bibles.lib.db
:members:
.. automodule:: openlp.plugins.bibles.lib.biblestab
:members:
.. automodule:: openlp.plugins.bibles.lib.manager
:members:
.. automodule:: openlp.plugins.bibles.lib.mediaitem
:members:
Bible Importers
---------------
.. automodule:: openlp.plugins.bibles.lib.csvbible
:members:
.. automodule:: openlp.plugins.bibles.lib.http
:members:
.. automodule:: openlp.plugins.bibles.lib.osis
:members:
.. automodule:: openlp.plugins.bibles.lib.opensong
:members:

View File

@ -0,0 +1,22 @@
.. _plugins-images:
Images Plugin
=============
.. automodule:: openlp.plugins.images
:members:
Plugin Class
------------
.. autoclass:: openlp.plugins.images.imageplugin.ImagePlugin
:members:
Helper Classes & Functions
--------------------------
.. automodule:: openlp.plugins.images.lib
:members:
.. automodule:: openlp.plugins.images.lib.mediaitem
:members:

View File

@ -11,24 +11,9 @@
songs
bibles
:mod:`presentations` Plugin
---------------------------
.. automodule:: openlp.plugins.presentations
:members:
:mod:`media` Plugin
-------------------
.. automodule:: openlp.plugins.media
:members:
:mod:`images` Plugin
--------------------
.. automodule:: openlp.plugins.images
:members:
presentations
media
images
:mod:`custom` Plugin
--------------------

View File

@ -0,0 +1,22 @@
.. _plugins-media:
Media Plugin
============
.. automodule:: openlp.plugins.media
:members:
Plugin Class
------------
.. autoclass:: openlp.plugins.media.mediaplugin.MediaPlugin
:members:
Helper Classes & Functions
--------------------------
.. automodule:: openlp.plugins.media.lib
:members:
.. automodule:: openlp.plugins.media.lib.mediaitem
:members:

View File

@ -0,0 +1,40 @@
.. _plugins-presentations:
Presentations Plugin
====================
Plugin Class
------------
.. autoclass:: openlp.plugins.presentations.presentationplugin.PresentationPlugin
:members:
Helper Classes & Functions
--------------------------
.. automodule:: openlp.plugins.presentations.lib
:members:
.. automodule:: openlp.plugins.presentations.lib.mediaitem
:members:
.. automodule:: openlp.plugins.presentations.lib.presentationtab
:members:
.. automodule:: openlp.plugins.presentations.lib.messagelistener
:members:
.. automodule:: openlp.plugins.presentations.lib.presentationcontroller
:members:
Presentation Application Controllers
------------------------------------
.. automodule:: openlp.plugins.presentations.lib.impresscontroller
:members:
.. automodule:: openlp.plugins.presentations.lib.pptviewcontroller
:members:
.. automodule:: openlp.plugins.presentations.lib.powerpointcontroller
:members:

View File

@ -0,0 +1,103 @@
.. _plugins-songs:
Songs Plugin
============
.. automodule:: openlp.plugins.songs
:members:
Plugin Class
------------
.. autoclass:: openlp.plugins.songs.songsplugin.SongsPlugin
:members:
Forms
-----
.. automodule:: openlp.plugins.songs.forms
:members:
.. autoclass:: openlp.plugins.songs.forms.authorsform.AuthorsForm
:members:
.. autoclass:: openlp.plugins.songs.forms.editsongform.EditSongForm
:members:
.. autoclass:: openlp.plugins.songs.forms.editverseform.EditVerseForm
:members:
.. autoclass:: openlp.plugins.songs.forms.songbookform.SongBookForm
:members:
.. autoclass:: openlp.plugins.songs.forms.songimportform.SongImportForm
:members:
.. autoclass:: openlp.plugins.songs.forms.songmaintenanceform.SongMaintenanceForm
:members:
.. autoclass:: openlp.plugins.songs.forms.topicsform.TopicsForm
:members:
Helper Classes & Functions
--------------------------
.. automodule:: openlp.plugins.songs.lib
:members:
.. automodule:: openlp.plugins.songs.lib.db
:members:
.. automodule:: openlp.plugins.songs.lib.importer
:members:
.. automodule:: openlp.plugins.songs.lib.mediaitem
:members:
.. autoclass:: openlp.plugins.songs.lib.mediaitem.SongListView
:members:
.. automodule:: openlp.plugins.songs.lib.songimport
:members:
.. automodule:: openlp.plugins.songs.lib.songstab
:members:
.. automodule:: openlp.plugins.songs.lib.xml
:members:
Song Importers
--------------
.. automodule:: openlp.plugins.songs.lib.cclifileimport
:members:
.. autoclass:: openlp.plugins.songs.lib.cclifileimport.CCLIFileImportError
:members:
.. automodule:: openlp.plugins.songs.lib.ewimport
:members:
.. autoclass:: openlp.plugins.songs.lib.ewimport.FieldDescEntry
:members:
.. automodule:: openlp.plugins.songs.lib.olp1import
:members:
.. automodule:: openlp.plugins.songs.lib.olpimport
:members:
.. automodule:: openlp.plugins.songs.lib.oooimport
:members:
.. automodule:: openlp.plugins.songs.lib.opensongimport
:members:
.. automodule:: openlp.plugins.songs.lib.sofimport
:members:
.. automodule:: openlp.plugins.songs.lib.songbeamerimport
:members:
.. automodule:: openlp.plugins.songs.lib.wowimport
:members:

View File

@ -0,0 +1,88 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf build/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
@echo
@echo "Build finished. The HTML pages are in build/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) build/dirhtml
@echo
@echo "Build finished. The HTML pages are in build/dirhtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) build/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in build/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) build/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in build/qthelp, like this:"
@echo "# qcollectiongenerator build/qthelp/OpenLP.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile build/qthelp/OpenLP.qhc"
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
@echo
@echo "Build finished; the LaTeX files are in build/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
@echo
@echo "The overview file is in build/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in build/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) build/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in build/doctest/output.txt."

View File

@ -0,0 +1,112 @@
@ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=sphinx-build
set ALLSPHINXOPTS=-d build/doctrees %SPHINXOPTS% source
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (build\*) do rmdir /q /s %%i
del /q /s build\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% build/html
echo.
echo.Build finished. The HTML pages are in build/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% build/dirhtml
echo.
echo.Build finished. The HTML pages are in build/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% build/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% build/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% build/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in build/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% build/qthelp
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in build/qthelp, like this:
echo.^> qcollectiongenerator build\qthelp\OpenLP.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile build\qthelp\OpenLP.ghc
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% build/latex
echo.
echo.Build finished; the LaTeX files are in build/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% build/changes
echo.
echo.The overview file is in build/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% build/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in build/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% build/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in build/doctest/output.txt.
goto end
)
:end

View File

@ -0,0 +1,208 @@
# -*- coding: utf-8 -*-
#
# OpenLP documentation build configuration file, created by
# sphinx-quickstart on Fri Jul 10 17:20:40 2009.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import os
import sys
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath(os.path.join('..', '..')))
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
#extensions = ['sphinx.ext.autodoc']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'OpenLP'
copyright = u'2004-2010 Raoul Snyman'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '2.0'
# The full version, including alpha/beta/rc tags.
release = '1.9.3'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = []
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
add_module_names = False
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {
'sidebarbgcolor': '#3a60a9',
'relbarbgcolor': '#203b6f',
'footerbgcolor': '#26437c',
'headtextcolor': '#203b6f',
'linkcolor': '#26437c',
'sidebarlinkcolor': '#ceceff'
}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
html_title = u'OpenLP 2.0 User Manual'
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'OpenLP-2.0-manual'
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'OpenLP.tex', u'OpenLP 2.0 User Manual',
u'Raoul Snyman', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
# A dictionary that contains LaTeX snippets that override those Sphinx usually
# puts into the generated .tex files.
latex_elements = {
'fontpkg': '\\usepackage{helvet}'
}

View File

@ -9,21 +9,22 @@ be used throughout this documentation, and when seeking support.
Main Window
-----------
The Main Window is what you will see when you first open OpenLP.
The Main Window contains all the tools and plugins that make OpenLP function.
The Main Window is what you will see when you first open OpenLP
.. image:: pics/mainwindow.png
The Main Window contains all the tools and plugins that make OpenLP function
Media Manager
-------------
The Media Manager contains a number of tabs that plugins supply to OpenLP.
Each tab in the Media Manager is called a **Media Item**
From the Media Manager you can send Media Items to the Preview or Live screens.
.. image:: pics/mediamanager.png
From the Media Manager you can send Media Items to the Preview or Live screens.
Preview
-------
@ -43,7 +44,7 @@ Service Item
A service item are the **media items** that are in the **service manager**
Service Manager
Service Manger
--------------
The service manager contains the media items in your service file. This is the

View File

@ -3,8 +3,8 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to OpenLP's documentation
==================================
Welcome to the OpenLP 2.0 User Manual
=====================================
Contents:

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

View File

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View File

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

View File

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 140 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 139 KiB

View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -1,95 +0,0 @@
.. _plugins-bibles:
:mod:`bibles` Plugin
====================
.. automodule:: openlp.plugins.bibles
:members:
:mod:`BiblePlugin` Class
-------------------------
.. autoclass:: openlp.plugins.bibles.bibleplugin.BiblePlugin
:members:
:mod:`forms` Submodule
----------------------
.. automodule:: openlp.plugins.bibles.forms
:members:
:mod:`BibleImportWizard`
^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.bibles.forms.bibleimportwizard.Ui_BibleImportWizard
:members:
.. autoclass:: openlp.plugins.bibles.forms.importwizardform.ImportWizardForm
:members:
:mod:`lib` Submodule
--------------------
.. automodule:: openlp.plugins.bibles.lib
:members:
:mod:`db`
^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.db
:members:
.. autoclass:: openlp.plugins.bibles.lib.db.BibleDB
:members:
:mod:`csv`
^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.csvbible
:members:
.. autoclass:: openlp.plugins.bibles.lib.csvbible.CSVBible
:members:
:mod:`http`
^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.http
:members:
.. autoclass:: openlp.plugins.bibles.lib.http.HTTPBible
:members:
:mod:`bibleOSISimpl`
^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.osis
:members:
.. autoclass:: openlp.plugins.bibles.lib.osis.OSISBible
:members:
:mod:`biblestab`
^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.biblestab
:members:
:mod:`common`
^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.common
:members:
:mod:`manager`
^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.manager
:members:
:mod:`mediaitem`
^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.bibles.lib.mediaitem
:members:

View File

@ -1,46 +0,0 @@
.. _plugins-songs:
:mod:`songs` Plugin
===================
.. automodule:: openlp.plugins.songs
:members:
:mod:`SongsPlugin` Class
------------------------
.. autoclass:: openlp.plugins.songs.songsplugin.SongsPlugin
:members:
:mod:`forms` Submodule
----------------------
.. automodule:: openlp.plugins.songs.forms
:members:
:mod:`AuthorsForm`
^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.authorsdialog.Ui_AuthorsDialog
:members:
.. autoclass:: openlp.plugins.songs.forms.authorsform.AuthorsForm
:members:
:mod:`EditSongForm`
^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.editsongdialog.Ui_EditSongDialog
:members:
.. autoclass:: openlp.plugins.songs.forms.editsongform.EditSongForm
:members:
:mod:`EditVerseForm`
^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.editversedialog.Ui_EditVerseDialog
:members:
.. autoclass:: openlp.plugins.songs.forms.editverseform.EditVerseForm
:members:

View File

@ -30,6 +30,7 @@ import sys
import logging
from optparse import OptionParser
from traceback import format_exception
from subprocess import Popen, PIPE
from PyQt4 import QtCore, QtGui
@ -71,6 +72,84 @@ class OpenLP(QtGui.QApplication):
"""
log.info(u'OpenLP Application Loaded')
def _get_version(self):
"""
Load and store current Application Version
"""
if u'--dev-version' in sys.argv:
# If we're running the dev version, let's use bzr to get the version
try:
# If bzrlib is availble, use it
from bzrlib.branch import Branch
b = Branch.open_containing('.')[0]
b.lock_read()
try:
# Get the branch's latest revision number.
revno = b.revno()
# Convert said revision number into a bzr revision id.
revision_id = b.dotted_revno_to_revision_id((revno,))
# Get a dict of tags, with the revision id as the key.
tags = b.tags.get_reverse_tag_dict()
# Check if the latest
if revision_id in tags:
full_version = u'%s' % tags[revision_id][0]
else:
full_version = '%s-bzr%s' % \
(sorted(b.tags.get_tag_dict().keys())[-1], revno)
finally:
b.unlock()
except:
# Otherwise run the command line bzr client
bzr = Popen((u'bzr', u'tags', u'--sort', u'time'), stdout=PIPE)
output, error = bzr.communicate()
code = bzr.wait()
if code != 0:
raise Exception(u'Error running bzr tags')
lines = output.splitlines()
if len(lines) == 0:
tag = u'0.0.0'
revision = u'0'
else:
tag, revision = lines[-1].split()
bzr = Popen((u'bzr', u'log', u'--line', u'-r', u'-1'),
stdout=PIPE)
output, error = bzr.communicate()
code = bzr.wait()
if code != 0:
raise Exception(u'Error running bzr log')
latest = output.split(u':')[0]
full_version = latest == revision and tag or \
u'%s-bzr%s' % (tag, latest)
else:
# We're not running the development version, let's use the file
filepath = AppLocation.get_directory(AppLocation.VersionDir)
filepath = os.path.join(filepath, u'.version')
fversion = None
try:
fversion = open(filepath, u'r')
full_version = unicode(fversion.read()).rstrip()
except IOError:
log.exception('Error in version file.')
full_version = u'0.0.0-bzr000'
finally:
if fversion:
fversion.close()
bits = full_version.split(u'-')
app_version = {
u'full': full_version,
u'version': bits[0],
u'build': bits[1] if len(bits) > 1 else None
}
if app_version[u'build']:
log.info(
u'Openlp version %s build %s',
app_version[u'version'],
app_version[u'build']
)
else:
log.info(u'Openlp version %s' % app_version[u'version'])
return app_version
def notify(self, obj, evt):
#TODO needed for presentation exceptions
return QtGui.QApplication.notify(self, obj, evt)
@ -79,39 +158,7 @@ class OpenLP(QtGui.QApplication):
"""
Run the OpenLP application.
"""
#Load and store current Application Version
filepath = AppLocation.get_directory(AppLocation.VersionDir)
filepath = os.path.join(filepath, u'.version')
fversion = None
try:
fversion = open(filepath, u'r')
for line in fversion:
full_version = unicode(line).rstrip() #\
#.replace(u'\r', u'').replace(u'\n', u'')
bits = full_version.split(u'-')
app_version = {
u'full': full_version,
u'version': bits[0],
u'build': bits[1] if len(bits) > 1 else None
}
if app_version[u'build']:
log.info(
u'Openlp version %s build %s',
app_version[u'version'],
app_version[u'build']
)
else:
log.info(u'Openlp version %s' % app_version[u'version'])
except IOError:
log.exception('Error in version file.')
app_version = {
u'full': u'1.9.0-bzr000',
u'version': u'1.9.0',
u'build': u'bzr000'
}
finally:
if fversion:
fversion.close()
app_version = self._get_version()
#provide a listener for widgets to reqest a screen update.
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_process_events'), self.processEvents)
@ -172,6 +219,9 @@ def main():
parser.add_option('-p', '--portable', dest='portable',
action='store_true', help='Specify if this should be run as a '
'portable app, off a USB flash drive (not implemented).')
parser.add_option('-d', '--dev-version', dest='dev_version',
action='store_true', help='Ignore the version file and pull the '
'version directly from Bazaar')
parser.add_option('-s', '--style', dest='style',
help='Set the Qt4 style (passed directly to Qt4).')
# Set up logging

View File

@ -223,16 +223,13 @@ def image_to_byte(image):
``image``
The image to converted.
"""
log.debug(u'image_to_byte')
log.debug(u'image_to_byte - start')
byte_array = QtCore.QByteArray()
# use buffer to store pixmap into byteArray
buffie = QtCore.QBuffer(byte_array)
buffie.open(QtCore.QIODevice.WriteOnly)
if isinstance(image, QtGui.QImage):
pixmap = QtGui.QPixmap.fromImage(image)
else:
pixmap = QtGui.QPixmap(image)
pixmap.save(buffie, "PNG")
image.save(buffie, "PNG")
log.debug(u'image_to_byte - end')
# convert to base64 encoding so does not get missed!
return byte_array.toBase64()
@ -253,8 +250,11 @@ def resize_image(image, width, height, background=QtCore.Qt.black):
The background colour defaults to black.
"""
log.debug(u'resize_image')
preview = QtGui.QImage(image)
log.debug(u'resize_image - start')
if isinstance(image, QtGui.QImage):
preview = image
else:
preview = QtGui.QImage(image)
if not preview.isNull():
# Only resize if different size
if preview.width() == width and preview.height == height:
@ -263,6 +263,7 @@ def resize_image(image, width, height, background=QtCore.Qt.black):
QtCore.Qt.SmoothTransformation)
image_cache_key = u'%s%s%s' % (image, unicode(width), unicode(height))
if image_cache_key in image_cache:
log.debug(u'resize_image - end cache')
return image_cache[image_cache_key]
realw = preview.width()
realh = preview.height()
@ -273,6 +274,7 @@ def resize_image(image, width, height, background=QtCore.Qt.black):
painter = QtGui.QPainter(new_image)
painter.drawImage((width - realw) / 2, (height - realh) / 2, preview)
image_cache[image_cache_key] = new_image
log.debug(u'resize_image - end')
return new_image
def check_item_selected(list_widget, message):
@ -313,7 +315,7 @@ def expand_tags(text):
from spelltextedit import SpellTextEdit
from eventreceiver import Receiver
from settingsmanager import SettingsManager
from plugin import PluginStatus, Plugin
from plugin import PluginStatus, StringContent, Plugin
from pluginmanager import PluginManager
from settingstab import SettingsTab
from serviceitem import ServiceItem

View File

@ -75,7 +75,7 @@ class EventReceiver(QtCore.QObject):
Broadcasts that an item has been made live/previewed
``slidecontroller_{live|preview}_change``
Informs the slidecontroller that a slide change has occurred and to
Informs the slidecontroller that a slide change has occurred and to
update itself
``slidecontroller_{live|preview}_changed``
@ -83,7 +83,7 @@ class EventReceiver(QtCore.QObject):
``slidecontroller_{live|preview}_text_request``
Request the text for the current item in the controller
Returns a slidecontroller_{live|preview}_text_response with an
Returns a slidecontroller_{live|preview}_text_response with an
array of dictionaries with the tag and verse text
``slidecontroller_{live|preview}_blank``
@ -106,23 +106,23 @@ class EventReceiver(QtCore.QObject):
``servicemanager_set_item``
Go live on a specific item, by index
``servicemanager_list_request``
Request the service list. Responds with servicemanager_list_response
containing a array of dictionaries
``maindisplay_blank``
Blank the maindisplay window
Blank the maindisplay window
``maindisplay_hide``
Hide the maindisplay window
Hide the maindisplay window
``maindisplay_show``
Return the maindisplay window
Return the maindisplay window
``maindisplay_active``
The maindisplay has been made active
``maindisplay_status_text``
Changes the bottom status bar text on the maindisplay window
@ -193,9 +193,17 @@ class EventReceiver(QtCore.QObject):
``{plugin}_add_service_item``
Ask the plugin to push the selected items to the service item
``{plugin}_service_load``
Ask the plugin to process an individual service item after it has been
loaded
``service_item_update``
Passes back to the service manager the service item after it has been
processed by the plugin
``alerts_text``
Displays an alert message
``bibles_nobook``
Attempt to find book resulted in no match

View File

@ -55,14 +55,17 @@ body {
background-color: black;
display: none;
}
#image {
#bgimage {
z-index:1;
}
#video1 {
#image {
z-index:2;
}
#video1 {
z-index:3;
}
#video2 {
z-index:2;
z-index:3;
}
#alert {
position: absolute;
@ -73,7 +76,7 @@ body {
}
#footer {
position: absolute;
z-index:5;
z-index:6;
%s
}
/* lyric css */
@ -112,7 +115,7 @@ body {
vid2.volume = volume;
}
switch(state){
case 'init':
case 'init':
vid.src = path;
vid2.src = path;
if(loop == null) loop = false;
@ -294,7 +297,8 @@ body {
</script>
</head>
<body>
<img id="image" class="size" %s />
<img id="bgimage" class="size" %s />
<img id="image" class="size" style="display:none" />
<video id="video1" class="size" style="visibility:hidden" autobuffer preload>
</video>
<video id="video2" class="size" style="visibility:hidden" autobuffer preload>
@ -397,7 +401,7 @@ def build_lyrics_css(item, webkitvers):
"""
style = """
.lyricstable {
z-index:4;
z-index:5;
position: absolute;
display: table;
%s

View File

@ -32,7 +32,8 @@ import os
from PyQt4 import QtCore, QtGui
from openlp.core.lib import context_menu_action, context_menu_separator, \
SettingsManager, OpenLPToolbar, ServiceItem, build_icon, translate
SettingsManager, OpenLPToolbar, ServiceItem, StringContent, build_icon, \
translate, Receiver
log = logging.getLogger(__name__)
@ -51,26 +52,19 @@ class MediaManagerItem(QtGui.QWidget):
The parent widget. Usually this will be the *Media Manager*
itself. This needs to be a class descended from ``QWidget``.
``plugin``
The plugin widget. Usually this will be the *Plugin*
itself. This needs to be a class descended from ``Plugin``.
``icon``
Either a ``QIcon``, a resource path, or a file name. This is
the icon which is displayed in the *Media Manager*.
``title``
The title visible on the item in the *Media Manager*.
**Member Variables**
When creating a descendant class from this class for your plugin,
the following member variables should be set.
``self.PluginNameShort``
The shortened (usually singular) name for the plugin e.g. *'Song'*
for the Songs plugin.
``self.pluginNameVisible``
The user visible name for a plugin which should use a suitable
translation function.
``self.OnNewPrompt``
Defaults to *'Select Image(s)'*.
@ -93,13 +87,17 @@ class MediaManagerItem(QtGui.QWidget):
"""
log.info(u'Media Item loaded')
def __init__(self, parent=None, icon=None, title=None):
def __init__(self, parent=None, plugin=None, icon=None):
"""
Constructor to create the media manager item.
"""
QtGui.QWidget.__init__(self)
self.parent = parent
self.settingsSection = title.lower()
#TODO: plugin should not be the parent in future
self.plugin = parent # plugin
visible_title = self.plugin.getString(StringContent.VisibleName)
self.title = unicode(visible_title[u'title'])
self.settingsSection = self.plugin.name.lower()
if isinstance(icon, QtGui.QIcon):
self.icon = icon
elif isinstance(icon, basestring):
@ -107,8 +105,6 @@ class MediaManagerItem(QtGui.QWidget):
QtGui.QIcon.Normal, QtGui.QIcon.Off)
else:
self.icon = None
if title:
self.title = title
self.toolbar = None
self.remoteTriggered = None
self.serviceItemIconName = None
@ -119,6 +115,9 @@ class MediaManagerItem(QtGui.QWidget):
self.requiredIcons()
self.setupUi()
self.retranslateUi()
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'%s_service_load' % self.parent.name.lower()),
self.serviceLoad)
def requiredIcons(self):
"""
@ -208,64 +207,58 @@ class MediaManagerItem(QtGui.QWidget):
"""
## Import Button ##
if self.hasImportIcon:
import_string = self.plugin.getString(StringContent.Import)
self.addToolbarButton(
unicode(translate('OpenLP.MediaManagerItem', 'Import %s')) %
self.PluginNameShort,
unicode(translate('OpenLP.MediaManagerItem', 'Import a %s')) %
self.pluginNameVisible,
import_string[u'title'],
import_string[u'tooltip'],
u':/general/general_import.png', self.onImportClick)
## File Button ##
## Load Button ##
if self.hasFileIcon:
load_string = self.plugin.getString(StringContent.Load)
self.addToolbarButton(
unicode(translate('OpenLP.MediaManagerItem', 'Load %s')) %
self.PluginNameShort,
unicode(translate('OpenLP.MediaManagerItem', 'Load a new %s')) %
self.pluginNameVisible,
load_string[u'title'],
load_string[u'tooltip'],
u':/general/general_open.png', self.onFileClick)
## New Button ##
if self.hasNewIcon:
new_string = self.plugin.getString(StringContent.New)
self.addToolbarButton(
unicode(translate('OpenLP.MediaManagerItem', 'New %s')) %
self.PluginNameShort,
unicode(translate('OpenLP.MediaManagerItem', 'Add a new %s')) %
self.pluginNameVisible,
new_string[u'title'],
new_string[u'tooltip'],
u':/general/general_new.png', self.onNewClick)
## Edit Button ##
if self.hasEditIcon:
edit_string = self.plugin.getString(StringContent.Edit)
self.addToolbarButton(
unicode(translate('OpenLP.MediaManagerItem', 'Edit %s')) %
self.PluginNameShort,
unicode(translate(
'OpenLP.MediaManagerItem', 'Edit the selected %s')) %
self.pluginNameVisible,
edit_string[u'title'],
edit_string[u'tooltip'],
u':/general/general_edit.png', self.onEditClick)
## Delete Button ##
if self.hasDeleteIcon:
delete_string = self.plugin.getString(StringContent.Delete)
self.addToolbarButton(
unicode(translate('OpenLP.MediaManagerItem', 'Delete %s')) %
self.PluginNameShort,
translate('OpenLP.MediaManagerItem',
'Delete the selected item'),
delete_string[u'title'],
delete_string[u'tooltip'],
u':/general/general_delete.png', self.onDeleteClick)
## Separator Line ##
self.addToolbarSeparator()
## Preview ##
preview_string = self.plugin.getString(StringContent.Preview)
self.addToolbarButton(
unicode(translate('OpenLP.MediaManagerItem', 'Preview %s')) %
self.PluginNameShort,
translate('OpenLP.MediaManagerItem', 'Preview the selected item'),
preview_string[u'title'],
preview_string[u'tooltip'],
u':/general/general_preview.png', self.onPreviewClick)
## Live Button ##
live_string = self.plugin.getString(StringContent.Live)
self.addToolbarButton(
u'Go Live',
translate('OpenLP.MediaManagerItem', 'Send the selected item live'),
live_string[u'title'],
live_string[u'tooltip'],
u':/general/general_live.png', self.onLiveClick)
## Add to service Button ##
service_string = self.plugin.getString(StringContent.Service)
self.addToolbarButton(
unicode(translate('OpenLP.MediaManagerItem', 'Add %s to Service')) %
self.PluginNameShort,
translate('OpenLP.MediaManagerItem',
'Add the selected item(s) to the service'),
service_string[u'title'],
service_string[u'tooltip'],
u':/general/general_add.png', self.onAddClick)
def addListViewToToolBar(self):
@ -281,17 +274,18 @@ class MediaManagerItem(QtGui.QWidget):
QtGui.QAbstractItemView.ExtendedSelection)
self.listView.setAlternatingRowColors(True)
self.listView.setDragEnabled(True)
self.listView.setObjectName(u'%sListView' % self.PluginNameShort)
self.listView.setObjectName(u'%sListView' % self.plugin.name)
#Add to pageLayout
self.pageLayout.addWidget(self.listView)
#define and add the context menu
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
name_string = self.plugin.getString(StringContent.Name)
if self.hasEditIcon:
self.listView.addAction(
context_menu_action(
self.listView, u':/general/general_edit.png',
unicode(translate('OpenLP.MediaManagerItem', '&Edit %s')) %
self.pluginNameVisible,
name_string[u'singular'],
self.onEditClick))
self.listView.addAction(context_menu_separator(self.listView))
if self.hasDeleteIcon:
@ -300,14 +294,14 @@ class MediaManagerItem(QtGui.QWidget):
self.listView, u':/general/general_delete.png',
unicode(translate('OpenLP.MediaManagerItem',
'&Delete %s')) %
self.pluginNameVisible,
name_string[u'singular'],
self.onDeleteClick))
self.listView.addAction(context_menu_separator(self.listView))
self.listView.addAction(
context_menu_action(
self.listView, u':/general/general_preview.png',
unicode(translate('OpenLP.MediaManagerItem', '&Preview %s')) %
self.pluginNameVisible,
name_string[u'singular'],
self.onPreviewClick))
self.listView.addAction(
context_menu_action(
@ -447,7 +441,7 @@ class MediaManagerItem(QtGui.QWidget):
translate('OpenLP.MediaManagerItem',
'You must select one or more items to preview.'))
else:
log.debug(self.PluginNameShort + u' Preview requested')
log.debug(self.plugin.name + u' Preview requested')
service_item = self.buildServiceItem()
if service_item:
service_item.from_plugin = True
@ -464,7 +458,7 @@ class MediaManagerItem(QtGui.QWidget):
translate('OpenLP.MediaManagerItem',
'You must select one or more items to send live.'))
else:
log.debug(self.PluginNameShort + u' Live requested')
log.debug(self.plugin.name + u' Live requested')
service_item = self.buildServiceItem()
if service_item:
service_item.from_plugin = True
@ -480,10 +474,10 @@ class MediaManagerItem(QtGui.QWidget):
translate('OpenLP.MediaManagerItem',
'You must select one or more items.'))
else:
#Is it posssible to process multiple list items to generate multiple
#service items?
# Is it posssible to process multiple list items to generate multiple
# service items?
if self.singleServiceItem or self.remoteTriggered:
log.debug(self.PluginNameShort + u' Add requested')
log.debug(self.plugin.name + u' Add requested')
service_item = self.buildServiceItem()
if service_item:
service_item.from_plugin = False
@ -507,10 +501,10 @@ class MediaManagerItem(QtGui.QWidget):
translate('OpenLP.MediaManagerItem',
'You must select one or more items'))
else:
log.debug(self.PluginNameShort + u' Add requested')
log.debug(self.plugin.name + u' Add requested')
service_item = self.parent.serviceManager.getServiceItem()
if not service_item:
QtGui.QMessageBox.information(self,
QtGui.QMessageBox.information(self,
translate('OpenLP.MediaManagerItem',
'No Service Item Selected'),
translate('OpenLP.MediaManagerItem',
@ -540,3 +534,11 @@ class MediaManagerItem(QtGui.QWidget):
return service_item
else:
return None
def serviceLoad(self, message):
"""
Method to add processing when a service has been loaded and
individual service items need to be processed by the plugins
"""
pass

View File

@ -42,6 +42,18 @@ class PluginStatus(object):
Inactive = 0
Disabled = -1
class StringContent(object):
Name = u'name'
Import = u'import'
Load = u'load'
New = u'new'
Edit = u'edit'
Delete = u'delete'
Preview = u'preview'
Live = u'live'
Service = u'service'
VisibleName = u'visible_name'
class Plugin(QtCore.QObject):
"""
Base class for openlp plugins to inherit from.
@ -117,6 +129,8 @@ class Plugin(QtCore.QObject):
"""
QtCore.QObject.__init__(self)
self.name = name
self.textStrings = {}
self.setPluginTextStrings()
if version:
self.version = version
self.settingsSection = self.name.lower()
@ -257,9 +271,9 @@ class Plugin(QtCore.QObject):
Called by the plugin to remove toolbar
"""
if self.mediaItem:
self.mediadock.remove_dock(self.name)
self.mediadock.remove_dock(self.mediaItem)
if self.settings_tab:
self.settingsForm.removeTab(self.name)
self.settingsForm.removeTab(self.settings_tab)
def insertToolboxItem(self):
"""
@ -289,3 +303,15 @@ class Plugin(QtCore.QObject):
The new name the plugin should now use.
"""
pass
def getString(self, name):
"""
encapsulate access of plugins translated text strings
"""
return self.textStrings[name]
def setPluginTextStrings(self):
"""
Called to define all translatable texts of the plugin
"""
pass

View File

@ -30,7 +30,7 @@ import os
import sys
import logging
from openlp.core.lib import Plugin, PluginStatus
from openlp.core.lib import Plugin, StringContent, PluginStatus
log = logging.getLogger(__name__)
@ -152,12 +152,13 @@ class PluginManager(object):
for plugin in self.plugins:
if plugin.status is not PluginStatus.Disabled:
plugin.settings_tab = plugin.getSettingsTab()
visible_title = plugin.getString(StringContent.VisibleName)
if plugin.settings_tab:
log.debug(u'Inserting settings tab item from %s' %
plugin.name)
settingsform.addTab(plugin.name, plugin.settings_tab)
visible_title[u'title'])
settingsform.addTab(visible_title[u'title'], plugin.settings_tab)
else:
log.debug(u'No tab settings in %s' % plugin.name)
log.debug(u'No tab settings in %s' % visible_title[u'title'])
def hook_import_menu(self, import_menu):
"""

View File

@ -58,6 +58,9 @@ class ItemCapabilities(object):
AllowsLoop = 5
AllowsAdditions = 6
NoLineBreaks = 7
OnLoadUpdate = 8
AddIfNewItem = 9
class ServiceItem(object):
"""
@ -98,6 +101,9 @@ class ServiceItem(object):
self.main = None
self.footer = None
self.bg_image_bytes = None
self.search_string = u''
self.data_string = u''
self._new_item()
def _new_item(self):
"""
@ -149,15 +155,15 @@ class ServiceItem(object):
line_break = True
if self.is_capable(ItemCapabilities.NoLineBreaks):
line_break = False
theme = None
if self.theme:
theme = self.theme
self.main, self.footer = \
self.render_manager.set_override_theme(theme, useOverride)
self.bg_image_bytes = self.render_manager.renderer.bg_image_bytes
self.themedata = self.render_manager.renderer._theme
if self.service_item_type == ServiceItemType.Text:
log.debug(u'Formatting slides')
theme = None
if self.theme:
theme = self.theme
self.main, self.footer = \
self.render_manager.set_override_theme(theme, useOverride)
self.bg_image_bytes = self.render_manager.renderer.bg_image_bytes
self.themedata = self.render_manager.renderer._theme
for slide in self._raw_frames:
before = time.time()
formatted = self.render_manager \
@ -170,7 +176,6 @@ class ServiceItem(object):
u'verseTag': slide[u'verseTag'] })
log.log(15, u'Formatting took %4s' % (time.time() - before))
elif self.service_item_type == ServiceItemType.Image:
self.themedata = self.render_manager.global_theme_data
for slide in self._raw_frames:
slide[u'image'] = resize_image(slide[u'image'],
self.render_manager.width, self.render_manager.height)
@ -255,7 +260,9 @@ class ServiceItem(object):
u'audit':self.audit,
u'notes':self.notes,
u'from_plugin':self.from_plugin,
u'capabilities':self.capabilities
u'capabilities':self.capabilities,
u'search':self.search_string,
u'data':self.data_string
}
service_data = []
if self.service_item_type == ServiceItemType.Text:
@ -293,6 +300,10 @@ class ServiceItem(object):
self.notes = header[u'notes']
self.from_plugin = header[u'from_plugin']
self.capabilities = header[u'capabilities']
# Added later so may not be present in older services.
if u'search' in header:
self.search_string = header[u'search']
self.data_string = header[u'data']
if self.service_item_type == ServiceItemType.Text:
for slide in serviceitem[u'serviceitem'][u'data']:
self._raw_frames.append(slide)
@ -388,6 +399,6 @@ class ServiceItem(object):
def get_frame_path(self, row=0):
"""
Returns the title of the raw frame
Returns the path of the raw frame
"""
return self._raw_frames[row][u'path']

View File

@ -31,16 +31,19 @@ class SettingsTab(QtGui.QWidget):
SettingsTab is a helper widget for plugins to define Tabs for the settings
dialog.
"""
def __init__(self, title):
def __init__(self, title, visible_title=None):
"""
Constructor to create the Settings tab item.
``title``
The title of the tab, which is used internally for the tab handling.
``visible_title``
The title of the tab, which is usually displayed on the tab.
"""
QtGui.QWidget.__init__(self)
self.tabTitle = title
self.tabTitleVisible = None
self.tabTitleVisible = visible_title
self.settingsSection = self.tabTitle.lower()
self.setupUi()
self.retranslateUi()

View File

@ -82,6 +82,9 @@ class AdvancedTab(SettingsTab):
self.doubleClickLiveCheckBox.setObjectName(u'doubleClickLiveCheckBox')
self.uiLayout.addWidget(self.doubleClickLiveCheckBox)
self.leftLayout.addWidget(self.uiGroupBox)
self.expandServiceItemCheckBox = QtGui.QCheckBox(self.uiGroupBox)
self.expandServiceItemCheckBox.setObjectName(u'expandServiceItemCheckBox')
self.uiLayout.addWidget(self.expandServiceItemCheckBox)
# self.sharedDirGroupBox = QtGui.QGroupBox(self.leftWidget)
# self.sharedDirGroupBox.setObjectName(u'sharedDirGroupBox')
# self.sharedDirGroupBox.setGeometry(QtCore.QRect(0, 65, 500, 85))
@ -140,6 +143,8 @@ class AdvancedTab(SettingsTab):
'Remember active media manager tab on startup'))
self.doubleClickLiveCheckBox.setText(translate('OpenLP.AdvancedTab',
'Double-click to send items straight to live (requires restart)'))
self.expandServiceItemCheckBox.setText(translate('OpenLP.AdvancedTab',
'Expand new service items on creation'))
# self.sharedDirGroupBox.setTitle(
# translate('AdvancedTab', 'Central Data Store'))
# self.sharedCheckBox.setText(
@ -167,6 +172,9 @@ class AdvancedTab(SettingsTab):
self.doubleClickLiveCheckBox.setChecked(
settings.value(u'double click live',
QtCore.QVariant(False)).toBool())
self.expandServiceItemCheckBox.setChecked(
settings.value(u'expand service item',
QtCore.QVariant(False)).toBool())
settings.endGroup()
def save(self):
@ -181,6 +189,8 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(self.mediaPluginCheckBox.isChecked()))
settings.setValue(u'double click live',
QtCore.QVariant(self.doubleClickLiveCheckBox.isChecked()))
settings.setValue(u'expand service item',
QtCore.QVariant(self.expandServiceItemCheckBox.isChecked()))
settings.endGroup()
def onSharedCheckBoxChanged(self, checked):

View File

@ -114,21 +114,23 @@ class MainDisplay(DisplayWidget):
"""
log.debug(u'Setup live = %s for %s ' % (self.isLive,
self.screens.monitor_number))
self.usePhonon = QtCore.QSettings().value(
u'media/use phonon', QtCore.QVariant(True)).toBool()
self.phononActive = False
self.screen = self.screens.current
self.setVisible(False)
self.setGeometry(self.screen[u'size'])
try:
self.webView = QtWebKit.QGraphicsWebView()
self.scene = QtGui.QGraphicsScene(self)
self.setScene(self.scene)
self.scene.addItem(self.webView)
self.webView.setGeometry(QtCore.QRectF(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height()))
except AttributeError:
# QGraphicsWebView a recent addition, so fall back to QWebView
self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height())
self.videoWidget = Phonon.VideoWidget(self)
self.videoWidget.setVisible(False)
self.videoWidget.setGeometry(QtCore.QRect(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height()))
self.mediaObject = Phonon.MediaObject(self)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.videoWidget)
Phonon.createPath(self.mediaObject, self.audio)
self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height())
self.page = self.webView.page()
self.frame = self.page.mainFrame()
QtCore.QObject.connect(self.webView,
@ -182,7 +184,7 @@ class MainDisplay(DisplayWidget):
`slide`
The slide text to be displayed
"""
log.debug(u'text')
log.debug(u'text to display')
# Wait for the webview to update before displayiong text.
while not self.loaded:
Receiver.send_message(u'openlp_process_events')
@ -197,9 +199,9 @@ class MainDisplay(DisplayWidget):
`slide`
The slide text to be displayed
"""
log.debug(u'alert')
log.debug(u'alert to display')
if self.height() != self.screen[u'size'].height() \
or not self.isVisible():
or not self.isVisible() or self.videoWidget.isVisible():
shrink = True
else:
shrink = False
@ -208,12 +210,17 @@ class MainDisplay(DisplayWidget):
u'top' if shrink else u'')
height = self.frame.evaluateJavaScript(js)
if shrink:
if text:
self.resize(self.width(), int(height.toString()))
self.setVisible(True)
if self.phononActive:
shrinkItem = self.webView
else:
self.setGeometry(self.screen[u'size'])
self.setVisible(False)
shrinkItem = self
if text:
shrinkItem.resize(self.width(), int(height.toString()))
shrinkItem.setVisible(True)
else:
shrinkItem.setVisible(False)
shrinkItem.resize(self.screen[u'size'].width(),
self.screen[u'size'].height())
def image(self, image):
"""
@ -223,9 +230,10 @@ class MainDisplay(DisplayWidget):
`Image`
The Image to be displayed can be QImage or QPixmap
"""
log.debug(u'image')
image = resize_image(image, self.screen[u'size'].width(),
self.screen[u'size'].height())
log.debug(u'image to display')
if not isinstance(image, QtGui.QImage):
image = resize_image(image, self.screen[u'size'].width(),
self.screen[u'size'].height())
self.resetVideo()
self.displayImage(image)
# show screen
@ -259,14 +267,24 @@ class MainDisplay(DisplayWidget):
Used after Video plugin has changed the background
"""
log.debug(u'resetVideo')
self.frame.evaluateJavaScript(u'show_video("close");')
if self.phononActive:
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.webView.setVisible(True)
self.videoWidget.setVisible(False)
self.phononActive = False
else:
self.frame.evaluateJavaScript(u'show_video("close");')
def videoPlay(self):
"""
Responds to the request to play a loaded video
"""
log.debug(u'videoPlay')
self.frame.evaluateJavaScript(u'show_video("play");')
if self.phononActive:
self.mediaObject.play()
else:
self.frame.evaluateJavaScript(u'show_video("play");')
# show screen
if self.isLive:
self.setVisible(True)
@ -276,32 +294,54 @@ class MainDisplay(DisplayWidget):
Responds to the request to pause a loaded video
"""
log.debug(u'videoPause')
self.frame.evaluateJavaScript(u'show_video("pause");')
if self.phononActive:
self.mediaObject.pause()
else:
self.frame.evaluateJavaScript(u'show_video("pause");')
def videoStop(self):
"""
Responds to the request to stop a loaded video
"""
log.debug(u'videoStop')
self.frame.evaluateJavaScript(u'show_video("stop");')
if self.phononActive:
self.mediaObject.stop()
else:
self.frame.evaluateJavaScript(u'show_video("stop");')
def videoVolume(self, volume):
"""
Changes the volume of a running video
"""
log.debug(u'videoVolume %d' % volume)
self.frame.evaluateJavaScript(u'show_video(null, null, %s);' %
str(float(volume)/float(10)))
vol = float(volume)/float(10)
if self.phononActive:
self.audio.setVolume(vol)
else:
self.frame.evaluateJavaScript(u'show_video(null, null, %s);' %
str(vol))
def video(self, videoPath, volume):
def video(self, videoPath, volume, isBackground=False):
"""
Loads and starts a video to run with the option of sound
"""
log.debug(u'video')
self.loaded = True
js = u'show_video("init", "%s", %s, true); show_video("play");' % \
(videoPath.replace(u'\\', u'\\\\'), str(float(volume)/float(10)))
self.frame.evaluateJavaScript(js)
vol = float(volume)/float(10)
if isBackground or not self.usePhonon:
js = u'show_video("init", "%s", %s, true); show_video("play");' % \
(videoPath.replace(u'\\', u'\\\\'), \
str(vol))
self.frame.evaluateJavaScript(js)
else:
self.phononActive = True
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.mediaObject.setCurrentSource(Phonon.MediaSource(videoPath))
self.mediaObject.play()
self.webView.setVisible(False)
self.videoWidget.setVisible(True)
self.audio.setVolume(vol)
return self.preview()
def isLoaded(self):
@ -382,6 +422,8 @@ class MainDisplay(DisplayWidget):
Store the images so they can be replaced when required
"""
log.debug(u'hideDisplay mode = %d', mode)
if self.phononActive:
self.videoPause()
if mode == HideMode.Screen:
self.frame.evaluateJavaScript(u'show_blank("desktop");')
self.setVisible(False)
@ -389,8 +431,11 @@ class MainDisplay(DisplayWidget):
self.frame.evaluateJavaScript(u'show_blank("black");')
else:
self.frame.evaluateJavaScript(u'show_blank("theme");')
if mode != HideMode.Screen and self.isHidden():
self.setVisible(True)
if mode != HideMode.Screen:
if self.isHidden():
self.setVisible(True)
if self.phononActive:
self.webView.setVisible(True)
self.hide_mode = mode
def showDisplay(self):
@ -403,6 +448,9 @@ class MainDisplay(DisplayWidget):
self.frame.evaluateJavaScript('show_blank("show");')
if self.isHidden():
self.setVisible(True)
if self.phononActive:
self.webView.setVisible(False)
self.videoPlay()
# Trigger actions when display is active again
Receiver.send_message(u'maindisplay_active')
self.hide_mode = None
@ -484,3 +532,4 @@ class AudioPlayer(QtCore.QObject):
"""
log.debug(u'AudioPlayer Reached end of media playlist')
self.mediaObject.clearQueue()

View File

@ -175,19 +175,13 @@ class Ui_MainWindow(object):
QtCore.Qt.DockWidgetArea(2), self.ThemeManagerDock)
# Create the menu items
self.FileNewItem = QtGui.QAction(MainWindow)
self.FileNewItem.setIcon(
self.ServiceManagerContents.toolbar.getIconFromTitle(
u'New Service'))
self.FileNewItem.setIcon(build_icon(u':/general/general_new.png'))
self.FileNewItem.setObjectName(u'FileNewItem')
self.FileOpenItem = QtGui.QAction(MainWindow)
self.FileOpenItem.setIcon(
self.ServiceManagerContents.toolbar.getIconFromTitle(
u'Open Service'))
self.FileOpenItem.setIcon(build_icon(u':/general/general_open.png'))
self.FileOpenItem.setObjectName(u'FileOpenItem')
self.FileSaveItem = QtGui.QAction(MainWindow)
self.FileSaveItem.setIcon(
self.ServiceManagerContents.toolbar.getIconFromTitle(
u'Save Service'))
self.FileSaveItem.setIcon(build_icon(u':/general/general_save.png'))
self.FileSaveItem.setObjectName(u'FileSaveItem')
self.FileSaveAsItem = QtGui.QAction(MainWindow)
self.FileSaveAsItem.setObjectName(u'FileSaveAsItem')
@ -343,7 +337,6 @@ class Ui_MainWindow(object):
Set up the translation system
"""
MainWindow.mainTitle = translate('OpenLP.MainWindow', 'OpenLP 2.0')
# MainWindow.language = translate('OpenLP.MainWindow', 'English')
MainWindow.setWindowTitle(MainWindow.mainTitle)
self.FileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
self.FileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))

View File

@ -26,6 +26,8 @@
import logging
from openlp.core.lib import StringContent
log = logging.getLogger(__name__)
class MediaDockManager(object):
@ -48,8 +50,9 @@ class MediaDockManager(object):
``icon``
An icon for this dock item
"""
log.info(u'Adding %s dock' % media_item.title)
self.media_dock.addItem(media_item, icon, media_item.title)
visible_title = media_item.plugin.getString(StringContent.VisibleName)
log.info(u'Adding %s dock' % visible_title)
self.media_dock.addItem(media_item, icon, visible_title[u'title'])
def insert_dock(self, media_item, icon, weight):
"""
@ -57,27 +60,29 @@ class MediaDockManager(object):
This does not work as it gives a Segmentation error.
For now add at end of stack if not present
"""
log.debug(u'Inserting %s dock' % media_item.title)
visible_title = media_item.plugin.getString(StringContent.VisibleName)
log.debug(u'Inserting %s dock' % visible_title[u'title'])
match = False
for dock_index in range(0, self.media_dock.count()):
if self.media_dock.widget(dock_index).settingsSection == \
media_item.title.lower():
media_item.plugin.name.lower():
match = True
break
if not match:
self.media_dock.addItem(media_item, icon, media_item.title)
self.media_dock.addItem(media_item, icon, visible_title[u'title'])
def remove_dock(self, name):
def remove_dock(self, media_item):
"""
Removes a MediaManagerItem from the dock
``name``
The item to remove
``media_item``
The item to add to the dock
"""
log.debug(u'remove %s dock' % name)
visible_title = media_item.plugin.getString(StringContent.VisibleName)
log.debug(u'remove %s dock' % visible_title[u'title'])
for dock_index in range(0, self.media_dock.count()):
if self.media_dock.widget(dock_index):
if self.media_dock.widget(dock_index).settingsSection == \
name.lower():
media_item.plugin.name.lower():
self.media_dock.widget(dock_index).hide()
self.media_dock.removeItem(dock_index)

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import PluginStatus, translate
from openlp.core.lib import PluginStatus, StringContent, translate
from plugindialog import Ui_PluginViewDialog
log = logging.getLogger(__name__)
@ -78,7 +78,8 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
elif plugin.status == PluginStatus.Disabled:
status_text = unicode(
translate('OpenLP.PluginForm', '%s (Disabled)'))
item.setText(status_text % plugin.name)
name_string = plugin.getString(StringContent.Name)
item.setText(status_text % name_string[u'plural'])
# If the plugin has an icon, set it!
if plugin.icon:
item.setIcon(plugin.icon)
@ -106,10 +107,11 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
if self.pluginListWidget.currentItem() is None:
self._clearDetails()
return
plugin_name = self.pluginListWidget.currentItem().text().split(u' ')[0]
plugin_name_plural = self.pluginListWidget.currentItem().text().split(u' ')[0]
self.activePlugin = None
for plugin in self.parent.plugin_manager.plugins:
if plugin.name == plugin_name:
name_string = plugin.getString(StringContent.Name)
if name_string[u'plural'] == plugin_name_plural:
self.activePlugin = plugin
break
if self.activePlugin:
@ -137,5 +139,6 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
elif self.activePlugin.status == PluginStatus.Disabled:
status_text = unicode(
translate('OpenLP.PluginForm', '%s (Disabled)'))
name_string = self.activePlugin.getString(StringContent.Name)
self.pluginListWidget.currentItem().setText(
status_text % self.activePlugin.name)
status_text % name_string[u'plural'])

View File

@ -107,6 +107,7 @@ class ServiceManager(QtGui.QWidget):
self.serviceName = u''
self.suffixes = []
self.droppos = 0
self.expandTabs = False
#is a new service and has not been saved
self.isNew = True
self.serviceNoteForm = ServiceNoteForm(self.parent)
@ -199,6 +200,19 @@ class ServiceManager(QtGui.QWidget):
translate('OpenLP.ServiceManager',
'Delete the selected item from the service.'),
self.onDeleteFromService)
self.orderToolbar.addSeparator()
self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Expand all'),
u':/services/service_top.png',
translate('OpenLP.ServiceManager',
'Expand all the service items.'),
self.onExpandAll)
self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Collapse all'),
u':/services/service_bottom.png',
translate('OpenLP.ServiceManager',
'Collapse all the service items.'),
self.onCollapseAll)
self.layout.addWidget(self.orderToolbar)
# Connect up our signals and slots
QtCore.QObject.connect(self.themeComboBox,
@ -220,9 +234,11 @@ class ServiceManager(QtGui.QWidget):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_list_request'), self.listRequest)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.regenerateServiceItems)
QtCore.SIGNAL(u'config_updated'), self.configUpdated)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_global'), self.themeChange)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate)
# Last little bits of setting up
self.service_theme = unicode(QtCore.QSettings().value(
self.parent.serviceSettingsSection + u'/service theme',
@ -263,6 +279,17 @@ class ServiceManager(QtGui.QWidget):
self.themeMenu = QtGui.QMenu(
translate('OpenLP.ServiceManager', '&Change Item Theme'))
self.menu.addMenu(self.themeMenu)
self.configUpdated(True)
def configUpdated(self, firstTime=False):
"""
Triggered when Config dialog is updated.
"""
self.expandTabs = QtCore.QSettings().value(
u'advanced/expand service item',
QtCore.QVariant(u'False')).toBool()
if not firstTime:
self.regenerateServiceItems()
def supportedSuffixes(self, suffix):
self.suffixes.append(suffix)
@ -319,7 +346,7 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems[item][u'service_item'])
if self.serviceItemEditForm.exec_():
self.addServiceItem(self.serviceItemEditForm.getServiceItem(),
replace=True)
replace=True, expand=self.serviceItems[item][u'expand'])
def nextItem(self):
"""
@ -421,6 +448,14 @@ class ServiceManager(QtGui.QWidget):
if setSelected:
firstItem.setSelected(True)
def onCollapseAll(self):
"""
Collapse all the service items
"""
for item in self.serviceItems:
item[u'expanded'] = False
self.regenerateServiceItems()
def collapsed(self, item):
"""
Record if an item is collapsed
@ -429,6 +464,14 @@ class ServiceManager(QtGui.QWidget):
pos = item.data(0, QtCore.Qt.UserRole).toInt()[0]
self.serviceItems[pos -1 ][u'expanded'] = False
def onExpandAll(self):
"""
Collapse all the service items
"""
for item in self.serviceItems:
item[u'expanded'] = True
self.regenerateServiceItems()
def expanded(self, item):
"""
Record if an item is collapsed
@ -526,12 +569,12 @@ class ServiceManager(QtGui.QWidget):
Used when moving items as the move takes place in supporting array,
and when regenerating all the items due to theme changes
"""
#Correct order of items in array
# Correct order of items in array
count = 1
for item in self.serviceItems:
item[u'order'] = count
count += 1
#Repaint the screen
# Repaint the screen
self.serviceManagerList.clear()
for itemcount, item in enumerate(self.serviceItems):
serviceitem = item[u'service_item']
@ -600,6 +643,7 @@ class ServiceManager(QtGui.QWidget):
zip = None
file = None
try:
write_list = []
zip = zipfile.ZipFile(unicode(filename), 'w')
for item in self.serviceItems:
service.append({u'serviceitem':item[u'service_item']
@ -609,7 +653,10 @@ class ServiceManager(QtGui.QWidget):
path_from = unicode(os.path.join(
frame[u'path'],
frame[u'title']))
zip.write(path_from.encode(u'utf-8'))
# On write a file once
if not path_from in write_list:
write_list.append(path_from)
zip.write(path_from.encode(u'utf-8'))
file = open(servicefile, u'wb')
cPickle.dump(service, file)
file.close()
@ -711,6 +758,9 @@ class ServiceManager(QtGui.QWidget):
serviceitem.set_from_service(item, self.servicePath)
self.validateItem(serviceitem)
self.addServiceItem(serviceitem)
if serviceitem.is_capable(ItemCapabilities.OnLoadUpdate):
Receiver.send_message(u'%s_service_load' %
serviceitem.name.lower(), serviceitem)
try:
if os.path.isfile(p_file):
os.remove(p_file)
@ -796,19 +846,48 @@ class ServiceManager(QtGui.QWidget):
self.isNew = True
for item in tempServiceItems:
self.addServiceItem(
item[u'service_item'], False, item[u'expanded'])
item[u'service_item'], False, expand=item[u'expanded'])
# Set to False as items may have changed rendering
# does not impact the saved song so True may also be valid
self.parent.serviceChanged(False, self.serviceName)
def addServiceItem(self, item, rebuild=False, expand=True, replace=False):
def serviceItemUpdate(self, message):
"""
Triggered from plugins to update service items.
"""
editId, uuid = message.split(u':')
for item in self.serviceItems:
if item[u'service_item']._uuid == uuid:
item[u'service_item'].editId = editId
def replaceServiceItem(self, newItem):
"""
Using the service item passed replace the one with the same edit id
if found.
"""
newItem.render()
for itemcount, item in enumerate(self.serviceItems):
if item[u'service_item'].editId == newItem.editId and \
item[u'service_item'].name == newItem.name:
newItem.merge(item[u'service_item'])
item[u'service_item'] = newItem
self.repaintServiceList(itemcount + 1, 0)
self.parent.LiveController.replaceServiceManagerItem(newItem)
self.parent.serviceChanged(False, self.serviceName)
def addServiceItem(self, item, rebuild=False, expand=None, replace=False):
"""
Add a Service item to the list
``item``
Service Item to be added
``expand``
Override the default expand settings. (Tristate)
"""
log.debug(u'addServiceItem')
if expand == None:
expand = self.expandTabs
sitem = self.findServiceItem()[0]
item.render()
if replace:
@ -817,7 +896,7 @@ class ServiceManager(QtGui.QWidget):
self.repaintServiceList(sitem + 1, 0)
self.parent.LiveController.replaceServiceManagerItem(item)
else:
#nothing selected for dnd
# nothing selected for dnd
if self.droppos == 0:
if isinstance(item, list):
for inditem in item:
@ -834,7 +913,7 @@ class ServiceManager(QtGui.QWidget):
u'order': self.droppos,
u'expanded':expand})
self.repaintServiceList(self.droppos, 0)
#if rebuilding list make sure live is fixed.
# if rebuilding list make sure live is fixed.
if rebuild:
self.parent.LiveController.replaceServiceManagerItem(item)
self.droppos = 0
@ -914,7 +993,7 @@ class ServiceManager(QtGui.QWidget):
else:
pos = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
count = item.data(0, QtCore.Qt.UserRole).toInt()[0]
#adjust for zero based arrays
# adjust for zero based arrays
pos = pos - 1
return pos, count
@ -940,7 +1019,7 @@ class ServiceManager(QtGui.QWidget):
if link.hasText():
plugin = event.mimeData().text()
item = self.serviceManagerList.itemAt(event.pos())
#ServiceManager started the drag and drop
# ServiceManager started the drag and drop
if plugin == u'ServiceManager':
startpos, startCount = self.findServiceItem()
if item is None:
@ -952,22 +1031,22 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems.insert(endpos, serviceItem)
self.repaintServiceList(endpos, startCount)
else:
#we are not over anything so drop
# we are not over anything so drop
replace = False
if item is None:
self.droppos = len(self.serviceItems)
else:
#we are over somthing so lets investigate
# we are over somthing so lets investigate
pos = self._getParentItemData(item) - 1
serviceItem = self.serviceItems[pos]
if (plugin == serviceItem[u'service_item'].name and
serviceItem[u'service_item'].is_capable(
ItemCapabilities.AllowsAdditions)):
action = self.dndMenu.exec_(QtGui.QCursor.pos())
#New action required
# New action required
if action == self.newAction:
self.droppos = self._getParentItemData(item)
#Append to existing action
# Append to existing action
if action == self.addToAction:
self.droppos = self._getParentItemData(item)
item.setSelected(True)

View File

@ -72,14 +72,15 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
self.settingsTabWidget.insertTab(
location + 14, tab, tab.tabTitleVisible)
def removeTab(self, name):
def removeTab(self, tab):
"""
Remove a tab from the form
"""
log.debug(u'remove %s tab' % name)
log.debug(u'remove %s tab' % tab.tabTitleVisible)
for tabIndex in range(0, self.settingsTabWidget.count()):
if self.settingsTabWidget.widget(tabIndex):
if self.settingsTabWidget.widget(tabIndex).tabTitle == name:
if self.settingsTabWidget.widget(tabIndex).tabTitleVisible == \
tab.tabTitleVisible:
self.settingsTabWidget.removeTab(tabIndex)
def accept(self):

View File

@ -179,19 +179,24 @@ class SlideController(QtGui.QWidget):
self.HideMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Hide'), self.Toolbar))
self.BlankScreen = QtGui.QAction(QtGui.QIcon(
u':/slides/slide_blank.png'), u'Blank Screen', self.HideMenu)
u':/slides/slide_blank.png'),
translate('OpenLP.SlideController',
'Blank Screen'), self.HideMenu)
self.BlankScreen.setCheckable(True)
QtCore.QObject.connect(self.BlankScreen,
QtCore.SIGNAL("triggered(bool)"), self.onBlankDisplay)
self.ThemeScreen = QtGui.QAction(QtGui.QIcon(
u':/slides/slide_theme.png'), u'Blank to Theme', self.HideMenu)
u':/slides/slide_theme.png'),
translate('OpenLP.SlideController',
'Blank to Theme'), self.HideMenu)
self.ThemeScreen.setCheckable(True)
QtCore.QObject.connect(self.ThemeScreen,
QtCore.SIGNAL("triggered(bool)"), self.onThemeDisplay)
if self.screens.display_count > 1:
self.DesktopScreen = QtGui.QAction(QtGui.QIcon(
u':/slides/slide_desktop.png'), u'Show Desktop',
self.HideMenu)
u':/slides/slide_desktop.png'),
translate('OpenLP.SlideController',
'Show Desktop'), self.HideMenu)
self.DesktopScreen.setCheckable(True)
QtCore.QObject.connect(self.DesktopScreen,
QtCore.SIGNAL("triggered(bool)"), self.onHideDisplay)
@ -209,7 +214,7 @@ class SlideController(QtGui.QWidget):
self.Toolbar.addToolbarSeparator(u'Close Separator')
self.Toolbar.addToolbarButton(
u'Edit Song', u':/general/general_edit.png',
translate('OpenLP.SlideController',
translate('OpenLP.SlideController',
'Edit and reload song preview'),
self.onEditSong)
if isLive:
@ -538,7 +543,7 @@ class SlideController(QtGui.QWidget):
Receiver.send_message(u'%s_stop' %
self.serviceItem.name.lower(), [serviceItem, self.isLive])
if self.serviceItem.is_media():
self.onMediaStop()
self.onMediaClose()
if self.isLive:
blanked = self.BlankScreen.isChecked()
else:
@ -579,11 +584,14 @@ class SlideController(QtGui.QWidget):
else:
label = QtGui.QLabel()
label.setMargin(4)
pixmap = resize_image(frame[u'image'],
self.parent.RenderManager.width,
self.parent.RenderManager.height)
label.setScaledContents(True)
label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
if isinstance(frame[u'image'], QtGui.QImage):
label.setPixmap(QtGui.QPixmap.fromImage(frame[u'image']))
else:
pixmap = resize_image(frame[u'image'],
self.parent.RenderManager.width,
self.parent.RenderManager.height)
label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
self.PreviewListWidget.setCellWidget(framenumber, 0, label)
slideHeight = width * self.parent.RenderManager.screen_ratio
row += 1
@ -926,14 +934,13 @@ class SlideController(QtGui.QWidget):
Respond to the arrival of a media service item
"""
log.debug(u'SlideController onMediaStart')
file = os.path.join(item.get_frame_path(), item.get_frame_title())
if self.isLive:
file = os.path.join(item.get_frame_path(), item.get_frame_title())
self.display.video(file, self.volume)
self.volumeSlider.setValue(self.volume)
else:
self.mediaObject.stop()
self.mediaObject.clearQueue()
file = os.path.join(item.get_frame_path(), item.get_frame_title())
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
self.seekSlider.setMediaObject(self.mediaObject)
self.seekSlider.show()
@ -981,3 +988,17 @@ class SlideController(QtGui.QWidget):
self.video.hide()
self.SlidePreview.clear()
self.SlidePreview.show()
def onMediaClose(self):
"""
Respond to a request to close the Video
"""
log.debug(u'SlideController onMediaStop')
if self.isLive:
self.display.resetVideo()
else:
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.video.hide()
self.SlidePreview.clear()
self.SlidePreview.show()

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, translate
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.db import Manager
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
from openlp.plugins.alerts.lib.db import init_schema
@ -45,13 +45,15 @@ class AlertsPlugin(Plugin):
self.icon = build_icon(u':/plugins/plugin_alerts.png')
self.alertsmanager = AlertsManager(self)
self.manager = Manager(u'alerts', init_schema)
self.alertForm = AlertForm(self)
visible_name = self.getString(StringContent.VisibleName)
self.alertForm = AlertForm(self, visible_name[u'title'])
def getSettingsTab(self):
"""
Return the settings tab for the Alerts plugin
"""
self.alertsTab = AlertsTab(self)
visible_name = self.getString(StringContent.VisibleName)
self.alertsTab = AlertsTab(self, visible_name[u'title'])
return self.alertsTab
def addToolsMenuItem(self, tools_menu):
@ -101,3 +103,17 @@ class AlertsPlugin(Plugin):
'<br />The alert plugin controls the displaying of nursery alerts '
'on the display screen')
return about_text
def setPluginTextStrings(self):
"""
Called to define all translatable texts of the plugin
"""
## Name PluginList ##
self.textStrings[StringContent.Name] = {
u'singular': translate('AlertsPlugin', 'Alert'),
u'plural': translate('AlertsPlugin', 'Alerts')
}
## Name for MediaDockManager, SettingsManager ##
self.textStrings[StringContent.VisibleName] = {
u'title': translate('AlertsPlugin', 'Alerts')
}

View File

@ -35,7 +35,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
"""
Provide UI for the alert system
"""
def __init__(self, plugin):
def __init__(self, plugin, visible_title):
"""
Initialise the alert form
"""

View File

@ -32,14 +32,13 @@ class AlertsTab(SettingsTab):
"""
AlertsTab is the alerts settings tab in the settings dialog.
"""
def __init__(self, parent):
def __init__(self, parent, visible_title):
self.parent = parent
self.manager = parent.manager
SettingsTab.__init__(self, parent.name)
SettingsTab.__init__(self, parent.name, visible_title)
def setupUi(self):
self.setObjectName(u'AlertsTab')
self.tabTitleVisible = translate('AlertsPlugin.AlertsTab', 'Alerts')
self.AlertsLayout = QtGui.QHBoxLayout(self)
self.AlertsLayout.setSpacing(8)
self.AlertsLayout.setMargin(8)
@ -296,4 +295,3 @@ class AlertsTab(SettingsTab):
self.FontPreview.setFont(font)
self.FontPreview.setStyleSheet(u'background-color: %s; color: %s' %
(self.bg_color, self.font_color))

View File

@ -24,6 +24,6 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`bibles' module provides the Bible plugin to enable OpenLP to display
The :mod:`bibles` module provides the Bible plugin to enable OpenLP to display
scripture.
"""

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, translate
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
log = logging.getLogger(__name__)
@ -58,11 +58,12 @@ class BiblePlugin(Plugin):
self.exportBibleItem.setVisible(False)
def getSettingsTab(self):
return BiblesTab(self.name)
visible_name = self.getString(StringContent.VisibleName)
return BiblesTab(self.name, visible_name[u'title'])
def getMediaManagerItem(self):
# Create the BibleManagerItem object.
return BibleMediaItem(self, self.icon, self.name)
return BibleMediaItem(self, self, self.icon)
def addImportMenuItem(self, import_menu):
self.importBibleItem = QtGui.QAction(import_menu)
@ -79,8 +80,7 @@ class BiblePlugin(Plugin):
self.exportBibleItem = QtGui.QAction(export_menu)
self.exportBibleItem.setObjectName(u'exportBibleItem')
export_menu.addAction(self.exportBibleItem)
self.exportBibleItem.setText(translate(
'BiblesPlugin', '&Bible'))
self.exportBibleItem.setText(translate('BiblesPlugin', '&Bible'))
self.exportBibleItem.setVisible(False)
def onBibleImportClick(self):
@ -96,7 +96,6 @@ class BiblePlugin(Plugin):
def usesTheme(self, theme):
"""
Called to find out if the bible plugin is currently using a theme.
Returns True if the theme is being used, otherwise returns False.
"""
if self.settings_tab.bible_theme == theme:
@ -116,3 +115,60 @@ class BiblePlugin(Plugin):
The new name the plugin should now use.
"""
self.settings_tab.bible_theme = newTheme
def setPluginTextStrings(self):
"""
Called to define all translatable texts of the plugin
"""
## Name PluginList ##
self.textStrings[StringContent.Name] = {
u'singular': translate('BiblesPlugin', 'Bible'),
u'plural': translate('BiblesPlugin', 'Bibles')
}
## Name for MediaDockManager, SettingsManager ##
self.textStrings[StringContent.VisibleName] = {
u'title': translate('BiblesPlugin', 'Bibles')
}
# Middle Header Bar
## Import Button ##
self.textStrings[StringContent.Import] = {
u'title': translate('BiblesPlugin', 'Import'),
u'tooltip': translate('BiblesPlugin',
'Import a Bible')
}
## New Button ##
self.textStrings[StringContent.New] = {
u'title': translate('BiblesPlugin', 'Add'),
u'tooltip': translate('BiblesPlugin',
'Add a new Bible')
}
## Edit Button ##
self.textStrings[StringContent.Edit] = {
u'title': translate('BiblesPlugin', 'Edit'),
u'tooltip': translate('BiblesPlugin',
'Edit the selected Bible')
}
## Delete Button ##
self.textStrings[StringContent.Delete] = {
u'title': translate('BiblesPlugin', 'Delete'),
u'tooltip': translate('BiblesPlugin',
'Delete the selected Bible')
}
## Preview ##
self.textStrings[StringContent.Preview] = {
u'title': translate('BiblesPlugin', 'Preview'),
u'tooltip': translate('BiblesPlugin',
'Preview the selected Bible')
}
## Live Button ##
self.textStrings[StringContent.Live] = {
u'title': translate('BiblesPlugin', 'Live'),
u'tooltip': translate('BiblesPlugin',
'Send the selected Bible live')
}
## Add to service Button ##
self.textStrings[StringContent.Service] = {
u'title': translate('BiblesPlugin', 'Service'),
u'tooltip': translate('BiblesPlugin',
'Add the selected Bible to the service')
}

View File

@ -24,6 +24,33 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from importwizardform import ImportWizardForm
"""
Forms in OpenLP are made up of two classes. One class holds all the graphical
elements, like buttons and lists, and the other class holds all the functional
code, like slots and loading and saving.
__all__ = ['ImportWizardForm']
The first class, commonly known as the **Dialog** class, is typically named
``Ui_<name>Dialog``. It is a slightly modified version of the class that the
``pyuic4`` command produces from Qt4's .ui file. Typical modifications will be
converting most strings from "" to u'' and using OpenLP's ``translate()``
function for translating strings.
The second class, commonly known as the **Form** class, is typically named
``<name>Form``. This class is the one which is instantiated and used. It uses
dual inheritance to inherit from (usually) QtGui.QDialog and the Ui class
mentioned above, like so::
class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
def __init__(self, parent, manager, bibleplugin):
QtGui.QWizard.__init__(self, parent)
self.setupUi(self)
This allows OpenLP to use ``self.object`` for all the GUI elements while keeping
them separate from the functionality, so that it is easier to recreate the GUI
from the .ui files later if necessary.
"""
from bibleimportform import BibleImportForm
__all__ = ['BibleImportForm']

View File

@ -54,7 +54,7 @@ class WebDownload(object):
return cls.Names[name]
class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
"""
This is the Bible Import Wizard, which allows easy importing of Bibles
into OpenLP from other formats like OSIS, CSV and OpenSong.
@ -282,7 +282,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.LicenseDetailsPage.registerField(
u'license_copyright', self.CopyrightEdit)
self.LicenseDetailsPage.registerField(
u'license_permission', self.PermissionEdit)
u'license_permissions', self.PermissionsEdit)
def setDefaults(self):
settings = QtCore.QSettings()
@ -308,8 +308,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
QtCore.QVariant(self.VersionNameEdit.text()))
self.setField(u'license_copyright',
QtCore.QVariant(self.CopyrightEdit.text()))
self.setField(u'license_permission',
QtCore.QVariant(self.PermissionEdit.text()))
self.setField(u'license_permissions',
QtCore.QVariant(self.PermissionsEdit.text()))
self.onLocationComboBoxChanged(WebDownload.Crosswalk)
settings.endGroup()
@ -391,8 +391,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
bible_type = self.field(u'source_format').toInt()[0]
license_version = unicode(self.field(u'license_version').toString())
license_copyright = unicode(self.field(u'license_copyright').toString())
license_permission = \
unicode(self.field(u'license_permission').toString())
license_permissions = \
unicode(self.field(u'license_permissions').toString())
importer = None
if bible_type == BibleFormat.OSIS:
# Import an OSIS bible
@ -436,7 +436,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
)
if importer.do_import():
self.manager.save_meta_data(license_version, license_version,
license_copyright, license_permission)
license_copyright, license_permissions)
self.manager.reload_bibles()
self.ImportProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Finished import.'))

View File

@ -275,14 +275,14 @@ class Ui_BibleImportWizard(object):
self.CopyrightEdit.setObjectName(u'CopyrightEdit')
self.LicenseDetailsLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
self.CopyrightEdit)
self.PermissionLabel = QtGui.QLabel(self.LicenseDetailsPage)
self.PermissionLabel.setObjectName(u'PermissionLabel')
self.PermissionsLabel = QtGui.QLabel(self.LicenseDetailsPage)
self.PermissionsLabel.setObjectName(u'PermissionsLabel')
self.LicenseDetailsLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
self.PermissionLabel)
self.PermissionEdit = QtGui.QLineEdit(self.LicenseDetailsPage)
self.PermissionEdit.setObjectName(u'PermissionEdit')
self.PermissionsLabel)
self.PermissionsEdit = QtGui.QLineEdit(self.LicenseDetailsPage)
self.PermissionsEdit.setObjectName(u'PermissionsEdit')
self.LicenseDetailsLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
self.PermissionEdit)
self.PermissionsEdit)
BibleImportWizard.addPage(self.LicenseDetailsPage)
self.ImportPage = QtGui.QWizardPage()
self.ImportPage.setObjectName(u'ImportPage')
@ -372,8 +372,8 @@ class Ui_BibleImportWizard(object):
translate('BiblesPlugin.ImportWizardForm', 'Version name:'))
self.CopyrightLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Copyright:'))
self.PermissionLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Permission:'))
self.PermissionsLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Permissions:'))
self.ImportPage.setTitle(
translate('BiblesPlugin.ImportWizardForm', 'Importing'))
self.ImportPage.setSubTitle(

View File

@ -60,22 +60,32 @@ def parse_reference(reference):
and converts it to a reference list, a list of references to be queried
from the Bible database files.
BIBLE_REFERENCE regular expression produces the following match groups:
0 This is a special group consisting of the whole string that matched.
1 [\w ]+ The book the reference is from.
2 [0-9]+ The first (or only) chapter in the reference.
3 None|[0-9]+ None or the only verse or the first verse in a
verse range or the start verse in a chapter range.
4 None|[0-9]+|end None or the end verse of the first verse range or
the end chapter of a chapter range.
5 None|[0-9]+ None or the second chapter in multiple
(non-ranged) chapters.
6 None|[0-9]+|end None, the start of the second verse range or the
end of a chapter range.
7 None|[0-9]+|end None or the end of the second verse range.
The ``BIBLE_REFERENCE`` constant regular expression produces the following
match groups:
0. (match string)
This is a special group consisting of the whole string that matched.
1. ``[\w ]+``
The book the reference is from.
2. ``[0-9]+``
The first (or only) chapter in the reference.
3. ``None`` or ``[0-9]+``
``None``, or the only verse, or the first verse in a verse range or,
the start verse in a chapter range.
4. ``None`` or ``[0-9]+`` or ``end``
``None``, or the end verse of the first verse range, or the end chapter
of a chapter range.
5. ``None`` or ``[0-9]+``
``None``, or the second chapter in multiple (non-ranged) chapters.
6. ``None`` or ``[0-9]+`` or ``end``
``None``, the start of the second verse range. or the end of a chapter
range.
7. ``None`` or ``[0-9]+`` or ``end``
``None``, or the end of the second verse range.
The reference list is a list of tuples, with each tuple structured like
this::
(book, chapter, start_verse, end_verse)
``reference``
@ -154,7 +164,7 @@ def parse_reference(reference):
class SearchResults(object):
"""
Encapsulate a set of search results. This is Bible-type independant.
Encapsulate a set of search results. This is Bible-type independent.
"""
def __init__(self, book, chapter, verselist):
"""

View File

@ -38,15 +38,14 @@ class BiblesTab(SettingsTab):
"""
log.info(u'Bible Tab loaded')
def __init__(self, title):
def __init__(self, title, visible_title):
self.paragraph_style = True
self.show_new_chapters = False
self.display_style = 0
SettingsTab.__init__(self, title)
SettingsTab.__init__(self, title, visible_title)
def setupUi(self):
self.setObjectName(u'BiblesTab')
self.tabTitleVisible = translate('BiblesPlugin.BiblesTab', 'Bibles')
self.BibleLayout = QtGui.QHBoxLayout(self)
self.BibleLayout.setSpacing(8)
self.BibleLayout.setMargin(8)

View File

@ -64,10 +64,10 @@ class Verse(BaseModel):
def init_schema(url):
"""
Setup a bible database connection and initialise the database schema
Setup a bible database connection and initialise the database schema.
``url``
The database to setup
The database to setup.
"""
session, metadata = init_db(url)
@ -240,7 +240,7 @@ class BibleDB(QtCore.QObject, Manager):
and the value is the verse text.
"""
log.debug(u'create_chapter %s,%s', book_id, chapter)
#text list has book and chapter as first two elements of the array
# text list has book and chapter as first two elements of the array
for verse_number, verse_text in textlist.iteritems():
verse = Verse.populate(
book_id = book_id,
@ -281,23 +281,23 @@ class BibleDB(QtCore.QObject, Manager):
def create_meta(self, key, value):
"""
Utility method to save BibleMeta objects in a Bible database
Utility method to save BibleMeta objects in a Bible database.
``key``
The key for this instance
The key for this instance.
``value``
The value for this instance
The value for this instance.
"""
log.debug(u'save_meta %s/%s', key, value)
self.save_object(BibleMeta.populate(key=key, value=value))
def get_book(self, book):
"""
Return a book object from the database
Return a book object from the database.
``book``
The name of the book to return
The name of the book to return.
"""
log.debug(u'BibleDb.get_book("%s")', book)
db_book = self.get_object_filtered(Book, Book.name.like(book + u'%'))
@ -353,9 +353,9 @@ class BibleDB(QtCore.QObject, Manager):
QtGui.QMessageBox.information(self.bible_plugin.mediaItem,
translate('BiblesPlugin.BibleDB', 'Book not found'),
translate('BiblesPlugin.BibleDB', 'The book you requested '
'could not be found in this bible. Please check your '
'spelling and that this is a complete bible not just '
'one testament.'))
'could not be found in this Bible. Please check your '
'spelling and that this is a complete Bible not just '
'one testament.'))
return verse_list
def verse_search(self, text):
@ -387,10 +387,10 @@ class BibleDB(QtCore.QObject, Manager):
def get_chapter_count(self, book):
"""
Return the number of chapters in a book
Return the number of chapters in a book.
``book``
The book to get the chapter count for
The book to get the chapter count for.
"""
log.debug(u'BibleDB.get_chapter_count("%s")', book)
count = self.session.query(Verse.chapter).join(Book)\
@ -403,13 +403,13 @@ class BibleDB(QtCore.QObject, Manager):
def get_verse_count(self, book, chapter):
"""
Return the number of verses in a chapter
Return the number of verses in a chapter.
``book``
The book containing the chapter
The book containing the chapter.
``chapter``
The chapter to get the verse count for
The chapter to get the verse count for.
"""
log.debug(u'BibleDB.get_verse_count("%s", %s)', book, chapter)
count = self.session.query(Verse).join(Book)\
@ -423,7 +423,7 @@ class BibleDB(QtCore.QObject, Manager):
def dump_bible(self):
"""
Utility debugging method to dump the contents of a bible
Utility debugging method to dump the contents of a bible.
"""
log.debug(u'.........Dumping Bible Database')
log.debug('...............................Books ')

View File

@ -187,16 +187,16 @@ class BGExtract(object):
def get_bible_chapter(self, version, bookname, chapter):
"""
Access and decode bibles via the BibleGateway website
Access and decode bibles via the BibleGateway website.
``version``
The version of the bible like 31 for New International version
The version of the bible like 31 for New International version.
``bookname``
Name of the Book
Name of the Book.
``chapter``
Chapter number
Chapter number.
"""
log.debug(u'get_bible_chapter %s, %s, %s', version, bookname, chapter)
url_params = urllib.urlencode(
@ -298,13 +298,13 @@ class CWExtract(object):
versetext = versetext + part
elif part and part.attrMap and \
(part.attrMap[u'class'] == u'WordsOfChrist' or \
part.attrMap[u'class'] == u'strongs'):
part.attrMap[u'class'] == u'strongs'):
for subpart in part.contents:
Receiver.send_message(u'openlp_process_events')
if isinstance(subpart, NavigableString):
versetext = versetext + subpart
elif subpart and subpart.attrMap and \
subpart.attrMap[u'class'] == u'strongs':
subpart.attrMap[u'class'] == u'strongs':
for subsub in subpart.contents:
Receiver.send_message(u'openlp_process_events')
if isinstance(subsub, NavigableString):
@ -428,7 +428,7 @@ class HTTPBible(BibleDB):
def get_chapter(self, book, chapter):
"""
Receive the request and call the relevant handler methods
Receive the request and call the relevant handler methods.
"""
log.debug(u'get_chapter %s, %s', book, chapter)
log.debug(u'source = %s', self.download_source)

View File

@ -137,7 +137,7 @@ class BibleManager(object):
name = bible.get_name()
log.debug(u'Bible Name: "%s"', name)
self.db_cache[name] = bible
# look to see if lazy load bible exists and get create getter.
# Look to see if lazy load bible exists and get create getter.
source = self.db_cache[name].get_object(BibleMeta,
u'download source')
if source:
@ -181,10 +181,10 @@ class BibleManager(object):
def get_bibles(self):
"""
Returns a list of the names of available Bibles.
Returns a dict with all available Bibles.
"""
log.debug(u'get_bibles')
return self.db_cache.keys()
return self.db_cache
def get_books(self, bible):
"""
@ -204,7 +204,7 @@ class BibleManager(object):
def get_chapter_count(self, bible, book):
"""
Returns the number of Chapters for a given book
Returns the number of Chapters for a given book.
"""
log.debug(u'get_book_chapter_count %s', book)
return self.db_cache[bible].get_chapter_count(book)
@ -212,7 +212,7 @@ class BibleManager(object):
def get_verse_count(self, bible, book, chapter):
"""
Returns all the number of verses for a given
book and chapterMaxBibleBookVerses
book and chapterMaxBibleBookVerses.
"""
log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)',
bible, book, chapter)
@ -254,12 +254,35 @@ class BibleManager(object):
'Book Chapter:Verse-Verse\n'
'Book Chapter:Verse-Verse,Verse-Verse\n'
'Book Chapter:Verse-Verse,Chapter:Verse-Verse\n'
'Book Chapter:Verse-Chapter:Verse\n'))
'Book Chapter:Verse-Chapter:Verse'))
return None
def verse_search(self, bible, text):
"""
Does a verse search for the given bible and text.
``bible``
The bible to seach in (unicode).
``text``
The text to search for (unicode).
"""
log.debug(u'BibleManager.verse_search("%s", "%s")', bible, text)
if text:
return self.db_cache[bible].verse_search(text)
else:
QtGui.QMessageBox.information(self.parent.mediaItem,
translate('BiblesPlugin.BibleManager',
'Scripture Reference Error'),
translate('BiblesPlugin.BibleManager', 'You did not enter a '
'search keyword.\nYou can separate different keywords by a '
'space to search for all of your keywords and you can seperate '
'them by a comma to search for one of them.'))
return None
def save_meta_data(self, bible, version, copyright, permissions):
"""
Saves the bibles meta data
Saves the bibles meta data.
"""
log.debug(u'save_meta data %s,%s, %s,%s',
bible, version, copyright, permissions)
@ -269,14 +292,14 @@ class BibleManager(object):
def get_meta_data(self, bible, key):
"""
Returns the meta data for a given key
Returns the meta data for a given key.
"""
log.debug(u'get_meta %s,%s', bible, key)
return self.db_cache[bible].get_object(BibleMeta, key)
def exists(self, name):
"""
Check cache to see if new bible
Check cache to see if new bible.
"""
if not isinstance(name, unicode):
name = unicode(name)

View File

@ -31,7 +31,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \
ItemCapabilities, translate
from openlp.plugins.bibles.forms import ImportWizardForm
from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib.db import BibleDB
log = logging.getLogger(__name__)
@ -361,7 +362,7 @@ class BibleMediaItem(MediaManagerItem):
def onImportClick(self):
if not hasattr(self, u'import_wizard'):
self.import_wizard = ImportWizardForm(self, self.parent.manager,
self.import_wizard = BibleImportForm(self, self.parent.manager,
self.parent)
self.import_wizard.exec_()
self.reloadBibles()
@ -374,7 +375,7 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedSecondBibleComboBox.clear()
self.QuickSecondBibleComboBox.addItem(u'')
self.AdvancedSecondBibleComboBox.addItem(u'')
bibles = self.parent.manager.get_bibles()
bibles = self.parent.manager.get_bibles().keys()
# load bibles into the combo boxes
first = True
for bible in bibles:
@ -407,21 +408,21 @@ class BibleMediaItem(MediaManagerItem):
self.initialiseChapterVerse(bible, book[u'name'],
book[u'chapters'])
def initialiseChapterVerse(self, bible, book, chapters):
def initialiseChapterVerse(self, bible, book, chapter_count):
log.debug(u'initialiseChapterVerse %s, %s', bible, book)
self.chapters_from = chapters
self.verses = self.parent.manager.get_verse_count(bible, book, 1)
if self.verses == 0:
self.chapter_count = chapter_count
verse_count = self.parent.manager.get_verse_count(bible, book, 1)
if verse_count == 0:
self.AdvancedSearchButton.setEnabled(False)
self.AdvancedMessage.setText(
translate('BiblesPlugin.MediaItem', 'Bible not fully loaded.'))
else:
self.AdvancedSearchButton.setEnabled(True)
self.AdvancedMessage.setText(u'')
self.adjustComboBox(1, self.chapters_from, self.AdvancedFromChapter)
self.adjustComboBox(1, self.chapters_from, self.AdvancedToChapter)
self.adjustComboBox(1, self.verses, self.AdvancedFromVerse)
self.adjustComboBox(1, self.verses, self.AdvancedToVerse)
self.adjustComboBox(1, self.chapter_count, self.AdvancedFromChapter)
self.adjustComboBox(1, self.chapter_count, self.AdvancedToChapter)
self.adjustComboBox(1, verse_count, self.AdvancedFromVerse)
self.adjustComboBox(1, verse_count, self.AdvancedToVerse)
def onAdvancedVersionComboBox(self):
self.initialiseBible(
@ -435,47 +436,69 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedBookComboBox.itemData(item).toInt()[0])
def onAdvancedFromVerse(self):
frm = int(self.AdvancedFromVerse.currentText())
chapter_frm = int(self.AdvancedFromChapter.currentText())
chapter_from = int(self.AdvancedFromChapter.currentText())
chapter_to = int(self.AdvancedToChapter.currentText())
if chapter_frm == chapter_to:
if chapter_from == chapter_to:
bible = unicode(self.AdvancedVersionComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText())
verses = self.parent.manager.get_verse_count(bible, book, chapter_to)
self.adjustComboBox(frm, verses, self.AdvancedToVerse)
verse_from = int(self.AdvancedFromVerse.currentText())
verse_count = self.parent.manager.get_verse_count(bible, book,
chapter_to)
self.adjustComboBox(verse_from, verse_count,
self.AdvancedToVerse, True)
def onAdvancedToChapter(self):
chapter_frm = int(self.AdvancedFromChapter.currentText())
chapter_to = int(self.AdvancedToChapter.currentText())
bible = unicode(self.AdvancedVersionComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText())
verses = self.parent.manager.get_verse_count(bible, book, chapter_to)
if chapter_frm != chapter_to:
self.adjustComboBox(1, verses, self.AdvancedToVerse)
chapter_from = int(self.AdvancedFromChapter.currentText())
chapter_to = int(self.AdvancedToChapter.currentText())
verse_from = int(self.AdvancedFromVerse.currentText())
verse_to = int(self.AdvancedToVerse.currentText())
verse_count = self.parent.manager.get_verse_count(bible, book,
chapter_to)
if chapter_from == chapter_to and verse_from > verse_to:
self.adjustComboBox(verse_from, verse_count, self.AdvancedToVerse)
else:
frm = int(self.AdvancedFromVerse.currentText())
to = int(self.AdvancedToVerse.currentText())
if to < frm:
self.adjustComboBox(frm, verses, self.AdvancedToVerse)
self.adjustComboBox(1, verse_count, self.AdvancedToVerse)
def onAdvancedFromChapter(self):
bible = unicode(self.AdvancedVersionComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText())
chapter_frm = int(self.AdvancedFromChapter.currentText())
self.adjustComboBox(chapter_frm, self.chapters_from,
self.AdvancedToChapter)
verse = self.parent.manager.get_verse_count(bible, book, chapter_frm)
self.adjustComboBox(1, verse, self.AdvancedToVerse)
self.adjustComboBox(1, verse, self.AdvancedFromVerse)
chapter_from = int(self.AdvancedFromChapter.currentText())
chapter_to = int(self.AdvancedToChapter.currentText())
verse_count = self.parent.manager.get_verse_count(bible, book,
chapter_from)
self.adjustComboBox(1, verse_count, self.AdvancedFromVerse)
if chapter_from > chapter_to:
self.adjustComboBox(1, verse_count, self.AdvancedToVerse)
self.adjustComboBox(chapter_from, self.chapter_count,
self.AdvancedToChapter)
elif chapter_from == chapter_to:
self.adjustComboBox(chapter_from, self.chapter_count,
self.AdvancedToChapter)
self.adjustComboBox(1, verse_count, self.AdvancedToVerse, True)
else:
self.adjustComboBox(chapter_from, self.chapter_count,
self.AdvancedToChapter, True)
def adjustComboBox(self, range_from, range_to, combo):
def adjustComboBox(self, range_from, range_to, combo, restore=False):
"""
``restore``
If True, then the combo's currentText will be restored after
adjusting (if possible).
"""
log.debug(u'adjustComboBox %s, %s, %s', combo, range_from, range_to)
if restore:
old_text = unicode(combo.currentText())
combo.clear()
for i in range(int(range_from), int(range_to) + 1):
combo.addItem(unicode(i))
if restore and combo.findText(old_text) != -1:
combo.setCurrentIndex(combo.findText(old_text))
def onAdvancedSearchButton(self):
log.debug(u'Advanced Search Button pressed')
self.AdvancedSearchButton.setEnabled(False)
bible = unicode(self.AdvancedVersionComboBox.currentText())
dual_bible = unicode(self.AdvancedSecondBibleComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText())
@ -508,16 +531,30 @@ class BibleMediaItem(MediaManagerItem):
self.displayResults(bible, dual_bible)
else:
self.displayResults(bible, dual_bible)
self.AdvancedSearchButton.setEnabled(True)
def onQuickSearchButton(self):
log.debug(u'Quick Search Button pressed')
self.QuickSearchButton.setEnabled(False)
bible = unicode(self.QuickVersionComboBox.currentText())
dual_bible = unicode(self.QuickSecondBibleComboBox.currentText())
text = unicode(self.QuickSearchEdit.text())
self.search_results = self.parent.manager.get_verses(bible, text)
if dual_bible:
self.dual_search_results = self.parent.manager.get_verses(
dual_bible, text)
if self.QuickSearchComboBox.currentIndex() == 0:
# We are doing a 'Verse Search'.
self.search_results = self.parent.manager.get_verses(bible, text)
if dual_bible and self.search_results:
self.dual_search_results = self.parent.manager.get_verses(
dual_bible, text)
else:
# We are doing a ' Text Search'.
bibles = self.parent.manager.get_bibles()
self.search_results = self.parent.manager.verse_search(bible, text)
if dual_bible and self.search_results:
text = []
for verse in self.search_results:
text.append((verse.book.name, verse.chapter, verse.verse,
verse.verse))
self.dual_search_results = bibles[dual_bible].get_verses(text)
if self.ClearQuickSearchComboBox.currentIndex() == 0:
self.listView.clear()
if self.listView.count() != 0 and self.search_results:
@ -537,6 +574,7 @@ class BibleMediaItem(MediaManagerItem):
self.displayResults(bible, dual_bible)
elif self.search_results:
self.displayResults(bible, dual_bible)
self.QuickSearchButton.setEnabled(True)
def displayResults(self, bible, dual_bible=u''):
"""
@ -545,16 +583,16 @@ class BibleMediaItem(MediaManagerItem):
"""
version = self.parent.manager.get_meta_data(bible, u'Version')
copyright = self.parent.manager.get_meta_data(bible, u'Copyright')
permission = self.parent.manager.get_meta_data(bible, u'Permissions')
permissions = self.parent.manager.get_meta_data(bible, u'Permissions')
if dual_bible:
dual_version = self.parent.manager.get_meta_data(dual_bible,
u'Version')
dual_copyright = self.parent.manager.get_meta_data(dual_bible,
u'Copyright')
dual_permission = self.parent.manager.get_meta_data(dual_bible,
dual_permissions = self.parent.manager.get_meta_data(dual_bible,
u'Permissions')
if not dual_permission:
dual_permission = u''
if not dual_permissions:
dual_permissions = u''
# We count the number of rows which are maybe already present.
start_count = self.listView.count()
for count, verse in enumerate(self.search_results):
@ -566,12 +604,12 @@ class BibleMediaItem(MediaManagerItem):
'bible': QtCore.QVariant(bible),
'version': QtCore.QVariant(version.value),
'copyright': QtCore.QVariant(copyright.value),
'permission': QtCore.QVariant(permission.value),
'permissions': QtCore.QVariant(permissions.value),
'text': QtCore.QVariant(verse.text),
'dual_bible': QtCore.QVariant(dual_bible),
'dual_version': QtCore.QVariant(dual_version.value),
'dual_copyright': QtCore.QVariant(dual_copyright.value),
'dual_permission': QtCore.QVariant(dual_permission.value),
'dual_permissions': QtCore.QVariant(dual_permissions.value),
'dual_text': QtCore.QVariant(
self.dual_search_results[count].text)
}
@ -586,12 +624,12 @@ class BibleMediaItem(MediaManagerItem):
'bible': QtCore.QVariant(bible),
'version': QtCore.QVariant(version.value),
'copyright': QtCore.QVariant(copyright.value),
'permission': QtCore.QVariant(permission.value),
'permissions': QtCore.QVariant(permissions.value),
'text': QtCore.QVariant(verse.text),
'dual_bible': QtCore.QVariant(u''),
'dual_version': QtCore.QVariant(u''),
'dual_copyright': QtCore.QVariant(u''),
'dual_permission': QtCore.QVariant(u''),
'dual_permissions': QtCore.QVariant(u''),
'dual_text': QtCore.QVariant(u'')
}
bible_text = u' %s %d:%d (%s)' % (verse.book.name,
@ -637,20 +675,20 @@ class BibleMediaItem(MediaManagerItem):
bible = self._decodeQtObject(bitem, 'bible')
version = self._decodeQtObject(bitem, 'version')
copyright = self._decodeQtObject(bitem, 'copyright')
permission = self._decodeQtObject(bitem, 'permission')
permissions = self._decodeQtObject(bitem, 'permissions')
text = self._decodeQtObject(bitem, 'text')
dual_bible = self._decodeQtObject(bitem, 'dual_bible')
dual_version = self._decodeQtObject(bitem, 'dual_version')
dual_copyright = self._decodeQtObject(bitem, 'dual_copyright')
dual_permission = self._decodeQtObject(bitem, 'dual_permission')
dual_permissions = self._decodeQtObject(bitem, 'dual_permissions')
dual_text = self._decodeQtObject(bitem, 'dual_text')
verse_text = self.formatVerse(old_chapter, chapter, verse)
footer = u'%s (%s %s %s)' % (book, version, copyright, permission)
footer = u'%s (%s %s %s)' % (book, version, copyright, permissions)
if footer not in raw_footer:
raw_footer.append(footer)
if dual_bible:
footer = u'%s (%s %s %s)' % (book, dual_version, dual_copyright,
dual_permission)
dual_permissions)
if footer not in raw_footer:
raw_footer.append(footer)
bible_text = u'%s %s\n\n%s %s' % (verse_text, text, verse_text,

View File

@ -28,7 +28,7 @@ import logging
from forms import EditCustomForm
from openlp.core.lib import Plugin, build_icon, translate
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.db import Manager
from openlp.plugins.custom.lib import CustomMediaItem, CustomTab
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
@ -55,11 +55,12 @@ class CustomPlugin(Plugin):
self.icon = build_icon(self.icon_path)
def getSettingsTab(self):
return CustomTab(self.name)
visible_name = self.getString(StringContent.VisibleName)
return CustomTab(self.name, visible_name[u'title'])
def getMediaManagerItem(self):
# Create the CustomManagerItem object
return CustomMediaItem(self, self.icon, self.name)
return CustomMediaItem(self, self, self.icon)
def about(self):
about_text = translate('CustomPlugin', '<strong>Custom Plugin</strong>'
@ -96,3 +97,66 @@ class CustomPlugin(Plugin):
for custom in customsUsingTheme:
custom.theme_name = newTheme
self.custommanager.save_object(custom)
def setPluginTextStrings(self):
"""
Called to define all translatable texts of the plugin
"""
## Name PluginList ##
self.textStrings[StringContent.Name] = {
u'singular': translate('CustomsPlugin', 'Custom'),
u'plural': translate('CustomsPlugin', 'Customs')
}
## Name for MediaDockManager, SettingsManager ##
self.textStrings[StringContent.VisibleName] = {
u'title': translate('CustomsPlugin', 'Customs')
}
# Middle Header Bar
## Import Button ##
self.textStrings[StringContent.Import] = {
u'title': translate('CustomsPlugin', 'Import'),
u'tooltip': translate('CustomsPlugin',
'Import a Custom')
}
## Load Button ##
self.textStrings[StringContent.Load] = {
u'title': translate('CustomsPlugin', 'Load'),
u'tooltip': translate('CustomsPlugin',
'Load a new Custom')
}
## New Button ##
self.textStrings[StringContent.New] = {
u'title': translate('CustomsPlugin', 'Add'),
u'tooltip': translate('CustomsPlugin',
'Add a new Custom')
}
## Edit Button ##
self.textStrings[StringContent.Edit] = {
u'title': translate('CustomsPlugin', 'Edit'),
u'tooltip': translate('CustomsPlugin',
'Edit the selected Custom')
}
## Delete Button ##
self.textStrings[StringContent.Delete] = {
u'title': translate('CustomsPlugin', 'Delete'),
u'tooltip': translate('CustomsPlugin',
'Delete the selected Custom')
}
## Preview ##
self.textStrings[StringContent.Preview] = {
u'title': translate('CustomsPlugin', 'Preview'),
u'tooltip': translate('CustomsPlugin',
'Preview the selected Custom')
}
## Live Button ##
self.textStrings[StringContent.Live] = {
u'title': translate('CustomsPlugin', 'Live'),
u'tooltip': translate('CustomsPlugin',
'Send the selected Custom live')
}
## Add to service Button ##
self.textStrings[StringContent.Service] = {
u'title': translate('CustomsPlugin', 'Service'),
u'tooltip': translate('CustomsPlugin',
'Add the selected Custom to the service')
}

View File

@ -25,3 +25,4 @@
###############################################################################
from editcustomform import EditCustomForm
from editcustomslideform import EditCustomSlideForm

View File

@ -26,7 +26,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.lib import build_icon, translate, SpellTextEdit
from openlp.core.lib import build_icon, translate
class Ui_CustomEditDialog(object):
def setupUi(self, customEditDialog):
@ -36,6 +36,70 @@ class Ui_CustomEditDialog(object):
build_icon(u':/icon/openlp.org-icon-32.bmp'))
self.gridLayout = QtGui.QGridLayout(customEditDialog)
self.gridLayout.setObjectName(u'gridLayout')
self.horizontalLayout3 = QtGui.QHBoxLayout()
self.horizontalLayout3.setObjectName(u'horizontalLayout3')
self.themeLabel = QtGui.QLabel(customEditDialog)
self.themeLabel.setObjectName(u'themeLabel')
self.horizontalLayout3.addWidget(self.themeLabel)
self.themeComboBox = QtGui.QComboBox(customEditDialog)
self.themeLabel.setBuddy(self.themeComboBox)
self.themeComboBox.setObjectName(u'themeComboBox')
self.horizontalLayout3.addWidget(self.themeComboBox)
self.gridLayout.addLayout(self.horizontalLayout3, 2, 0, 1, 1)
self.horizontalLayout2 = QtGui.QHBoxLayout()
self.horizontalLayout2.setObjectName(u'horizontalLayout2')
self.creditLabel = QtGui.QLabel(customEditDialog)
self.creditLabel.setObjectName(u'creditLabel')
self.horizontalLayout2.addWidget(self.creditLabel)
self.creditEdit = QtGui.QLineEdit(customEditDialog)
self.creditLabel.setBuddy(self.creditEdit)
self.creditEdit.setObjectName(u'creditEdit')
self.horizontalLayout2.addWidget(self.creditEdit)
self.gridLayout.addLayout(self.horizontalLayout2, 3, 0, 1, 1)
self.buttonBox = QtGui.QDialogButtonBox(customEditDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.gridLayout.addWidget(self.buttonBox, 4, 0, 1, 1)
self.horizontalLayout4 = QtGui.QHBoxLayout()
self.horizontalLayout4.setObjectName(u'horizontalLayout4')
self.slideListView = QtGui.QListWidget(customEditDialog)
self.slideListView.setAlternatingRowColors(True)
self.slideListView.setObjectName(u'slideListView')
self.horizontalLayout4.addWidget(self.slideListView)
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(u'verticalLayout')
self.addButton = QtGui.QPushButton(customEditDialog)
self.addButton.setObjectName(u'addButton')
self.verticalLayout.addWidget(self.addButton)
self.editButton = QtGui.QPushButton(customEditDialog)
self.editButton.setObjectName(u'editButton')
self.verticalLayout.addWidget(self.editButton)
self.editAllButton = QtGui.QPushButton(customEditDialog)
self.editAllButton.setObjectName(u'editAllButton')
self.verticalLayout.addWidget(self.editAllButton)
self.deleteButton = QtGui.QPushButton(customEditDialog)
self.deleteButton.setObjectName(u'deleteButton')
self.verticalLayout.addWidget(self.deleteButton)
spacerItem = QtGui.QSpacerItem(20, 128, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.upButton = QtGui.QPushButton(customEditDialog)
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(u':/services/service_up.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.upButton.setIcon(icon1)
self.upButton.setObjectName(u'upButton')
self.verticalLayout.addWidget(self.upButton)
self.downButton = QtGui.QPushButton(customEditDialog)
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(u':/services/service_down.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.downButton.setIcon(icon2)
self.downButton.setObjectName(u'downButton')
self.verticalLayout.addWidget(self.downButton)
self.horizontalLayout4.addLayout(self.verticalLayout)
self.gridLayout.addLayout(self.horizontalLayout4, 1, 0, 1, 1)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(u'horizontalLayout')
self.titleLabel = QtGui.QLabel(customEditDialog)
@ -46,91 +110,6 @@ class Ui_CustomEditDialog(object):
self.titleEdit.setObjectName(u'titleEdit')
self.horizontalLayout.addWidget(self.titleEdit)
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
self.horizontalLayout4 = QtGui.QHBoxLayout()
self.horizontalLayout4.setObjectName(u'horizontalLayout4')
self.verseListView = QtGui.QListWidget(customEditDialog)
self.verseListView.setAlternatingRowColors(True)
self.verseListView.setObjectName(u'verseListView')
self.horizontalLayout4.addWidget(self.verseListView)
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName(u'verticalLayout')
self.upButton = QtGui.QPushButton(customEditDialog)
self.upButton.setIcon(build_icon(u':/services/service_up.png'))
self.upButton.setObjectName(u'upButton')
self.verticalLayout.addWidget(self.upButton)
spacerItem = QtGui.QSpacerItem(20, 128, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.downButton = QtGui.QPushButton(customEditDialog)
self.downButton.setIcon(build_icon(u':/services/service_down.png'))
self.downButton.setObjectName(u'downButton')
self.verticalLayout.addWidget(self.downButton)
self.horizontalLayout4.addLayout(self.verticalLayout)
self.gridLayout.addLayout(self.horizontalLayout4, 1, 0, 1, 1)
self.editWidget = QtGui.QWidget(customEditDialog)
self.editWidget.setObjectName(u'editWidget')
self.editLayout3 = QtGui.QHBoxLayout(self.editWidget)
self.editLayout3.setSpacing(8)
self.editLayout3.setMargin(0)
self.editLayout3.setObjectName(u'editLayout3')
self.verseTextEdit = SpellTextEdit(self)
self.verseTextEdit.setObjectName(u'verseTextEdit')
self.editLayout3.addWidget(self.verseTextEdit)
self.buttonWidget = QtGui.QWidget(self.editWidget)
self.buttonWidget.setObjectName(u'buttonWidget')
self.verticalLayout2 = QtGui.QVBoxLayout(self.buttonWidget)
self.verticalLayout2.setObjectName(u'verticalLayout2')
self.addButton = QtGui.QPushButton(self.buttonWidget)
self.addButton.setObjectName(u'addButton')
self.verticalLayout2.addWidget(self.addButton)
self.editButton = QtGui.QPushButton(self.buttonWidget)
self.editButton.setObjectName(u'editButton')
self.verticalLayout2.addWidget(self.editButton)
self.editAllButton = QtGui.QPushButton(self.buttonWidget)
self.editAllButton.setObjectName(u'editAllButton')
self.verticalLayout2.addWidget(self.editAllButton)
self.saveButton = QtGui.QPushButton(self.buttonWidget)
self.saveButton.setObjectName(u'saveButton')
self.verticalLayout2.addWidget(self.saveButton)
self.deleteButton = QtGui.QPushButton(self.buttonWidget)
self.deleteButton.setObjectName(u'deleteButton')
self.verticalLayout2.addWidget(self.deleteButton)
self.clearButton = QtGui.QPushButton(self.buttonWidget)
self.clearButton.setObjectName(u'clearButton')
self.verticalLayout2.addWidget(self.clearButton)
self.splitButton = QtGui.QPushButton(self.buttonWidget)
self.splitButton.setObjectName(u'splitButton')
self.verticalLayout2.addWidget(self.splitButton)
spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum,
QtGui.QSizePolicy.Expanding)
self.verticalLayout2.addItem(spacerItem1)
self.editLayout3.addWidget(self.buttonWidget)
self.gridLayout.addWidget(self.editWidget, 2, 0, 1, 1)
self.horizontalLayout3 = QtGui.QHBoxLayout()
self.horizontalLayout3.setObjectName(u'horizontalLayout3')
self.themeLabel = QtGui.QLabel(customEditDialog)
self.themeLabel.setObjectName(u'themeLabel')
self.horizontalLayout3.addWidget(self.themeLabel)
self.themeComboBox = QtGui.QComboBox(customEditDialog)
self.themeLabel.setBuddy(self.themeComboBox)
self.themeComboBox.setObjectName(u'themeComboBox')
self.horizontalLayout3.addWidget(self.themeComboBox)
self.gridLayout.addLayout(self.horizontalLayout3, 3, 0, 1, 1)
self.horizontalLayout2 = QtGui.QHBoxLayout()
self.horizontalLayout2.setObjectName(u'horizontalLayout2')
self.creditLabel = QtGui.QLabel(customEditDialog)
self.creditLabel.setObjectName(u'creditLabel')
self.horizontalLayout2.addWidget(self.creditLabel)
self.creditEdit = QtGui.QLineEdit(customEditDialog)
self.creditLabel.setBuddy(self.creditEdit)
self.creditEdit.setObjectName(u'creditEdit')
self.horizontalLayout2.addWidget(self.creditEdit)
self.gridLayout.addLayout(self.horizontalLayout2, 4, 0, 1, 1)
self.buttonBox = QtGui.QDialogButtonBox(customEditDialog)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1)
self.retranslateUi(customEditDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
customEditDialog.accept)
@ -143,46 +122,32 @@ class Ui_CustomEditDialog(object):
translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
self.upButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide up one '
'position.'))
'position.'))
self.downButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Move slide down one '
'position.'))
'position.'))
self.titleLabel.setText(
translate('CustomPlugin.EditCustomForm', '&Title:'))
self.addButton.setText(
translate('CustomPlugin.EditCustomForm', 'Add New'))
translate('CustomPlugin.EditCustomForm', '&Add'))
self.addButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Add a new slide at '
'bottom.'))
'bottom.'))
self.editButton.setText(
translate('CustomPlugin.EditCustomForm', 'Edit'))
translate('CustomPlugin.EditCustomForm', '&Edit'))
self.editButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit the selected '
'slide.'))
'slide.'))
self.editAllButton.setText(
translate('CustomPlugin.EditCustomForm', 'Edit All'))
translate('CustomPlugin.EditCustomForm', 'Ed&it All'))
self.editAllButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Edit all the slides at '
'once.'))
self.saveButton.setText(
translate('CustomPlugin.EditCustomForm', 'Save'))
self.saveButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Save the slide currently '
'being edited.'))
'once.'))
self.deleteButton.setText(
translate('CustomPlugin.EditCustomForm', 'Delete'))
translate('CustomPlugin.EditCustomForm', '&Delete'))
self.deleteButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Delete the selected '
'slide.'))
self.clearButton.setText(
translate('CustomPlugin.EditCustomForm', 'Clear'))
self.clearButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Clear edit area'))
self.splitButton.setText(
translate('CustomPlugin.EditCustomForm', 'Split Slide'))
self.splitButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Split a slide into two '
'by inserting a slide splitter.'))
'slide.'))
self.themeLabel.setText(
translate('CustomPlugin.EditCustomForm', 'The&me:'))
self.creditLabel.setText(

View File

@ -32,6 +32,7 @@ from openlp.core.lib import Receiver, translate
from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser
from openlp.plugins.custom.lib.db import CustomSlide
from editcustomdialog import Ui_CustomEditDialog
from editcustomslideform import EditCustomSlideForm
log = logging.getLogger(__name__)
@ -40,7 +41,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
Class documentation goes here.
"""
log.info(u'Custom Editor loaded')
def __init__(self, custommanager, parent = None):
def __init__(self, custommanager, parent=None):
"""
Constructor
"""
@ -61,28 +62,20 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
QtCore.SIGNAL(u'pressed()'), self.onEditButtonPressed)
QtCore.QObject.connect(self.editAllButton,
QtCore.SIGNAL(u'pressed()'), self.onEditAllButtonPressed)
QtCore.QObject.connect(self.saveButton,
QtCore.SIGNAL(u'pressed()'), self.onSaveButtonPressed)
QtCore.QObject.connect(self.deleteButton,
QtCore.SIGNAL(u'pressed()'), self.onDeleteButtonPressed)
QtCore.QObject.connect(self.clearButton,
QtCore.SIGNAL(u'pressed()'), self.onClearButtonPressed)
QtCore.QObject.connect(self.upButton,
QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed)
QtCore.QObject.connect(self.downButton,
QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed)
QtCore.QObject.connect(self.splitButton,
QtCore.SIGNAL(u'pressed()'), self.onSplitButtonPressed)
QtCore.QObject.connect(self.verseListView,
QtCore.SIGNAL(u'itemDoubleClicked(QListWidgetItem*)'),
self.onVerseListViewSelected)
QtCore.QObject.connect(self.verseListView,
QtCore.QObject.connect(self.slideListView,
QtCore.SIGNAL(u'itemClicked(QListWidgetItem*)'),
self.onVerseListViewPressed)
self.onSlideListViewPressed)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.loadThemes)
# Create other objects and forms
# Create other objects and forms.
self.custommanager = custommanager
self.editSlideForm = EditCustomSlideForm(self)
self.initialise()
def onPreview(self, button):
@ -92,21 +85,15 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
Receiver.send_message(u'custom_preview')
def initialise(self):
self.editAll = False
self.addButton.setEnabled(True)
self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(True)
self.saveButton.setEnabled(False)
self.clearButton.setEnabled(False)
self.splitButton.setEnabled(False)
self.titleEdit.setText(u'')
self.creditEdit.setText(u'')
self.verseTextEdit.clear()
self.verseListView.clear()
#make sure we have a new item
self.slideListView.clear()
# Make sure we have a new item.
self.customSlide = CustomSlide()
self.themeComboBox.addItem(u'')
def loadThemes(self, themelist):
self.themeComboBox.clear()
@ -115,6 +102,16 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.themeComboBox.addItem(themename)
def loadCustom(self, id, preview=False):
"""
Called when editing or creating a new custom.
``id``
The cutom's id. If zero, then a new custom is created.
``preview``
States whether the custom is edited while being previewed in the
preview panel.
"""
self.customSlide = CustomSlide()
self.initialise()
if id != 0:
@ -122,9 +119,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.titleEdit.setText(self.customSlide.title)
self.creditEdit.setText(self.customSlide.credits)
customXML = CustomXMLParser(self.customSlide.text)
verseList = customXML.get_verses()
for verse in verseList:
self.verseListView.addItem(verse[1])
slideList = customXML.get_verses()
for slide in slideList:
self.slideListView.addItem(slide[1])
theme = self.customSlide.theme_name
id = self.themeComboBox.findText(theme, QtCore.Qt.MatchExactly)
if id == -1:
@ -132,7 +129,8 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.themeComboBox.setCurrentIndex(id)
else:
self.themeComboBox.setCurrentIndex(0)
#if not preview hide the preview button
self.editAllButton.setEnabled(False)
# If not preview hide the preview button.
self.previewButton.setVisible(False)
if preview:
self.previewButton.setVisible(True)
@ -148,6 +146,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.close()
def saveCustom(self):
"""
Saves the custom.
"""
valid, message = self._validate()
if not valid:
QtGui.QMessageBox.critical(self,
@ -157,9 +158,9 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
sxml.new_document()
sxml.add_lyrics_to_song()
count = 1
for i in range(0, self.verseListView.count()):
for i in range(0, self.slideListView.count()):
sxml.add_verse_to_lyrics(u'custom', unicode(count),
unicode(self.verseListView.item(i).text()))
unicode(self.slideListView.item(i).text()))
count += 1
self.customSlide.title = unicode(self.titleEdit.displayText(), u'utf-8')
self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8')
@ -170,114 +171,103 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
return self.custommanager.save_object(self.customSlide)
def onUpButtonPressed(self):
selectedRow = self.verseListView.currentRow()
selectedRow = self.slideListView.currentRow()
if selectedRow != 0:
qw = self.verseListView.takeItem(selectedRow)
self.verseListView.insertItem(selectedRow - 1, qw)
self.verseListView.setCurrentRow(selectedRow - 1)
qw = self.slideListView.takeItem(selectedRow)
self.slideListView.insertItem(selectedRow - 1, qw)
self.slideListView.setCurrentRow(selectedRow - 1)
def onDownButtonPressed(self):
selectedRow = self.verseListView.currentRow()
selectedRow = self.slideListView.currentRow()
# zero base arrays
if selectedRow != self.verseListView.count() - 1:
qw = self.verseListView.takeItem(selectedRow)
self.verseListView.insertItem(selectedRow + 1, qw)
self.verseListView.setCurrentRow(selectedRow + 1)
if selectedRow != self.slideListView.count() - 1:
qw = self.slideListView.takeItem(selectedRow)
self.slideListView.insertItem(selectedRow + 1, qw)
self.slideListView.setCurrentRow(selectedRow + 1)
def onClearButtonPressed(self):
self.verseTextEdit.clear()
self.editAll = False
self.addButton.setEnabled(True)
self.editAllButton.setEnabled(True)
self.saveButton.setEnabled(False)
def onVerseListViewPressed(self, item):
def onSlideListViewPressed(self, item):
self.deleteButton.setEnabled(True)
self.editButton.setEnabled(True)
def onVerseListViewSelected(self, item):
self.editText(item.text())
def onAddButtonPressed(self):
self.verseListView.addItem(self.verseTextEdit.toPlainText())
self.deleteButton.setEnabled(False)
self.verseTextEdit.clear()
self.editSlideForm.setText(u'')
if self.editSlideForm.exec_():
for slide in self.editSlideForm.getText():
self.slideListView.addItem(slide)
self.editAllButton.setEnabled(True)
def onEditButtonPressed(self):
self.editText(self.verseListView.currentItem().text())
self.editSlideForm.setText(self.slideListView.currentItem().text())
if self.editSlideForm.exec_():
self.updateSlideList(self.editSlideForm.getText())
def onEditAllButtonPressed(self):
self.editAll = True
self.addButton.setEnabled(False)
self.splitButton.setEnabled(True)
if self.verseListView.count() > 0:
verse_list = u''
for row in range(0, self.verseListView.count()):
item = self.verseListView.item(row)
verse_list += item.text()
if row != self.verseListView.count() - 1:
verse_list += u'\n[---]\n'
self.editText(verse_list)
"""
Edits all slides.
"""
if self.slideListView.count() > 0:
slide_list = u''
for row in range(0, self.slideListView.count()):
item = self.slideListView.item(row)
slide_list += item.text()
if row != self.slideListView.count() - 1:
slide_list += u'\n[---]\n'
self.editSlideForm.setText(slide_list)
if self.editSlideForm.exec_():
self.updateSlideList(self.editSlideForm.getText(), True)
def editText(self, text):
self.beforeText = text
self.verseTextEdit.setPlainText(text)
self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(False)
self.saveButton.setEnabled(True)
self.clearButton.setEnabled(True)
def updateSlideList(self, slides, edit_all=False):
"""
Updates the slide list after editing slides.
def onSaveButtonPressed(self):
if self.editAll:
self.verseListView.clear()
for row in unicode(self.verseTextEdit.toPlainText()).split(
u'\n[---]\n'):
self.verseListView.addItem(row)
``slides``
A list of all slides which have been edited.
``edit_all``
Indicates if all slides or only one slide has been edited.
"""
if len(slides) == 1:
self.slideListView.currentItem().setText(slides[0])
else:
self.verseListView.currentItem().setText(
self.verseTextEdit.toPlainText())
#number of lines has change
if len(self.beforeText.split(u'\n')) != \
len(self.verseTextEdit.toPlainText().split(u'\n')):
tempList = {}
for row in range(0, self.verseListView.count()):
tempList[row] = self.verseListView.item(row).text()
self.verseListView.clear()
for row in range (0, len(tempList)):
self.verseListView.addItem(tempList[row])
self.verseListView.repaint()
self.addButton.setEnabled(True)
self.saveButton.setEnabled(False)
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(True)
self.splitButton.setEnabled(False)
self.verseTextEdit.clear()
def onSplitButtonPressed(self):
if self.verseTextEdit.textCursor().columnNumber() != 0:
self.verseTextEdit.insertPlainText(u'\n')
self.verseTextEdit.insertPlainText(u'[---]\n' )
self.verseTextEdit.setFocus()
if edit_all:
self.slideListView.clear()
for slide in slides:
self.slideListView.addItem(slide)
else:
old_slides = []
old_row = self.slideListView.currentRow()
# Create a list with all (old/unedited) slides.
old_slides = [self.slideListView.item(row).text() for row in \
range(0, self.slideListView.count())]
self.slideListView.clear()
old_slides.pop(old_row)
# Insert all slides to make the old_slides list complete.
for slide in slides:
old_slides.insert(old_row, slide)
for slide in old_slides:
self.slideListView.addItem(slide)
self.slideListView.repaint()
def onDeleteButtonPressed(self):
self.verseListView.takeItem(self.verseListView.currentRow())
self.editButton.setEnabled(False)
self.slideListView.takeItem(self.slideListView.currentRow())
self.editButton.setEnabled(True)
self.editAllButton.setEnabled(True)
if self.slideListView.count() == 0:
self.deleteButton.setEnabled(False)
self.editButton.setEnabled(False)
self.editAllButton.setEnabled(False)
def _validate(self):
"""
Checks whether a custom is valid or not.
"""
# We must have a title.
if len(self.titleEdit.displayText()) == 0:
self.titleEdit.setFocus()
return False, translate('CustomPlugin.EditCustomForm',
'You need to type in a title.')
# must have 1 slide
if self.verseListView.count() == 0:
self.verseTextEdit.setFocus()
# We must have one slide.
if self.slideListView.count() == 0:
return False, translate('CustomPlugin.EditCustomForm',
'You need to add at least one slide')
if self.verseTextEdit.toPlainText():
self.verseTextEdit.setFocus()
return False, translate('CustomPlugin.EditCustomForm',
'You have one or more unsaved slides, please either save your '
'slide(s) or clear your changes.')
return True, u''

View File

@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, SpellTextEdit
class Ui_CustomSlideEditDialog(object):
def setupUi(self, customSlideEditDialog):
customSlideEditDialog.setObjectName(u'customSlideEditDialog')
customSlideEditDialog.resize(474, 442)
self.buttonBox = QtGui.QDialogButtonBox(customSlideEditDialog)
self.buttonBox.setGeometry(QtCore.QRect(8, 407, 458, 32))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel |
QtGui.QDialogButtonBox.Save)
self.buttonBox.setObjectName(u'buttonBox')
self.slideTextEdit = SpellTextEdit(self)
self.slideTextEdit.setGeometry(QtCore.QRect(8, 8, 458, 349))
self.slideTextEdit.setObjectName(u'slideTextEdit')
self.splitButton = QtGui.QPushButton(customSlideEditDialog)
self.splitButton.setGeometry(QtCore.QRect(380, 370, 85, 27))
self.splitButton.setObjectName(u'splitButton')
self.retranslateUi(customSlideEditDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
customSlideEditDialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
customSlideEditDialog.reject)
QtCore.QMetaObject.connectSlotsByName(customSlideEditDialog)
def retranslateUi(self, customSlideEditDialog):
self.splitButton.setText(
translate('CustomPlugin.EditCustomForm', 'Split Slide'))
self.splitButton.setToolTip(
translate('CustomPlugin.EditCustomForm', 'Split a slide into two '
'by inserting a slide splitter.'))

View File

@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, translate
from editcustomslidedialog import Ui_CustomSlideEditDialog
log = logging.getLogger(__name__)
class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
"""
Class documentation goes here.
"""
log.info(u'Custom Verse Editor loaded')
def __init__(self, parent=None):
"""
Constructor
"""
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
# Connecting signals and slots
QtCore.QObject.connect(self.splitButton,
QtCore.SIGNAL(u'pressed()'), self.onSplitButtonPressed)
def setText(self, text):
"""
Set the text for slideTextEdit.
``text``
The text (unicode).
"""
self.slideTextEdit.clear()
if text:
self.slideTextEdit.setPlainText(text)
self.slideTextEdit.setFocus()
def getText(self):
"""
Returns a list with all slides.
"""
return self.slideTextEdit.toPlainText().split(u'\n[---]\n')
def onSplitButtonPressed(self):
"""
Splits a slide in two slides.
"""
if self.slideTextEdit.textCursor().columnNumber() != 0:
self.slideTextEdit.insertPlainText(u'\n')
self.slideTextEdit.insertPlainText(u'[---]\n' )
self.slideTextEdit.setFocus()

View File

@ -32,12 +32,11 @@ class CustomTab(SettingsTab):
"""
CustomTab is the Custom settings tab in the settings dialog.
"""
def __init__(self, title):
SettingsTab.__init__(self, title)
def __init__(self, title, visible_title):
SettingsTab.__init__(self, title, visible_title)
def setupUi(self):
self.setObjectName(u'CustomTab')
self.tabTitleVisible = translate('CustomPlugin.CustomTab', 'Custom')
self.customLayout = QtGui.QFormLayout(self)
self.customLayout.setSpacing(8)
self.customLayout.setMargin(8)

View File

@ -46,14 +46,12 @@ class CustomMediaItem(MediaManagerItem):
"""
log.info(u'Custom Media Item loaded')
def __init__(self, parent, icon, title):
self.PluginNameShort = u'Custom'
self.pluginNameVisible = translate('CustomPlugin.MediaItem', 'Custom')
def __init__(self, parent, plugin, icon):
self.IconPath = u'custom/custom'
# this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = CustomListView
MediaManagerItem.__init__(self, parent, icon, title)
MediaManagerItem.__init__(self, parent, self, icon)
self.singleServiceItem = False
# Holds information about whether the edit is remotly triggered and
# which Custom is required.

View File

@ -26,7 +26,7 @@
import logging
from openlp.core.lib import Plugin, build_icon, translate
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.plugins.images.lib import ImageMediaItem
log = logging.getLogger(__name__)
@ -42,7 +42,7 @@ class ImagePlugin(Plugin):
def getMediaManagerItem(self):
# Create the MediaManagerItem object
return ImageMediaItem(self, self.icon, self.name)
return ImageMediaItem(self, self, self.icon)
def about(self):
about_text = translate('ImagePlugin', '<strong>Image Plugin</strong>'
@ -57,3 +57,60 @@ class ImagePlugin(Plugin):
'selected image as a background instead of the background '
'provided by the theme.')
return about_text
def setPluginTextStrings(self):
"""
Called to define all translatable texts of the plugin
"""
## Name PluginList ##
self.textStrings[StringContent.Name] = {
u'singular': translate('ImagePlugin', 'Image'),
u'plural': translate('ImagePlugin', 'Images')
}
## Name for MediaDockManager, SettingsManager ##
self.textStrings[StringContent.VisibleName] = {
u'title': translate('ImagePlugin', 'Images')
}
# Middle Header Bar
## Load Button ##
self.textStrings[StringContent.Load] = {
u'title': translate('ImagePlugin', 'Load'),
u'tooltip': translate('ImagePlugin',
'Load a new Image')
}
## New Button ##
self.textStrings[StringContent.New] = {
u'title': translate('ImagePlugin', 'Add'),
u'tooltip': translate('ImagePlugin',
'Add a new Image')
}
## Edit Button ##
self.textStrings[StringContent.Edit] = {
u'title': translate('ImagePlugin', 'Edit'),
u'tooltip': translate('ImagePlugin',
'Edit the selected Image')
}
## Delete Button ##
self.textStrings[StringContent.Delete] = {
u'title': translate('ImagePlugin', 'Delete'),
u'tooltip': translate('ImagePlugin',
'Delete the selected Image')
}
## Preview ##
self.textStrings[StringContent.Preview] = {
u'title': translate('ImagePlugin', 'Preview'),
u'tooltip': translate('ImagePlugin',
'Preview the selected Image')
}
## Live Button ##
self.textStrings[StringContent.Live] = {
u'title': translate('ImagePlugin', 'Live'),
u'tooltip': translate('ImagePlugin',
'Send the selected Image live')
}
## Add to service Button ##
self.textStrings[StringContent.Service] = {
u'title': translate('ImagePlugin', 'Service'),
u'tooltip': translate('ImagePlugin',
'Add the selected Image to the service')
}

View File

@ -49,14 +49,12 @@ class ImageMediaItem(MediaManagerItem):
"""
log.info(u'Image Media Item loaded')
def __init__(self, parent, icon, title):
self.PluginNameShort = u'Image'
self.pluginNameVisible = translate('ImagePlugin.MediaItem', 'Image')
def __init__(self, parent, plugin, icon):
self.IconPath = u'images/image'
# this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = ImageListView
MediaManagerItem.__init__(self, parent, icon, title)
MediaManagerItem.__init__(self, parent, self, icon)
def retranslateUi(self):
self.OnNewPrompt = translate('ImagePlugin.MediaItem',

View File

@ -25,5 +25,6 @@
###############################################################################
from mediaitem import MediaMediaItem
from mediatab import MediaTab
__all__ = ['MediaMediaItem']

View File

@ -46,9 +46,7 @@ class MediaMediaItem(MediaManagerItem):
"""
log.info(u'%s MediaMediaItem loaded', __name__)
def __init__(self, parent, icon, title):
self.PluginNameShort = u'Media'
self.pluginNameVisible = translate('MediaPlugin.MediaItem', 'Media')
def __init__(self, parent, plugin, icon):
self.IconPath = u'images/image'
self.background = False
# this next is a class, not an instance of a class - it will
@ -56,7 +54,7 @@ class MediaMediaItem(MediaManagerItem):
self.ListViewWithDnD_class = MediaListView
self.PreviewFunction = QtGui.QPixmap(
u':/media/media_video.png').toImage()
MediaManagerItem.__init__(self, parent, icon, title)
MediaManagerItem.__init__(self, parent, self, icon)
self.singleServiceItem = False
self.serviceItemIconName = u':/media/media_video.png'
@ -115,7 +113,7 @@ class MediaMediaItem(MediaManagerItem):
'You must select a media file to replace the background with.')):
item = self.listView.currentItem()
filename = unicode(item.data(QtCore.Qt.UserRole).toString())
self.parent.liveController.display.video(filename, 0)
self.parent.liveController.display.video(filename, 0, True)
self.resetButton.setVisible(True)
def generateSlideData(self, service_item, item=None):

View File

@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate, Receiver
class MediaTab(SettingsTab):
"""
MediaTab is the Media settings tab in the settings dialog.
"""
def __init__(self, title):
SettingsTab.__init__(self, title)
def setupUi(self):
self.setObjectName(u'MediaTab')
self.tabTitleVisible = translate('MediaPlugin.MediaTab', 'Media')
self.mediaLayout = QtGui.QFormLayout(self)
self.mediaLayout.setSpacing(8)
self.mediaLayout.setMargin(8)
self.mediaLayout.setObjectName(u'mediaLayout')
self.mediaModeGroupBox = QtGui.QGroupBox(self)
self.mediaModeGroupBox.setObjectName(u'mediaModeGroupBox')
self.mediaModeLayout = QtGui.QVBoxLayout(self.mediaModeGroupBox)
self.mediaModeLayout.setSpacing(8)
self.mediaModeLayout.setMargin(8)
self.mediaModeLayout.setObjectName(u'mediaModeLayout')
self.usePhononCheckBox = QtGui.QCheckBox(self.mediaModeGroupBox)
self.usePhononCheckBox.setObjectName(u'usePhononCheckBox')
self.mediaModeLayout.addWidget(self.usePhononCheckBox)
self.mediaLayout.setWidget(
0, QtGui.QFormLayout.LabelRole, self.mediaModeGroupBox)
QtCore.QObject.connect(self.usePhononCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onUsePhononCheckBoxChanged)
def retranslateUi(self):
self.mediaModeGroupBox.setTitle(translate('MediaPlugin.MediaTab',
'Media Display'))
self.usePhononCheckBox.setText(
translate('MediaPlugin.MediaTab', 'Use Phonon for video playback'))
def onUsePhononCheckBoxChanged(self, check_state):
self.usePhonon = (check_state == QtCore.Qt.Checked)
self.usePhononChanged = True
def load(self):
self.usePhonon = QtCore.QSettings().value(
self.settingsSection + u'/use phonon',
QtCore.QVariant(True)).toBool()
self.usePhononCheckBox.setChecked(self.usePhonon)
def save(self):
oldUsePhonon = QtCore.QSettings().value(
u'media/use phonon', QtCore.QVariant(True)).toBool()
if oldUsePhonon != self.usePhonon:
QtCore.QSettings().setValue(self.settingsSection + u'/use phonon',
QtCore.QVariant(self.usePhonon))
Receiver.send_message(u'config_screen_changed')

View File

@ -28,8 +28,8 @@ import logging
from PyQt4.phonon import Phonon
from openlp.core.lib import Plugin, build_icon, translate
from openlp.plugins.media.lib import MediaMediaItem
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.plugins.media.lib import MediaMediaItem, MediaTab
log = logging.getLogger(__name__)
@ -68,11 +68,71 @@ class MediaPlugin(Plugin):
type = u''
return list, type
def getSettingsTab(self):
return MediaTab(self.name)
def getMediaManagerItem(self):
# Create the MediaManagerItem object
return MediaMediaItem(self, self.icon, self.name)
return MediaMediaItem(self, self, self.icon)
def about(self):
about_text = translate('MediaPlugin', '<strong>Media Plugin</strong>'
'<br />The media plugin provides playback of audio and video.')
return about_text
def setPluginTextStrings(self):
"""
Called to define all translatable texts of the plugin
"""
## Name PluginList ##
self.textStrings[StringContent.Name] = {
u'singular': translate('MediaPlugin', 'Media'),
u'plural': translate('MediaPlugin', 'Media')
}
## Name for MediaDockManager, SettingsManager ##
self.textStrings[StringContent.VisibleName] = {
u'title': translate('MediaPlugin', 'Media')
}
# Middle Header Bar
## Load Button ##
self.textStrings[StringContent.Load] = {
u'title': translate('MediaPlugin', 'Load'),
u'tooltip': translate('MediaPlugin',
'Load a new Media')
}
## New Button ##
self.textStrings[StringContent.New] = {
u'title': translate('MediaPlugin', 'Add'),
u'tooltip': translate('MediaPlugin',
'Add a new Media')
}
## Edit Button ##
self.textStrings[StringContent.Edit] = {
u'title': translate('MediaPlugin', 'Edit'),
u'tooltip': translate('MediaPlugin',
'Edit the selected Media')
}
## Delete Button ##
self.textStrings[StringContent.Delete] = {
u'title': translate('MediaPlugin', 'Delete'),
u'tooltip': translate('MediaPlugin',
'Delete the selected Media')
}
## Preview ##
self.textStrings[StringContent.Preview] = {
u'title': translate('MediaPlugin', 'Preview'),
u'tooltip': translate('MediaPlugin',
'Preview the selected Media')
}
## Live Button ##
self.textStrings[StringContent.Live] = {
u'title': translate('MediaPlugin', 'Live'),
u'tooltip': translate('MediaPlugin',
'Send the selected Media live')
}
## Add to service Button ##
self.textStrings[StringContent.Service] = {
u'title': translate('MediaPlugin', 'Service'),
u'tooltip': translate('MediaPlugin',
'Add the selected Media to the service')
}

View File

@ -169,7 +169,8 @@ class ImpressController(PresentationController):
try:
return Dispatch(u'com.sun.star.ServiceManager')
except pywintypes.com_error:
log.exception(u'Failed to get COM service manager')
log.warn(u'Failed to get COM service manager. '
u'Impress Controller has been disabled')
return None
def kill(self):

View File

@ -58,15 +58,12 @@ class PresentationMediaItem(MediaManagerItem):
Constructor. Setup defaults
"""
self.controllers = controllers
self.PluginNameShort = u'Presentation'
self.pluginNameVisible = translate('PresentationPlugin.MediaItem',
'Presentation')
self.IconPath = u'presentations/presentation'
self.Automatic = u''
# this next is a class, not an instance of a class - it will
# be instanced by the base MediaManagerItem
self.ListViewWithDnD_class = PresentationListView
MediaManagerItem.__init__(self, parent, icon, title)
MediaManagerItem.__init__(self, parent, self, icon)
self.message_listener = MessageListener(self)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild)

View File

@ -110,10 +110,10 @@ class PowerpointDocument(PresentationDocument):
"""
Class which holds information and controls a single presentation
"""
def __init__(self, controller, presentation):
"""
Constructor, store information about the file and initialise
Constructor, store information about the file and initialise
"""
log.debug(u'Init Presentation Powerpoint')
PresentationDocument.__init__(self, controller, presentation)
@ -125,13 +125,13 @@ class PowerpointDocument(PresentationDocument):
Opens the PowerPoint file using the process created earlier
``presentation``
The file name of the presentations to run.
The file name of the presentations to run.
"""
log.debug(u'LoadPresentation')
if not self.controller.process or not self.controller.process.Visible:
self.controller.start_process()
try:
self.controller.process.Presentations.Open(self.filepath, False,
self.controller.process.Presentations.Open(self.filepath, False,
False, True)
except pywintypes.com_error:
return False
@ -143,22 +143,24 @@ class PowerpointDocument(PresentationDocument):
def create_thumbnails(self):
"""
Create the thumbnail images for the current presentation.
Note an alternative and quicker method would be do
Note an alternative and quicker method would be do::
self.presentation.Slides[n].Copy()
thumbnail = QApplication.clipboard.image()
But for now we want a physical file since it makes
life easier elsewhere
However, for the moment, we want a physical file since it makes life
easier elsewhere.
"""
if self.check_thumbnails():
return
self.presentation.Export(os.path.join(self.get_thumbnail_folder(), ''),
self.presentation.Export(os.path.join(self.get_thumbnail_folder(), ''),
'png', 320, 240)
def close_presentation(self):
"""
Close presentation and clean up objects
Triggerent by new object being added to SlideController orOpenLP
being shut down
Close presentation and clean up objects. This is triggered by a new
object being added to SlideController or OpenLP being shut down.
"""
log.debug(u'ClosePresentation')
if self.presentation:
@ -171,7 +173,7 @@ class PowerpointDocument(PresentationDocument):
def is_loaded(self):
"""
Returns true if a presentation is loaded
Returns ``True`` if a presentation is loaded.
"""
try:
if not self.controller.process.Visible:
@ -187,7 +189,7 @@ class PowerpointDocument(PresentationDocument):
def is_active(self):
"""
Returns true if a presentation is currently active
Returns ``True`` if a presentation is currently active.
"""
if not self.is_loaded():
return False
@ -202,7 +204,7 @@ class PowerpointDocument(PresentationDocument):
def unblank_screen(self):
"""
Unblanks (restores) the presentationn
Unblanks (restores) the presentation.
"""
self.presentation.SlideShowSettings.Run()
self.presentation.SlideShowWindow.View.State = 1
@ -210,13 +212,13 @@ class PowerpointDocument(PresentationDocument):
def blank_screen(self):
"""
Blanks the screen
Blanks the screen.
"""
self.presentation.SlideShowWindow.View.State = 3
def is_blank(self):
"""
Returns true if screen is blank
Returns ``True`` if screen is blank.
"""
if self.is_active():
return self.presentation.SlideShowWindow.View.State == 3
@ -225,14 +227,14 @@ class PowerpointDocument(PresentationDocument):
def stop_presentation(self):
"""
Stops the current presentation and hides the output
Stops the current presentation and hides the output.
"""
self.presentation.SlideShowWindow.View.Exit()
if os.name == u'nt':
def start_presentation(self):
"""
Starts a presentation from the beginning
Starts a presentation from the beginning.
"""
#SlideShowWindow measures its size/position by points, not pixels
try:
@ -254,40 +256,40 @@ class PowerpointDocument(PresentationDocument):
def get_slide_number(self):
"""
Returns the current slide number
Returns the current slide number.
"""
return self.presentation.SlideShowWindow.View.CurrentShowPosition
def get_slide_count(self):
"""
Returns total number of slides
Returns total number of slides.
"""
return self.presentation.Slides.Count
def goto_slide(self, slideno):
"""
Moves to a specific slide in the presentation
Moves to a specific slide in the presentation.
"""
self.presentation.SlideShowWindow.View.GotoSlide(slideno)
def next_step(self):
"""
Triggers the next effect of slide on the running presentation
Triggers the next effect of slide on the running presentation.
"""
self.presentation.SlideShowWindow.View.Next()
def previous_step(self):
"""
Triggers the previous slide on the running presentation
Triggers the previous slide on the running presentation.
"""
self.presentation.SlideShowWindow.View.Previous()
def get_slide_text(self, slide_no):
"""
Returns the text on the slide
Returns the text on the slide.
``slide_no``
The slide the text is required for, starting at 1
The slide the text is required for, starting at 1.
"""
text = ''
shapes = self.presentation.Slides(slide_no).Shapes
@ -299,10 +301,10 @@ class PowerpointDocument(PresentationDocument):
def get_slide_notes(self, slide_no):
"""
Returns the text on the slide
Returns the text on the slide.
``slide_no``
The slide the notes are required for, starting at 1
The slide the notes are required for, starting at 1.
"""
text = ''
shapes = self.presentation.Slides(slide_no).NotesPage.Shapes

View File

@ -37,16 +37,21 @@ log = logging.getLogger(__name__)
class PresentationController(object):
"""
Base class for presentation controllers to inherit from
Class to control interactions with presentations.
It creates the runtime environment
To create a new controller, take a copy of this file and name it
so it ends in controller.py, i.e. foobarcontroller.py
Make sure it inherits PresentationController
Then fill in the blanks. If possible try and make sure it loads
on all platforms, using for example os.name checks, although
__init__, check_available and presentation_deleted should always work.
See impresscontroller, powerpointcontroller or pptviewcontroller
This class is used to control interactions with presentation applications
by creating a runtime environment. This is a base class for presentation
controllers to inherit from.
To create a new controller, take a copy of this file and name it so it ends
with ``controller.py``, i.e. ``foobarcontroller.py``. Make sure it inherits
:class:`~openlp.plugins.presentations.lib.presentationcontroller.PresentationController`,
and then fill in the blanks. If possible try to make sure it loads on all
platforms, usually by using :mod:``os.name`` checks, although
``__init__``, ``check_available`` and ``presentation_deleted`` should
always be implemented.
See :class:`~openlp.plugins.presentations.lib.impresscontroller.ImpressController`,
:class:`~openlp.plugins.presentations.lib.powerpointcontroller.PowerpointController` or
:class:`~openlp.plugins.presentations.lib.pptviewcontroller.PptviewController`
for examples.
**Basic Attributes**
@ -70,7 +75,7 @@ class PresentationController(object):
``alsosupports``
Other file types the application can import, although not necessarily
the first choice due to potential incompatibilities
**Hook Functions**
``kill()``
@ -246,7 +251,7 @@ class PresentationDocument(object):
``presentation``
The file name of the presentations to the run.
Returns False if the file could not be opened
"""
return False
@ -387,7 +392,7 @@ class PresentationDocument(object):
if os.path.isfile(file):
img = resize_image(file, 320, 240)
img.save(self.get_thumbnail_path(idx, False))
def get_thumbnail_path(self, slide_no, check_exists):
"""
Returns an image path containing a preview for the requested slide

View File

@ -32,20 +32,18 @@ class PresentationTab(SettingsTab):
"""
PresentationsTab is the Presentations settings tab in the settings dialog.
"""
def __init__(self, title, controllers):
def __init__(self, title, visible_title, controllers):
"""
Constructor
"""
self.controllers = controllers
SettingsTab.__init__(self, title)
SettingsTab.__init__(self, title, visible_title)
def setupUi(self):
"""
Create the controls for the settings tab
"""
self.setObjectName(u'PresentationTab')
self.tabTitleVisible = translate('PresentationPlugin.PresentationTab',
'Presentations')
self.PresentationLayout = QtGui.QHBoxLayout(self)
self.PresentationLayout.setSpacing(8)
self.PresentationLayout.setMargin(8)

View File

@ -30,7 +30,7 @@ presentations from a variety of document formats.
import os
import logging
from openlp.core.lib import Plugin, build_icon, translate
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.utils import AppLocation
from openlp.plugins.presentations.lib import PresentationController, \
PresentationMediaItem, PresentationTab
@ -60,7 +60,8 @@ class PresentationPlugin(Plugin):
"""
Create the settings Tab
"""
return PresentationTab(self.name, self.controllers)
visible_name = self.getString(StringContent.VisibleName)
return PresentationTab(self.name, visible_name[u'title'], self.controllers)
def initialise(self):
"""
@ -143,3 +144,48 @@ class PresentationPlugin(Plugin):
'programs. The choice of available presentation programs is '
'available to the user in a drop down box.')
return about_text
def setPluginTextStrings(self):
"""
Called to define all translatable texts of the plugin
"""
## Name PluginList ##
self.textStrings[StringContent.Name] = {
u'singular': translate('PresentationPlugin', 'Presentation'),
u'plural': translate('PresentationPlugin', 'Presentations')
}
## Name for MediaDockManager, SettingsManager ##
self.textStrings[StringContent.VisibleName] = {
u'title': translate('PresentationPlugin', 'Presentations')
}
# Middle Header Bar
## Load Button ##
self.textStrings[StringContent.Load] = {
u'title': translate('PresentationPlugin', 'Load'),
u'tooltip': translate('PresentationPlugin',
'Load a new Presentation')
}
## Delete Button ##
self.textStrings[StringContent.Delete] = {
u'title': translate('PresentationPlugin', 'Delete'),
u'tooltip': translate('PresentationPlugin',
'Delete the selected Presentation')
}
## Preview ##
self.textStrings[StringContent.Preview] = {
u'title': translate('PresentationPlugin', 'Preview'),
u'tooltip': translate('PresentationPlugin',
'Preview the selected Presentation')
}
## Live Button ##
self.textStrings[StringContent.Live] = {
u'title': translate('PresentationPlugin', 'Live'),
u'tooltip': translate('PresentationPlugin',
'Send the selected Presentation live')
}
## Add to service Button ##
self.textStrings[StringContent.Service] = {
u'title': translate('PresentationPlugin', 'Service'),
u'tooltip': translate('PresentationPlugin',
'Add the selected Presentation to the service')
}

View File

@ -32,12 +32,11 @@ class RemoteTab(SettingsTab):
"""
RemoteTab is the Remotes settings tab in the settings dialog.
"""
def __init__(self, title):
SettingsTab.__init__(self, title)
def __init__(self, title, visible_title):
SettingsTab.__init__(self, title, visible_title)
def setupUi(self):
self.setObjectName(u'RemoteTab')
self.tabTitleVisible = translate('RemotePlugin.RemoteTab', 'Remotes')
self.remoteLayout = QtGui.QFormLayout(self)
self.remoteLayout.setSpacing(8)
self.remoteLayout.setMargin(8)

View File

@ -26,7 +26,7 @@
import logging
from openlp.core.lib import Plugin, translate, build_icon
from openlp.core.lib import Plugin, StringContent, translate, build_icon
from openlp.plugins.remotes.lib import RemoteTab, HttpServer
log = logging.getLogger(__name__)
@ -65,7 +65,8 @@ class RemotesPlugin(Plugin):
"""
Create the settings Tab
"""
return RemoteTab(self.name)
visible_name = self.getString(StringContent.VisibleName)
return RemoteTab(self.name, visible_name[u'title'])
def about(self):
"""
@ -76,3 +77,17 @@ class RemotesPlugin(Plugin):
'a running version of OpenLP on a different computer via a web '
'browser or through the remote API.')
return about_text
def setPluginTextStrings(self):
"""
Called to define all translatable texts of the plugin
"""
## Name PluginList ##
self.textStrings[StringContent.Name] = {
u'singular': translate('RemotePlugin', 'Remote'),
u'plural': translate('RemotePlugin', 'Remotes')
}
## Name for MediaDockManager, SettingsManager ##
self.textStrings[StringContent.VisibleName] = {
u'title': translate('RemotePlugin', 'Remotes')
}

View File

@ -24,10 +24,37 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Forms in OpenLP are made up of two classes. One class holds all the graphical
elements, like buttons and lists, and the other class holds all the functional
code, like slots and loading and saving.
The first class, commonly known as the **Dialog** class, is typically named
``Ui_<name>Dialog``. It is a slightly modified version of the class that the
``pyuic4`` command produces from Qt4's .ui file. Typical modifications will be
converting most strings from "" to u'' and using OpenLP's ``translate()``
function for translating strings.
The second class, commonly known as the **Form** class, is typically named
``<name>Form``. This class is the one which is instantiated and used. It uses
dual inheritance to inherit from (usually) QtGui.QDialog and the Ui class
mentioned above, like so::
class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
This allows OpenLP to use ``self.object`` for all the GUI elements while keeping
them separate from the functionality, so that it is easier to recreate the GUI
from the .ui files later if necessary.
"""
from authorsform import AuthorsForm
from topicsform import TopicsForm
from songbookform import SongBookForm
from editverseform import EditVerseForm
from editsongform import EditSongForm
from songmaintenanceform import SongMaintenanceForm
from songimportform import ImportWizardForm
from songimportform import SongImportForm

View File

@ -483,6 +483,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.VerseListWidget.resizeRowsToContents()
self.VerseListWidget.repaint()
self.tagRows()
self.VerseEditButton.setEnabled(False)
self.VerseDeleteButton.setEnabled(False)
def onVerseDeleteButtonClicked(self):
self.VerseListWidget.removeRow(self.VerseListWidget.currentRow())

View File

@ -53,6 +53,9 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
QtCore.QObject.connect(self.verseTextEdit,
QtCore.SIGNAL(u'cursorPositionChanged()'),
self.onCursorPositionChanged)
QtCore.QObject.connect(self.verseTypeComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onVerseTypeComboBoxChanged)
self.verse_regex = re.compile(r'---\[([-\w]+):([\d]+)\]---')
def contextMenu(self, point):
@ -66,27 +69,43 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
self.verseTextEdit.setFocus()
def onInsertButtonClicked(self):
if self.verseTextEdit.textCursor().columnNumber() != 0:
self.verseTextEdit.insertPlainText(u'\n')
verse_type = self.verseTypeComboBox.currentIndex()
if verse_type == VerseType.Verse:
self.insertVerse(VerseType.to_string(VerseType.Verse),
if VerseType.to_string(verse_type) is not None:
self.insertVerse(VerseType.to_string(verse_type),
self.verseNumberBox.value())
elif verse_type == VerseType.Chorus:
self.insertVerse(VerseType.to_string(VerseType.Chorus),
self.verseNumberBox.value())
elif verse_type == VerseType.Bridge:
self.insertVerse(VerseType.to_string(VerseType.Bridge))
elif verse_type == VerseType.PreChorus:
self.insertVerse(VerseType.to_string(VerseType.PreChorus))
elif verse_type == VerseType.Intro:
self.insertVerse(VerseType.to_string(VerseType.Intro))
elif verse_type == VerseType.Ending:
self.insertVerse(VerseType.to_string(VerseType.Ending))
elif verse_type == VerseType.Other:
self.insertVerse(VerseType.to_string(VerseType.Other))
def onVerseTypeComboBoxChanged(self):
"""
Adjusts the verse number SpinBox in regard to the selected verse type
and the cursor's position.
"""
position = self.verseTextEdit.textCursor().position()
text = unicode(self.verseTextEdit.toPlainText())
verse_type = VerseType.to_string(self.verseTypeComboBox.currentIndex())
if not text:
return
position = text.rfind(u'---[%s' % verse_type, 0, position)
if position == -1:
self.verseNumberBox.setValue(1)
return
text = text[position:]
position = text.find(u']---')
if position == -1:
return
text = text[:position + 4]
match = self.verse_regex.match(text)
if match:
verse_type = match.group(1)
verse_number = int(match.group(2))
verse_type_index = VerseType.from_string(verse_type)
if verse_type_index is not None:
self.verseNumberBox.setValue(verse_number)
def onCursorPositionChanged(self):
"""
Determines the previous verse type and number in regard to the cursor's
position and adjusts the ComboBox and SpinBox to these values.
"""
position = self.verseTextEdit.textCursor().position()
text = unicode(self.verseTextEdit.toPlainText())
if not text:

View File

@ -35,7 +35,7 @@ from openlp.plugins.songs.lib.importer import SongFormat
log = logging.getLogger(__name__)
class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
class SongImportForm(QtGui.QWizard, Ui_SongImportWizard):
"""
This is the Song Import Wizard, which allows easy importing of Songs
into OpenLP from other formats like OpenLyrics, OpenSong and CCLI.
@ -248,18 +248,24 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
# Progress page
return True
def getFileName(self, title, editbox):
def getFileName(self, title, editbox,
filters = '%s (*)' % translate('SongsPlugin.ImportWizardForm',
'All Files')):
filename = QtGui.QFileDialog.getOpenFileName(self, title,
SettingsManager.get_last_dir(self.plugin.settingsSection, 1))
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
filters)
if filename:
editbox.setText(filename)
SettingsManager.set_last_dir(
self.plugin.settingsSection,
os.path.split(unicode(filename))[0], 1)
def getFiles(self, title, listbox):
def getFiles(self, title, listbox,
filters = u'%s (*)' % translate('SongsPlugin.ImportWizardForm',
'All Files')):
filenames = QtGui.QFileDialog.getOpenFileNames(self, title,
SettingsManager.get_last_dir(self.plugin.settingsSection, 1))
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
filters)
if filenames:
listbox.addItems(filenames)
SettingsManager.set_last_dir(
@ -281,14 +287,24 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
self.getFileName(
translate('SongsPlugin.ImportWizardForm',
'Select OpenLP 2.0 Database File'),
self.openLP2FilenameEdit
self.openLP2FilenameEdit,
u'%s (*.sqlite);;%s (*)'
% (translate('SongsPlugin.ImportWizardForm',
'OpenLP 2.0 Databases'),
translate('SongsPlugin.ImportWizardForm',
'All Files'))
)
def onOpenLP1BrowseButtonClicked(self):
self.getFileName(
translate('SongsPlugin.ImportWizardForm',
'Select openlp.org 1.x Database File'),
self.openLP1FilenameEdit
self.openLP1FilenameEdit,
u'%s (*.olp);;%s (*)'
% (translate('SongsPlugin.ImportWizardForm',
'openlp.org v1.x Databases'),
translate('SongsPlugin.ImportWizardForm',
'All Files'))
)
#def onOpenLyricsAddButtonClicked(self):
@ -315,7 +331,12 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
self.getFiles(
translate('SongsPlugin.ImportWizardForm',
'Select Words of Worship Files'),
self.wordsOfWorshipFileListWidget
self.wordsOfWorshipFileListWidget,
u'%s (*.wsg *.wow-song);;%s (*)'
% (translate('SongsPlugin.ImportWizardForm',
'Words Of Worship Song Files'),
translate('SongsPlugin.ImportWizardForm',
'All Files'))
)
def onWordsOfWorshipRemoveButtonClicked(self):
@ -335,7 +356,12 @@ class ImportWizardForm(QtGui.QWizard, Ui_SongImportWizard):
self.getFiles(
translate('SongsPlugin.ImportWizardForm',
'Select Songs of Fellowship Files'),
self.songsOfFellowshipFileListWidget
self.songsOfFellowshipFileListWidget,
u'%s (*.rtf);;%s (*)'
% (translate('SongsPlugin.ImportWizardForm',
'Songs Of Felloship Song Files'),
translate('SongsPlugin.ImportWizardForm',
'All Files'))
)
def onSongsOfFellowshipRemoveButtonClicked(self):

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