This commit is contained in:
Raoul Snyman 2011-03-14 23:17:28 +02:00
commit 304202bbfc
90 changed files with 16323 additions and 7819 deletions

View File

@ -4,13 +4,10 @@ recursive-include openlp *.csv
recursive-include openlp *.html
recursive-include openlp *.js
recursive-include openlp *.css
recursive-include openlp *.qm
recursive-include documentation *
recursive-include resources/forms *
recursive-include resources/i18n *
recursive-include resources/images *
recursive-include scripts *.py
include resources/*.desktop
recursive-include resources *
recursive-include scripts *
include copyright.txt
include LICENSE
include README.txt
include openlp/.version

View File

@ -4,11 +4,11 @@ Dual Monitor Setup
The first step in getting OpenLP working on your system is to setup your
computer properly for dual monitors. This is not very difficult, but the steps
do vary depending on operating system.
will vary depending on operating system.
Most modern computers do have the ability for dual monitors. To be certain
Most modern computers have the ability for dual monitors. To be certain,
check your computer's documentation. A typical desktop computer capable of dual
monitors will have two of, or a combination of the two connectors below.
monitors will have two of, or a combination of the two, connectors below.
**VGA**
@ -18,8 +18,8 @@ monitors will have two of, or a combination of the two connectors below.
.. image:: pics/dvi.png
A laptop computer setup only varies slightly, generally you will need only one
of outputs pictured above since your laptops screen serves as one of the
A laptop computer setup only varies slightly. Generally you will need only one
of the outputs pictured above since your laptop screen serves as one of the
monitors. Sometimes with older laptops a key stroke generally involving the
:kbd:`Fn` key and another key is required to enable the second monitor on
laptops.
@ -27,9 +27,10 @@ laptops.
Some computers also incorporate the use of :abbr:`S-Video (Separate Video)` or
:abbr:`HDMI (High-Definition Multimedia Interface)` connections.
A typical OpenLP set up consist of your normal single monitor setup, with your
projector setup as the second monitor. With the option of extending your
desktop across the second monitor, or your operating system's equivalent.
A typical OpenLP setup consist of your normal single monitor, with your
projector hooked up to your computer as the second monitor. With the option of
extending your desktop across the second monitor, or your operating system's
equivalent.
Microsoft Windows
-----------------
@ -46,8 +47,8 @@ press :kbd:`Windows+P`.
The more traditional way is also fairly straight forward. Go to
:guilabel:`Control Panel` and click on :guilabel:`Display`. This will open up
the :guilabel:`Display` dialog. You can also bypass this step by right click on
a blank area on your desktop and selecting :guilabel:`Resolution`.
the :guilabel:`Display` dialog. You may also bypass this step by a right click
on a blank area on your desktop and selecting :guilabel:`Resolution`.
.. image:: pics/winsevendisplay.png
@ -66,7 +67,7 @@ a blank place on the desktop and click :guilabel:`Personalization`.
.. image:: pics/vistapersonalize.png
From the :guilabel:`Personalization` window click on :guilabel:`Display
Settings`. Then enable the montior that represents your projector and make sure
Settings`. Click on the monitor that represents your projector and make sure
you have checked :guilabel:`Extend the desktop onto this monitor`.
.. image:: pics/vistadisplaysettings.png
@ -77,7 +78,7 @@ Windows XP
From :guilabel:`Control Panel` select :guilabel:`Display`, or right click on a
blank area of the desktop and select :guilabel:`Properties`. From the
:guilabel:`Display Properties` window click on the :guilabel:`Settings` tab.
Then click on the monitor that represents your projector and make sure you have
Click on the monitor that represents your projector and make sure you have
checked :guilabel:`Extend my Windows desktop onto this monitor`.
.. image:: pics/xpdisplaysettings.png
@ -87,7 +88,7 @@ Linux
Due to the vast varieties of hardware, distributions, desktops, and drivers
this is not an exhaustive guide to dual monitor setup on Linux. This guide
assumes that you have properly set up any proprietary drivers if needed. You
assumes you have properly set up any proprietary drivers if needed. You
should seek out your distributions documentation if this general guide does not
work.
@ -123,7 +124,8 @@ Linux Systems Using nVidia Drivers
This guide is for users of the proprietary nVidia driver on Linux Distributions.
It is assumed that you have properly setup your drivers according to your
distribution's documentation, and you have a working ``xorg.conf`` file in place.
distribution's documentation, and you have a working ``xorg.conf`` file in
place.
If you wish to make the changes permanent in setting up your system for dual
monitors it will be necessary to modify your ``xorg.conf`` file. It is always a
@ -166,7 +168,7 @@ After clicking :guilabel:`Configure`, select :guilabel:`TwinView`. Then click
.. image:: pics/twinview.png
Then click :guilabel:`Apply` and if you are happy with the way things look click
Click :guilabel:`Apply` and if you are happy with the way things look click
:guilabel:`Keep` to keep your new settings. Don't worry if all goes wrong the
settings will return back to the previous settings in 15 seconds without any
action. nVidia Settings should take care of selecting your optimum resolution
@ -175,6 +177,6 @@ on :guilabel:`Save to X Configuration File`.
.. image:: pics/xorgwrite.png
Then click :guilabel:`Save` and you should be set. You may want to restart X or
Click :guilabel:`Save` and you should be set. You may want to restart X or
your machine just to make sure all the settings carry over the next time you log
in.

View File

@ -18,7 +18,7 @@ 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.
The Media Manager contains a number of tabs the plugins supply to OpenLP.
Each tab in the Media Manager is called a **Media Item**
.. image:: pics/mediamanager.png
@ -36,20 +36,20 @@ with them.
Service File
------------
A service file, is the file that is created when you save your work on OpenLP.
A service file is the file that is created when you save your service in OpenLP.
The service file consist of **Service Items**
Service Item
------------
A service item are the **media items** that are in the **service manager**
Service items are the **media items** that are in the **service manager**
Service Manger
--------------
The service manager contains the media items in your service file. This is the
area from which your media items go live, and you can also save, open, and edit
services files.
area where your media items go live. You can also save, open, and edit
services files from here.
.. image:: pics/servicemanager.png
@ -65,6 +65,6 @@ Theme Manager
-------------
The theme manager is where themes are created and edited. Themes are the text
styles backgrounds that you use to personalize your services.
styles and backgrounds that you use to personalize your services.
.. image:: pics/thememanager.png

View File

@ -16,4 +16,3 @@ Contents:
dualmonitors
mediamanager
songs

View File

@ -8,26 +8,26 @@ converters provided to get data from other formats into OpenLP.
Song Importer
=============
If you are using an earlier version of OpenLP or come from another software
If you are using an earlier version of OpenLP or, come from another software
package, you may be able to convert your existing database to work in OpenLP
2.0. To access the Song Importer :menuselection:`File --> Import --> Song`.
You will then see the Song Importer window, then click :guilabel:`Next`.
2.0. To access the Song Importer click :menuselection:`File --> Import --> Song`.
You will see the Song Importer window, then click :guilabel:`Next`.
.. image:: pics/songimporter.png
After choosing :guilabel:`Next` you can then select from the various types of
After choosing :guilabel:`Next` you can select from the various types of
software that OpenLP will convert songs from.
.. image:: pics/songimporterchoices.png
Then click on the file folder icon to choose the file of the song database you
Click on the file folder icon to choose the file of the song database you
want to import. See the following sections for information on the different
formats that OpenLP will import.
Importing from OpenLP Version 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Converting from OpenLP Version 1 is a pretty simple process. You will first
Converting from OpenLP Version 1 is a simple process. First you will
need to locate your version 1 database file.
Windows XP::
@ -38,33 +38,34 @@ Windows Vista / Windows 7::
C:\ProgramData\openlp.org\Data\songs.olp
After clicking :guilabel:`Next` your conversion should be complete.
After clicking :guilabel:`Next` your conversion will be complete.
.. image:: pics/finishedimport.png
Then press :guilabel:`Finish` and you should now be ready to use your OpenLP
version one songs.
Press :guilabel:`Finish` and you will now be ready to use your OpenLP
version 1 songs.
Importing from OpenSong
^^^^^^^^^^^^^^^^^^^^^^^
Converting from OpenSong you will need to locate your songs database. In the
Converting from OpenSong, you will need to locate your songs database. In the
later versions of OpenSong you are asked to define the location of this. The
songs will be located in a folder named :guilabel:`Songs`. This folder should
contain files with all your songs in them without a file extension. (file.xxx).
When you have located this folder you will then need to select the songs from
songs will be located in a folder named :guilabel:`Songs`. This folder will
contain files with all your songs in them, without a file extension. (file.xxx).
When you have located this folder you will need to select the songs from
the folder.
.. image:: pics/selectsongs.png
On most operating systems to select all the songs, first select the first song
in the lest then press shift and select the last song in the list. After this
press :guilabel:`Next` and you should see that your import has been successful.
On most operating systems, to select all the songs, first select the first song
in the list, press the shift key, and select the last song in the list. After
this press :guilabel:`Next` and you will see that your import has been
successful.
.. image:: pics/finishedimport.png
Press :guilabel:`Finish` and you will now be ready to use your songs imported
from OpenSong.
Press :guilabel:`Finish` and OpenLP will be ready to use your songs that you
imported from OpenSong.
Importing from CCLI Song Select
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -79,22 +80,23 @@ Then search for your desired song. For this example we will be adding the song
.. image:: pics/songselectsongsearch.png
For the song you are searching for select `lyrics` This should take you to a
page displaying the lyrics and copyright info for your song.
For the song you are searching for, select `lyrics` This will take you to a
page displaying the lyrics and copyright information for your song.
.. image:: pics/songselectlyrics.png
Next, hover over the :guilabel:`Lyrics` menu from the upper right corner. Then
choose either the .txt or .usr file. You will then be asked to chose a download
Next, hover over the :guilabel:`Lyrics` menu from the upper right corner.
Choose either the .txt or .usr file. You will be asked to chose a download
location if your browser does not automatically select that for you. Select
this file from the OpenLP import window and then click :guilabel:`Next` You can
also select multiple songs for import at once on most operating systems by
selecting the first item in the list then holding shift select the last item in
the list. When finished you should see that your import has completed.
selecting the first item in the list then holding the shift key and select the
last item in the list. When finished, you will see that your import has
completed.
.. image:: pics/finishedimport.png
Press :guilabel:`Finish` and you will now be ready to use your songs imported
Press :guilabel:`Finish` and OpenLP will be ready to use your songs imported
from CCLI SongSelect.

View File

@ -24,7 +24,6 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import os
import sys
import logging
@ -37,6 +36,8 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, check_directory_exists
from openlp.core.resources import qInitResources
from openlp.core.ui.mainwindow import MainWindow
from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm
from openlp.core.ui.firsttimeform import FirstTimeForm
from openlp.core.ui.exceptionform import ExceptionForm
from openlp.core.ui import SplashScreen, ScreenList
from openlp.core.utils import AppLocation, LanguageManager, VersionThread
@ -150,10 +151,6 @@ class OpenLP(QtGui.QApplication):
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)
def run(self):
"""
Run the OpenLP application.
@ -170,6 +167,13 @@ class OpenLP(QtGui.QApplication):
self.setOrganizationDomain(u'openlp.org')
self.setApplicationName(u'OpenLP')
self.setApplicationVersion(app_version[u'version'])
# Decide how many screens we have and their size
screens = ScreenList(self.desktop())
# First time checks in settings
has_run_wizard = QtCore.QSettings().value(
u'general/has run wizard', QtCore.QVariant(False)).toBool()
if not has_run_wizard:
FirstTimeForm(screens).exec_()
if os.name == u'nt':
self.setStyleSheet(application_stylesheet)
show_splash = QtCore.QSettings().value(
@ -179,22 +183,16 @@ class OpenLP(QtGui.QApplication):
self.splash.show()
# make sure Qt really display the splash screen
self.processEvents()
screens = ScreenList()
# Decide how many screens we have and their size
for screen in xrange(0, self.desktop().numScreens()):
size = self.desktop().screenGeometry(screen)
screens.add_screen({u'number': screen,
u'size': size,
u'primary': (self.desktop().primaryScreen() == screen)})
log.info(u'Screen %d found with resolution %s', screen, size)
# start the main app window
self.appClipboard = self.clipboard()
self.mainWindow = MainWindow(screens, app_version, self.appClipboard)
self.mainWindow = MainWindow(screens, app_version, self.clipboard())
self.mainWindow.show()
if show_splash:
# now kill the splashscreen
self.splash.finish(self.mainWindow)
self.mainWindow.repaint()
self.processEvents()
if not has_run_wizard:
self.mainWindow.firstTime()
update_check = QtCore.QSettings().value(
u'general/update check', QtCore.QVariant(True)).toBool()
if update_check:
@ -273,10 +271,19 @@ def main():
qInitResources()
# Now create and actually run the application.
app = OpenLP(qt_args)
if sys.platform == 'darwin':
# Define the settings environment
settings = QtCore.QSettings(u'OpenLP', u'OpenLP')
# First time checks in settings
# Use explicit reference as not inside a QT environment yet
if not settings.value(u'general/has run wizard',
QtCore.QVariant(False)).toBool():
if not FirstTimeLanguageForm().exec_():
# if cancel then stop processing
sys.exit()
if sys.platform == u'darwin':
OpenLP.addLibraryPath(QtGui.QApplication.applicationDirPath()
+ "/qt4_plugins")
#i18n Set Language
# i18n Set Language
language = LanguageManager.get_language()
appTranslator = LanguageManager.get_translator(language)
app.installTranslator(appTranslator)

View File

@ -248,9 +248,8 @@ def resize_image(image, width, height, background=QtCore.Qt.black):
``height``
The new image height.
``background``
``background``
The background colour defaults to black.
"""
log.debug(u'resize_image - start')
if isinstance(image, QtGui.QImage):

View File

@ -349,11 +349,11 @@ class MediaManagerItem(QtGui.QWidget):
Validates whether an image still exists and, if it does, is the
thumbnail representation of the image up to date.
"""
if not os.path.exists(image):
if not os.path.exists(unicode(image)):
return False
if os.path.exists(thumb):
imageDate = os.stat(image).st_mtime
thumbDate = os.stat(thumb).st_mtime
imageDate = os.stat(unicode(image)).st_mtime
thumbDate = os.stat(unicode(thumb)).st_mtime
# If image has been updated rebuild icon
if imageDate > thumbDate:
self.iconFromFile(image, thumb)

View File

@ -114,8 +114,8 @@ class Plugin(QtCore.QObject):
"""
log.info(u'loaded')
def __init__(self, name, version=None, pluginHelpers=None,
mediaItemClass=None, settingsTabClass=None):
def __init__(self, name, pluginHelpers=None, mediaItemClass=None,
settingsTabClass=None, version=None):
"""
This is the constructor for the plugin object. This provides an easy
way for descendent plugins to populate common data. This method *must*
@ -123,7 +123,7 @@ class Plugin(QtCore.QObject):
class MyPlugin(Plugin):
def __init__(self):
Plugin.__init__(self, u'MyPlugin', u'0.1')
Plugin.__init__(self, u'MyPlugin', version=u'0.1')
``name``
Defaults to *None*. The name of the plugin.
@ -145,8 +145,7 @@ class Plugin(QtCore.QObject):
self.textStrings = {}
self.setPluginTextStrings()
self.nameStrings = self.textStrings[StringContent.Name]
if version:
self.version = version
self.version = version if version else u'1.9.4'
self.settingsSection = self.name.lower()
self.icon = None
self.mediaItemClass = mediaItemClass

View File

@ -49,16 +49,13 @@ class PluginManager(object):
``plugin_dir``
The directory to search for plugins.
"""
log.info(u'Plugin manager initing')
log.info(u'Plugin manager Initialising')
if not plugin_dir in sys.path:
log.debug(u'Inserting %s into sys.path', plugin_dir)
sys.path.insert(0, plugin_dir)
self.basepath = os.path.abspath(plugin_dir)
log.debug(u'Base path %s ', self.basepath)
self.plugin_helpers = []
self.plugins = []
# this has to happen after the UI is sorted
# self.find_plugins(plugin_dir)
log.info(u'Plugin manager Initialised')
def find_plugins(self, plugin_dir, plugin_helpers):
@ -73,7 +70,7 @@ class PluginManager(object):
A list of helper objects to pass to the plugins.
"""
self.plugin_helpers = plugin_helpers
log.info(u'Finding plugins')
startdepth = len(os.path.abspath(plugin_dir).split(os.sep))
log.debug(u'finding plugins in %s at depth %d',
unicode(plugin_dir), startdepth)
@ -102,11 +99,11 @@ class PluginManager(object):
plugin_objects = []
for p in plugin_classes:
try:
plugin = p(self.plugin_helpers)
log.debug(u'Loaded plugin %s with helpers', unicode(p))
plugin = p(plugin_helpers)
log.debug(u'Loaded plugin %s', unicode(p))
plugin_objects.append(plugin)
except TypeError:
log.exception(u'loaded plugin %s has no helpers', unicode(p))
log.exception(u'Failed to load plugin %s', unicode(p))
plugins_list = sorted(plugin_objects, self.order_by_weight)
for plugin in plugins_list:
if plugin.checkPreConditions():
@ -203,6 +200,7 @@ class PluginManager(object):
Loop through all the plugins and give them an opportunity to
initialise themselves.
"""
log.info(u'Initialise Plugins - Started')
for plugin in self.plugins:
log.info(u'initialising plugins %s in a %s state'
% (plugin.name, plugin.isActive()))
@ -211,6 +209,7 @@ class PluginManager(object):
log.info(u'Initialisation Complete for %s ' % plugin.name)
if not plugin.isActive():
plugin.removeToolboxItem()
log.info(u'Initialise Plugins - Finished')
def finalise_plugins(self):
"""

View File

@ -69,7 +69,6 @@ class RenderManager(object):
self.image_manager = ImageManager()
self.display = MainDisplay(self, screens, False)
self.display.imageManager = self.image_manager
self.display.setup()
self.theme_manager = theme_manager
self.renderer = Renderer()
self.calculate_default(self.screens.current[u'size'])

View File

@ -88,8 +88,8 @@ class ServiceItem(object):
self.audit = u''
self.items = []
self.iconic_representation = None
self.raw_footer = None
self.foot_text = None
self.raw_footer = []
self.foot_text = u''
self.theme = None
self.service_item_type = None
self._raw_frames = []
@ -183,9 +183,12 @@ class ServiceItem(object):
else:
log.error(u'Invalid value renderer :%s' % self.service_item_type)
self.title = clean_tags(self.title)
self.foot_text = None
if self.raw_footer:
self.foot_text = u'<br>'.join(self.raw_footer)
# The footer should never be None, but to be compatible with older
# release of OpenLP, we have to correct this to avoid tracebacks.
if self.raw_footer is None:
self.raw_footer = []
self.foot_text = \
u'<br>'.join([footer for footer in self.raw_footer if footer])
def add_from_image(self, path, title):
"""

View File

@ -48,7 +48,7 @@ class OpenLPToolbar(QtGui.QToolBar):
self.icons = {}
self.setIconSize(QtCore.QSize(20, 20))
self.actions = {}
log.debug(u'Init done')
log.debug(u'Init done for %s' % parent.__class__.__name__)
def addToolbarButton(self, title, icon, tooltip=None, slot=None,
checkable=False, shortcut=0, alternate=0,

View File

@ -51,6 +51,8 @@ class HideMode(object):
Theme = 2
Screen = 3
from firsttimeform import FirstTimeForm
from firsttimelanguageform import FirstTimeLanguageForm
from themeform import ThemeForm
from filerenameform import FileRenameForm
from starttimeform import StartTimeForm
@ -74,4 +76,4 @@ from thememanager import ThemeManager
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay',
'SlideController', 'ServiceManager', 'ThemeManager', 'MediaDockManager',
'ServiceItemEditForm']
'ServiceItemEditForm', u'FirstTimeForm']

View File

@ -108,19 +108,40 @@ class Ui_AboutDialog(object):
self.aboutNotebook.indexOf(self.aboutTab), UiStrings.About)
lead = u'Raoul "superfly" Snyman'
developers = [u'Tim "TRB143" Bentley', u'Jonathan "gushie" Corwin',
u'Michael "cocooncrash" Gorven', u'Scott "sguerrieri" Guerrieri',
u'Raoul "superfly" Snyman', u'Martin "mijiti" Thompson',
u'Jon "Meths" Tibble<']
contributors = [u'Meinert "m2j" Jordan', u'Andreas "googol" Preikschat',
u'Michael "cocooncrash" Gorven',
u'Andreas "googol" Preikschat', u'Raoul "superfly" Snyman',
u'Martin "mijiti" Thompson', u'Jon "Meths" Tibble']
contributors = [u'Scott "sguerrieri" Guerrieri',
u'Meinert "m2j" Jordan', u'Armin "orangeshirt" K\xf6hler',
u'Christian "crichter" Richter', u'Philip "Phill" Ridout',
u'Maikel Stuivenberg', u'Carsten "catini" Tingaard',
u'Frode "frodus" Woldsund']
testers = [u'Philip "Phill" Ridout', u'Wesley "wrst" Stout (lead)']
packagers = [u'Thomas "tabthorpe" Abthorpe (FreeBSD)',
u'Jeffrey "whydoubt" Smith', u'Maikel Stuivenberg',
u'Carsten "catini" Tingaard', u'Frode "frodus" Woldsund']
testers = [u'Philip "Phill" Ridout', u'Wesley "wrst" Stout',
u'John "jseagull1" Cegalis (lead)']
packagers = ['Thomas "tabthorpe" Abthorpe (FreeBSD)',
u'Tim "TRB143" Bentley (Fedora)',
u'Michael "cocooncrash" Gorven (Ubuntu)',
u'Matthias "matthub" Hub (Mac OS X)',
u'Raoul "superfly" Snyman (Windows, Ubuntu)']
translators = {
u'af': [u'Johan "nuvolari" Mynhardt'],
u'de': [u'Patrick "madmuffin" Br\xfcckner',
u'Meinert "m2j" Jordan',
u'Andreas "googol" Preikschat',
u'Christian "crichter" Richter'],
u'en_GB': [u'Tim "TRB143" Bentley', u'Jonathan "gushie" Corwin'],
u'en_ZA': [u'Raoul "superfly" Snyman'],
u'et': [u'Mattias "mahfiaz" P\xf5ldaru'],
u'fr': [u'Stephan\xe9 "stbrunner" Brunner'],
u'hu': [u'Gyuris Gellért'],
u'ja': [u'Kunio "Kunio" Nakamaru'],
u'nb': [u'Atle "pendlaren" Weibell', u'Frode "frodus" Woldsund'],
u'nl': [u'Arjen "typovar" van Voorst'],
u'pt_BR': [u'Rafael "rafaellerm" Lerm'],
u'ru': [u'Sergey "ratz" Ratz']
}
documentors = [u'Wesley "wrst" Stout',
u'John "jseagull1" Cegalis (lead)']
self.creditsTextEdit.setPlainText(unicode(translate('OpenLP.AboutForm',
'Project Lead\n'
' %s\n'
@ -137,6 +158,35 @@ class Ui_AboutDialog(object):
'Packagers\n'
' %s\n'
'\n'
'Translators\n'
' Afrikaans (af)\n'
' %s\n'
' German (de)\n'
' %s\n'
' English, United Kingdom (en_GB)\n'
' %s\n'
' English, South Africa (en_ZA)\n'
' %s\n'
' Estonian (et)\n'
' %s\n'
' French (fr)\n'
' %s\n'
' Hungarian (hu)\n'
' %s\n'
' Japanese (ja)\n'
' %s\n'
' Norwegian Bokm\xe5l (nb)\n'
' %s\n'
' Dutch (nl)\n'
' %s\n'
' Portuguese, Brazil (pt_BR)\n'
' %s\n'
' Russian (ru)\n'
' %s\n'
'\n'
'Documentation\n'
' %s\n'
'\n'
'Built With\n'
' Python: http://www.python.org/\n'
' Qt4: http://qt.nokia.com/\n'
@ -155,7 +205,19 @@ class Ui_AboutDialog(object):
' bring this software to you for free because\n'
' He has set us free.')) % (lead, u'\n '.join(developers),
u'\n '.join(contributors), u'\n '.join(testers),
u'\n '.join(packagers)))
u'\n '.join(packagers), u'\n '.join(translators[u'af']),
u'\n '.join(translators[u'de']),
u'\n '.join(translators[u'en_GB']),
u'\n '.join(translators[u'en_ZA']),
u'\n '.join(translators[u'et']),
u'\n '.join(translators[u'fr']),
u'\n '.join(translators[u'hu']),
u'\n '.join(translators[u'ja']),
u'\n '.join(translators[u'nb']),
u'\n '.join(translators[u'nl']),
u'\n '.join(translators[u'pt_BR']),
u'\n '.join(translators[u'ru']),
u'\n '.join(documentors)))
self.aboutNotebook.setTabText(
self.aboutNotebook.indexOf(self.creditsTab),
translate('OpenLP.AboutForm', 'Credits'))
@ -164,7 +226,7 @@ class Ui_AboutDialog(object):
'Portions copyright \xa9 2004-2011 '
'Tim Bentley, Jonathan Corwin, Michael Gorven, Scott Guerrieri,\n'
'Meinert Jordan, Andreas Preikschat, Christian Richter, Philip\n'
'Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Carstenn'
'Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Carsten\n'
'Tinggaard, Frode Woldsund')
licence = translate('OpenLP.AboutForm',
'This program is free software; you can redistribute it and/or '

View File

@ -143,11 +143,11 @@ class Ui_DisplayTagDialog(object):
self.tagTableWidget.horizontalHeaderItem(0).setText(
translate('OpenLP.DisplayTagDialog', 'Description'))
self.tagTableWidget.horizontalHeaderItem(1).setText(
translate('OpenLP.DisplayTagDialog', 'Tag id'))
translate('OpenLP.DisplayTagDialog', 'Tag Id'))
self.tagTableWidget.horizontalHeaderItem(2).setText(
translate('OpenLP.DisplayTagDialog', 'Start Html'))
translate('OpenLP.DisplayTagDialog', 'Start HTML'))
self.tagTableWidget.horizontalHeaderItem(3).setText(
translate('OpenLP.DisplayTagDialog', 'End Html'))
translate('OpenLP.DisplayTagDialog', 'End HTML'))
self.tagTableWidget.setColumnWidth(0, 120)
self.tagTableWidget.setColumnWidth(1, 40)
self.tagTableWidget.setColumnWidth(2, 240)

View File

@ -0,0 +1,279 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, 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 io
import logging
import os
import urllib
from tempfile import gettempdir
from ConfigParser import SafeConfigParser
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate, PluginStatus, check_directory_exists, \
Receiver, build_icon
from openlp.core.utils import get_web_page, AppLocation
from firsttimewizard import Ui_FirstTimeWizard, FirstTimePage
log = logging.getLogger(__name__)
class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
"""
This is the Theme Import Wizard, which allows easy creation and editing of
OpenLP themes.
"""
log.info(u'ThemeWizardForm loaded')
def __init__(self, screens, parent=None):
QtGui.QWizard.__init__(self, parent)
self.setupUi(self)
# check to see if we have web access
self.web = u'http://openlp.org/files/frw/'
self.config = SafeConfigParser()
self.webAccess = get_web_page(u'%s%s' % (self.web, u'download.cfg'))
if self.webAccess:
files = self.webAccess.read()
self.config.readfp(io.BytesIO(files))
self.displayComboBox.addItems(screens.get_screen_list())
self.downloading = unicode(translate('OpenLP.FirstTimeWizard',
'Downloading %s...'))
QtCore.QObject.connect(self,
QtCore.SIGNAL(u'currentIdChanged(int)'),
self.onCurrentIdChanged)
def exec_(self, edit=False):
"""
Run the wizard.
"""
self.setDefaults()
return QtGui.QWizard.exec_(self)
def setDefaults(self):
"""
Set up display at start of theme edit.
"""
self.restart()
# Sort out internet access for downloads
if self.webAccess:
songs = self.config.get(u'songs', u'languages')
songs = songs.split(u',')
for song in songs:
title = unicode(self.config.get(
u'songs_%s' % song, u'title'), u'utf8')
filename = unicode(self.config.get(
u'songs_%s' % song, u'filename'), u'utf8')
item = QtGui.QListWidgetItem(title, self.songsListWidget)
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(filename))
item.setCheckState(QtCore.Qt.Unchecked)
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
bible_languages = self.config.get(u'bibles', u'languages')
bible_languages = bible_languages.split(u',')
for lang in bible_languages:
language = unicode(self.config.get(
u'bibles_%s' % lang, u'title'), u'utf8')
langItem = QtGui.QTreeWidgetItem(
self.biblesTreeWidget, QtCore.QStringList(language))
bibles = self.config.get(u'bibles_%s' % lang, u'translations')
bibles = bibles.split(u',')
for bible in bibles:
title = unicode(self.config.get(
u'bible_%s' % bible, u'title'), u'utf8')
filename = unicode(self.config.get(
u'bible_%s' % bible, u'filename'))
item = QtGui.QTreeWidgetItem(
langItem, QtCore.QStringList(title))
item.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(filename))
item.setCheckState(0, QtCore.Qt.Unchecked)
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
self.biblesTreeWidget.expandAll()
themes = self.config.get(u'themes', u'files')
themes = themes.split(u',')
if not os.path.exists(os.path.join(gettempdir(), u'openlp')):
os.makedirs(os.path.join(gettempdir(), u'openlp'))
for theme in themes:
title = self.config.get(u'theme_%s' % theme, u'title')
filename = self.config.get(u'theme_%s' % theme, u'filename')
screenshot = self.config.get(u'theme_%s' % theme, u'screenshot')
urllib.urlretrieve(u'%s/%s' % (self.web, screenshot),
os.path.join(gettempdir(), u'openlp', screenshot))
item = QtGui.QListWidgetItem(title, self.themesListWidget)
item.setData(QtCore.Qt.UserRole,
QtCore.QVariant(filename))
item.setIcon(build_icon(
os.path.join(gettempdir(), u'openlp', screenshot)))
item.setCheckState(QtCore.Qt.Unchecked)
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
def nextId(self):
"""
Determine the next page in the Wizard to go to.
"""
if self.currentId() == FirstTimePage.Plugins:
if not self.webAccess:
return FirstTimePage.NoInternet
else:
return FirstTimePage.Songs
elif self.currentId() == FirstTimePage.Progress:
return -1
else:
return self.currentId() + 1
def onCurrentIdChanged(self, pageId):
"""
Detects Page changes and updates as approprate.
"""
if pageId == FirstTimePage.NoInternet:
self.finishButton.setVisible(True)
self.finishButton.setEnabled(True)
self.nextButton.setVisible(False)
elif pageId == FirstTimePage.Defaults:
self.themeComboBox.clear()
for iter in xrange(self.themesListWidget.count()):
item = self.themesListWidget.item(iter)
if item.checkState() == QtCore.Qt.Checked:
self.themeComboBox.addItem(item.text())
elif pageId == FirstTimePage.Progress:
self._preWizard()
self._performWizard()
self._postWizard()
def _incrementProgressBar(self, status_text, increment=1):
"""
Update the wizard progress page.
``status_text``
Current status information to display.
``increment``
The value to increment the progress bar by.
"""
if status_text:
self.progressLabel.setText(status_text)
if increment > 0:
self.progressBar.setValue(self.progressBar.value() + increment)
Receiver.send_message(u'openlp_process_events')
def _preWizard(self):
"""
Prepare the UI for the process.
"""
# We start on 2 for plugins status setting plus a "finished" point.
max_progress = 2
# Loop through the songs list and increase for each selected item
for i in xrange(self.songsListWidget.count()):
if self.songsListWidget.item(i).checkState() == QtCore.Qt.Checked:
max_progress += 1
# Loop through the Bibles list and increase for each selected item
iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget)
while iterator.value():
item = iterator.value()
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
max_progress += 1
iterator += 1
# Loop through the themes list and increase for each selected item
for i in xrange(self.themesListWidget.count()):
if self.themesListWidget.item(i).checkState() == QtCore.Qt.Checked:
max_progress += 1
self.finishButton.setVisible(False)
self.progressBar.setValue(0)
self.progressBar.setMinimum(0)
self.progressBar.setMaximum(max_progress)
def _postWizard(self):
"""
Clean up the UI after the process has finished.
"""
self.progressBar.setValue(self.progressBar.maximum())
self.finishButton.setVisible(True)
self.finishButton.setEnabled(True)
self.cancelButton.setVisible(False)
self.nextButton.setVisible(False)
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
'Download complete. Click the finish button to start OpenLP.'))
Receiver.send_message(u'openlp_process_events')
def _performWizard(self):
"""
Run the tasks in the wizard.
"""
# Set plugin states
self._incrementProgressBar(translate('OpenLP.FirstTimeWizard',
'Enabling selected plugins...'))
self._setPluginStatus(self.songsCheckBox, u'songs/status')
self._setPluginStatus(self.bibleCheckBox, u'bibles/status')
self._setPluginStatus(self.presentationCheckBox, u'presentations/status')
self._setPluginStatus(self.imageCheckBox, u'images/status')
self._setPluginStatus(self.mediaCheckBox, u'media/status')
self._setPluginStatus(self.remoteCheckBox, u'remotes/status')
self._setPluginStatus(self.customCheckBox, u'custom/status')
self._setPluginStatus(self.songUsageCheckBox, u'songusage/status')
self._setPluginStatus(self.alertCheckBox, u'alerts/status')
# Build directories for downloads
songs_destination = os.path.join(unicode(gettempdir()), u'openlp')
bibles_destination = AppLocation.get_section_data_path(u'bibles')
themes_destination = AppLocation.get_section_data_path(u'themes')
# Download songs
for i in xrange(self.songsListWidget.count()):
item = self.songsListWidget.item(i)
if item.checkState() == QtCore.Qt.Checked:
filename = item.data(QtCore.Qt.UserRole).toString()
self._incrementProgressBar(self.downloading % filename)
destination = os.path.join(songs_destination, unicode(filename))
urllib.urlretrieve(u'%s%s' % (self.web, filename), destination)
# Download Bibles
bibles_iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget)
while bibles_iterator.value():
item = bibles_iterator.value()
if item.parent() and item.checkState(0) == QtCore.Qt.Checked:
bible = unicode(item.data(0, QtCore.Qt.UserRole).toString())
self._incrementProgressBar(self.downloading % bible)
urllib.urlretrieve(u'%s%s' % (self.web, bible),
os.path.join(bibles_destination, bible))
bibles_iterator += 1
# Download themes
for i in xrange(self.themesListWidget.count()):
item = self.themesListWidget.item(i)
if item.checkState() == QtCore.Qt.Checked:
theme = unicode(item.data(QtCore.Qt.UserRole).toString())
self._incrementProgressBar(self.downloading % theme)
urllib.urlretrieve(u'%s%s' % (self.web, theme),
os.path.join(themes_destination, theme))
# Set Default Display
if self.displayComboBox.currentIndex() != -1:
QtCore.QSettings().setValue(u'General/monitor',
QtCore.QVariant(self.displayComboBox.currentIndex()))
# Set Global Theme
if self.themeComboBox.currentIndex() != -1:
QtCore.QSettings().setValue(u'themes/global theme',
QtCore.QVariant(self.themeComboBox.currentText()))
QtCore.QSettings().setValue(u'general/has run wizard',
QtCore.QVariant(True))
def _setPluginStatus(self, field, tag):
status = PluginStatus.Active if field.checkState() \
== QtCore.Qt.Checked else PluginStatus.Inactive
QtCore.QSettings().setValue(tag, QtCore.QVariant(status))

View File

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
from openlp.core.lib.ui import create_accept_reject_button_box
class Ui_FirstTimeLanguageDialog(object):
def setupUi(self, languageDialog):
languageDialog.setObjectName(u'languageDialog')
languageDialog.resize(300, 50)
self.dialogLayout = QtGui.QVBoxLayout(languageDialog)
self.dialogLayout.setContentsMargins(8, 8, 8, 8)
self.dialogLayout.setSpacing(8)
self.dialogLayout.setObjectName(u'dialogLayout')
self.infoLabel = QtGui.QLabel(languageDialog)
self.infoLabel.setObjectName(u'infoLabel')
self.dialogLayout.addWidget(self.infoLabel)
self.languageLayout = QtGui.QHBoxLayout()
self.languageLayout.setObjectName(u'languageLayout')
self.languageLabel = QtGui.QLabel(languageDialog)
self.languageLabel.setObjectName(u'languageLabel')
self.languageLayout.addWidget(self.languageLabel)
self.languageComboBox = QtGui.QComboBox(languageDialog)
self.languageComboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
self.languageComboBox.setObjectName("languageComboBox")
self.languageLayout.addWidget(self.languageComboBox)
self.dialogLayout.addLayout(self.languageLayout)
self.buttonBox = create_accept_reject_button_box(languageDialog, True)
self.dialogLayout.addWidget(self.buttonBox)
self.retranslateUi(languageDialog)
self.setMaximumHeight(self.sizeHint().height())
QtCore.QMetaObject.connectSlotsByName(languageDialog)
def retranslateUi(self, languageDialog):
self.setWindowTitle(translate('OpenLP.FirstTimeLanguageForm',
'Select Translation'))
self.infoLabel.setText(translate('OpenLP.FirstTimeLanguageForm',
'Choose the translation you\'d like to use in OpenLP.'))
self.languageLabel.setText(translate('OpenLP.FirstTimeLanguageForm',
'Translation:'))

View File

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, 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 QtGui
from openlp.core.lib import translate
from openlp.core.utils import LanguageManager
from firsttimelanguagedialog import Ui_FirstTimeLanguageDialog
class FirstTimeLanguageForm(QtGui.QDialog, Ui_FirstTimeLanguageDialog):
"""
The exception dialog
"""
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
self.qmList = LanguageManager.get_qm_list()
self.languageComboBox.addItem(u'Autodetect')
for key in sorted(self.qmList.keys()):
self.languageComboBox.addItem(key)
def exec_(self):
"""
Run the Dialog with correct heading.
"""
return QtGui.QDialog.exec_(self)
def accept(self):
# It's the first row so must be Automatic
if self.languageComboBox.currentIndex() == 0:
LanguageManager.auto_language = True
LanguageManager.set_language(False, False)
else:
LanguageManager.auto_language = False
action = QtGui.QAction(None)
action.setObjectName(unicode(self.languageComboBox.currentText()))
LanguageManager.set_language(action, False)
return QtGui.QDialog.accept(self)
def reject(self):
LanguageManager.auto_language = True
LanguageManager.set_language(False, False)
return QtGui.QDialog.reject(self)

View File

@ -0,0 +1,261 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2011 Raoul Snyman #
# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, Frode Woldsund #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
from openlp.core.lib.ui import add_welcome_page
class FirstTimePage(object):
Welcome = 0
Plugins = 1
NoInternet = 2
Songs = 3
Bibles = 4
Themes = 5
Defaults = 6
Progress = 7
class Ui_FirstTimeWizard(object):
def setupUi(self, FirstTimeWizard):
FirstTimeWizard.setObjectName(u'FirstTimeWizard')
FirstTimeWizard.resize(550, 386)
FirstTimeWizard.setModal(True)
FirstTimeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
FirstTimeWizard.setOptions(QtGui.QWizard.IndependentPages|
QtGui.QWizard.NoBackButtonOnStartPage |
QtGui.QWizard.NoBackButtonOnLastPage)
self.finishButton = self.button(QtGui.QWizard.FinishButton)
self.cancelButton = self.button(QtGui.QWizard.CancelButton)
self.nextButton = self.button(QtGui.QWizard.NextButton)
self.backButton = self.button(QtGui.QWizard.BackButton)
add_welcome_page(FirstTimeWizard, u':/wizards/wizard_firsttime.bmp')
# The plugins page
self.pluginPage = QtGui.QWizardPage()
self.pluginPage.setObjectName(u'pluginPage')
self.pluginLayout = QtGui.QVBoxLayout(self.pluginPage)
self.pluginLayout.setContentsMargins(40, 15, 40, 0)
self.pluginLayout.setObjectName(u'pluginLayout')
self.songsCheckBox = QtGui.QCheckBox(self.pluginPage)
self.songsCheckBox.setChecked(True)
self.songsCheckBox.setObjectName(u'songsCheckBox')
self.pluginLayout.addWidget(self.songsCheckBox)
self.customCheckBox = QtGui.QCheckBox(self.pluginPage)
self.customCheckBox.setChecked(True)
self.customCheckBox.setObjectName(u'customCheckBox')
self.pluginLayout.addWidget(self.customCheckBox)
self.bibleCheckBox = QtGui.QCheckBox(self.pluginPage)
self.bibleCheckBox.setChecked(True)
self.bibleCheckBox.setObjectName(u'bibleCheckBox')
self.pluginLayout.addWidget(self.bibleCheckBox)
self.imageCheckBox = QtGui.QCheckBox(self.pluginPage)
self.imageCheckBox.setChecked(True)
self.imageCheckBox.setObjectName(u'imageCheckBox')
self.pluginLayout.addWidget(self.imageCheckBox)
self.presentationCheckBox = QtGui.QCheckBox(self.pluginPage)
self.presentationCheckBox.setChecked(True)
self.presentationCheckBox.setObjectName(u'presentationCheckBox')
self.pluginLayout.addWidget(self.presentationCheckBox)
self.mediaCheckBox = QtGui.QCheckBox(self.pluginPage)
self.mediaCheckBox.setChecked(True)
self.mediaCheckBox.setObjectName(u'mediaCheckBox')
self.pluginLayout.addWidget(self.mediaCheckBox)
self.remoteCheckBox = QtGui.QCheckBox(self.pluginPage)
self.remoteCheckBox.setObjectName(u'remoteCheckBox')
self.pluginLayout.addWidget(self.remoteCheckBox)
self.songUsageCheckBox = QtGui.QCheckBox(self.pluginPage)
self.songUsageCheckBox.setChecked(True)
self.songUsageCheckBox.setObjectName(u'songUsageCheckBox')
self.pluginLayout.addWidget(self.songUsageCheckBox)
self.alertCheckBox = QtGui.QCheckBox(self.pluginPage)
self.alertCheckBox.setChecked(True)
self.alertCheckBox.setObjectName(u'alertCheckBox')
self.pluginLayout.addWidget(self.alertCheckBox)
FirstTimeWizard.setPage(FirstTimePage.Plugins, self.pluginPage)
# The "you don't have an internet connection" page.
self.noInternetPage = QtGui.QWizardPage()
self.noInternetPage.setObjectName(u'noInternetPage')
self.noInternetLayout = QtGui.QVBoxLayout(self.noInternetPage)
self.noInternetLayout.setContentsMargins(50, 30, 50, 40)
self.noInternetLayout.setObjectName(u'noInternetLayout')
self.noInternetLabel = QtGui.QLabel(self.noInternetPage)
self.noInternetLabel.setWordWrap(True)
self.noInternetLabel.setObjectName(u'noInternetLabel')
self.noInternetLayout.addWidget(self.noInternetLabel)
FirstTimeWizard.setPage(FirstTimePage.NoInternet, self.noInternetPage)
# The song samples page
self.songsPage = QtGui.QWizardPage()
self.songsPage.setObjectName(u'songsPage')
self.songsLayout = QtGui.QVBoxLayout(self.songsPage)
self.songsLayout.setContentsMargins(50, 20, 50, 20)
self.songsLayout.setObjectName(u'songsLayout')
self.songsListWidget = QtGui.QListWidget(self.songsPage)
self.songsListWidget.setAlternatingRowColors(True)
self.songsListWidget.setObjectName(u'songsListWidget')
self.songsLayout.addWidget(self.songsListWidget)
FirstTimeWizard.setPage(FirstTimePage.Songs, self.songsPage)
# The Bible samples page
self.biblesPage = QtGui.QWizardPage()
self.biblesPage.setObjectName(u'biblesPage')
self.biblesLayout = QtGui.QVBoxLayout(self.biblesPage)
self.biblesLayout.setContentsMargins(50, 20, 50, 20)
self.biblesLayout.setObjectName(u'biblesLayout')
self.biblesTreeWidget = QtGui.QTreeWidget(self.biblesPage)
self.biblesTreeWidget.setAlternatingRowColors(True)
self.biblesTreeWidget.header().setVisible(False)
self.biblesTreeWidget.setObjectName(u'biblesTreeWidget')
self.biblesLayout.addWidget(self.biblesTreeWidget)
FirstTimeWizard.setPage(FirstTimePage.Bibles, self.biblesPage)
# The theme samples page
self.themesPage = QtGui.QWizardPage()
self.themesPage.setObjectName(u'themesPage')
self.themesLayout = QtGui.QVBoxLayout(self.themesPage)
self.themesLayout.setContentsMargins(20, 50, 20, 60)
self.themesLayout.setObjectName(u'themesLayout')
self.themesListWidget = QtGui.QListWidget(self.themesPage)
self.themesListWidget.setViewMode(QtGui.QListView.IconMode)
self.themesListWidget.setMovement(QtGui.QListView.Static)
self.themesListWidget.setFlow(QtGui.QListView.LeftToRight)
self.themesListWidget.setSpacing(4)
self.themesListWidget.setUniformItemSizes(True)
self.themesListWidget.setIconSize(QtCore.QSize(133, 100))
self.themesListWidget.setWrapping(False)
self.themesListWidget.setObjectName(u'themesListWidget')
self.themesLayout.addWidget(self.themesListWidget)
FirstTimeWizard.setPage(FirstTimePage.Themes, self.themesPage)
# the default settings page
self.defaultsPage = QtGui.QWizardPage()
self.defaultsPage.setObjectName(u'defaultsPage')
self.defaultsLayout = QtGui.QFormLayout(self.defaultsPage)
self.defaultsLayout.setContentsMargins(50, 20, 50, 20)
self.defaultsLayout.setObjectName(u'defaultsLayout')
self.displayLabel = QtGui.QLabel(self.defaultsPage)
self.displayLabel.setObjectName(u'displayLabel')
self.displayComboBox = QtGui.QComboBox(self.defaultsPage)
self.displayComboBox.setEditable(False)
self.displayComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.displayComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToContents)
self.displayComboBox.setObjectName(u'displayComboBox')
self.defaultsLayout.addRow(self.displayLabel, self.displayComboBox)
self.themeLabel = QtGui.QLabel(self.defaultsPage)
self.themeLabel.setObjectName(u'themeLabel')
self.themeComboBox = QtGui.QComboBox(self.defaultsPage)
self.themeComboBox.setEditable(False)
self.themeComboBox.setInsertPolicy(QtGui.QComboBox.NoInsert)
self.themeComboBox.setSizeAdjustPolicy(
QtGui.QComboBox.AdjustToContents)
self.themeComboBox.setObjectName(u'themeComboBox')
self.defaultsLayout.addRow(self.themeLabel, self.themeComboBox)
FirstTimeWizard.setPage(FirstTimePage.Defaults, self.defaultsPage)
# Progress page
self.progressPage = QtGui.QWizardPage()
self.progressPage.setObjectName(u'progressPage')
self.progressLayout = QtGui.QVBoxLayout(self.progressPage)
self.progressLayout.setMargin(48)
self.progressLayout.setObjectName(u'progressLayout')
self.progressLabel = QtGui.QLabel(self.progressPage)
self.progressLabel.setObjectName(u'progressLabel')
self.progressLayout.addWidget(self.progressLabel)
self.progressBar = QtGui.QProgressBar(self.progressPage)
self.progressBar.setObjectName(u'progressBar')
self.progressLayout.addWidget(self.progressBar)
FirstTimeWizard.setPage(FirstTimePage.Progress, self.progressPage)
self.retranslateUi(FirstTimeWizard)
QtCore.QMetaObject.connectSlotsByName(FirstTimeWizard)
def retranslateUi(self, FirstTimeWizard):
FirstTimeWizard.setWindowTitle(translate(
'OpenLP.FirstTimeWizard', 'First Time Wizard'))
self.titleLabel.setText(
u'<span style="font-size:14pt; font-weight:600;">%s</span>' % \
translate('OpenLP.FirstTimeWizard',
'Welcome to the First Time Wizard'))
self.informationLabel.setText(translate('OpenLP.FirstTimeWizard',
'This wizard will help you to configure OpenLP for initial use.'
' Click the next button below to start the process of selection '
'your initial options. '))
self.pluginPage.setTitle(translate('OpenLP.FirstTimeWizard',
'Activate required Plugins'))
self.pluginPage.setSubTitle(translate('OpenLP.FirstTimeWizard',
'Select the Plugins you wish to use. '))
self.songsCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Songs'))
self.customCheckBox.setText(translate('OpenLP.FirstTimeWizard',
'Custom Text'))
self.bibleCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Bible'))
self.imageCheckBox.setText(translate('OpenLP.FirstTimeWizard',
'Images'))
self.presentationCheckBox.setText(translate('OpenLP.FirstTimeWizard',
'Presentations'))
self.mediaCheckBox.setText(translate('OpenLP.FirstTimeWizard',
'Media (Audio and Video)'))
self.remoteCheckBox.setText(translate('OpenLP.FirstTimeWizard',
'Allow remote access'))
self.songUsageCheckBox.setText(translate('OpenLP.FirstTimeWizard',
'Monitor Song Usage'))
self.alertCheckBox.setText(translate('OpenLP.FirstTimeWizard',
'Allow Alerts'))
self.noInternetPage.setTitle(translate('OpenLP.FirstTimeWizard',
'No Internet Connection'))
self.noInternetPage.setSubTitle(translate(
'OpenLP.FirstTimeWizard',
'Unable to detect an Internet connection.'))
self.noInternetLabel.setText(translate('OpenLP.FirstTimeWizard',
'No Internet connection was found. The First Time Wizard needs an '
'Internet connection in order to be able to download sample '
'songs, Bibles and themes.\n\nTo re-run the First Time Wizard and '
'import this sample data at a later stage, press the cancel '
'button now, check your Internet connection, and restart OpenLP.'
'\n\nTo cancel the First Time Wizard completely, press the finish '
'button now.'))
self.songsPage.setTitle(translate('OpenLP.FirstTimeWizard',
'Sample Songs'))
self.songsPage.setSubTitle(translate('OpenLP.FirstTimeWizard',
'Select and download public domain songs.'))
self.biblesPage.setTitle(translate('OpenLP.FirstTimeWizard',
'Sample Bibles'))
self.biblesPage.setSubTitle(translate('OpenLP.FirstTimeWizard',
'Select and download free Bibles.'))
self.themesPage.setTitle(translate('OpenLP.FirstTimeWizard',
'Sample Themes'))
self.themesPage.setSubTitle(translate('OpenLP.FirstTimeWizard',
'Select and download sample themes.'))
self.defaultsPage.setTitle(translate('OpenLP.FirstTimeWizard',
'Default Settings'))
self.defaultsPage.setSubTitle(translate('OpenLP.FirstTimeWizard',
'Set up default settings to be used by OpenLP.'))
self.progressPage.setTitle(translate('OpenLP.FirstTimeWizard',
'Setting Up And Importing'))
self.progressPage.setSubTitle(translate('OpenLP.FirstTimeWizard',
'Please wait while OpenLP is set up and your data is imported.'))
self.displayLabel.setText(translate('OpenLP.FirstTimeWizard',
'Default output display:'))
self.themeLabel.setText(translate('OpenLP.FirstTimeWizard',
'Select default theme:'))
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
'Starting configuration process...'))

View File

@ -234,6 +234,9 @@ class GeneralTab(SettingsTab):
QtCore.QObject.connect(self.customXValueEdit,
QtCore.SIGNAL(u'textEdited(const QString&)'),
self.onDisplayPositionChanged)
# Reload the tab, as the screen resolution/count may have changed.
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_screen_changed'), self.load)
def retranslateUi(self):
"""
@ -300,13 +303,9 @@ class GeneralTab(SettingsTab):
"""
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
for screen in self.screens.screen_list:
screen_name = u'%s %d' % (translate('OpenLP.GeneralTab', 'Screen'),
screen[u'number'] + 1)
if screen[u'primary']:
screen_name = u'%s (%s)' % (screen_name,
translate('OpenLP.GeneralTab', 'primary'))
self.monitorComboBox.addItem(screen_name)
self.monitorComboBox.clear()
for screen in self.screens.get_screen_list():
self.monitorComboBox.addItem(screen)
self.numberEdit.setText(unicode(settings.value(
u'ccli number', QtCore.QVariant(u'')).toString()))
self.usernameEdit.setText(unicode(settings.value(

View File

@ -67,6 +67,7 @@ class MainDisplay(DisplayWidget):
self.isLive = live
self.alertTab = None
self.hideMode = None
self.videoHide = False
self.override = {}
mainIcon = build_icon(u':/icon/openlp-logo-16x16.png')
self.setWindowIcon(mainIcon)
@ -90,8 +91,8 @@ class MainDisplay(DisplayWidget):
"""
Set up and build the output screen
"""
log.debug(u'Setup live = %s for monitor %s ' % (self.isLive,
self.screens.monitor_number))
log.debug(u'Start setup for monitor %s (live = %s)' %
(self.screens.monitor_number, self.isLive))
self.usePhonon = QtCore.QSettings().value(
u'media/use phonon', QtCore.QVariant(True)).toBool()
self.phononActive = False
@ -102,6 +103,7 @@ class MainDisplay(DisplayWidget):
self.videoWidget.setVisible(False)
self.videoWidget.setGeometry(QtCore.QRect(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height()))
log.debug(u'Setup Phonon for monitor %s' % self.screens.monitor_number)
self.mediaObject = Phonon.MediaObject(self)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.videoWidget)
@ -109,6 +111,13 @@ class MainDisplay(DisplayWidget):
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
self.videoStart)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'),
self.videoFinished)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'tick(qint64)'),
self.videoTick)
log.debug(u'Setup webView for monitor %s' % self.screens.monitor_number)
self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height())
@ -165,6 +174,8 @@ class MainDisplay(DisplayWidget):
self.primary = False
else:
self.primary = True
log.debug(
u'Finished setup for monitor %s' % self.screens.monitor_number)
def text(self, slide):
"""
@ -233,9 +244,6 @@ class MainDisplay(DisplayWidget):
image = self.imageManager.get_image_bytes(name)
self.resetVideo()
self.displayImage(image)
# show screen
if self.isLive:
self.setVisible(True)
return self.preview()
def displayImage(self, image):
@ -248,7 +256,8 @@ class MainDisplay(DisplayWidget):
js = u'show_image("");'
self.frame.evaluateJavaScript(js)
# Update the preview frame.
Receiver.send_message(u'maindisplay_active')
if self.isLive:
Receiver.send_message(u'maindisplay_active')
def resetImage(self):
"""
@ -260,9 +269,11 @@ class MainDisplay(DisplayWidget):
self.displayImage(self.serviceItem.bg_image_bytes)
else:
self.displayImage(None)
# clear the cache
self.override = {}
# Update the preview frame.
Receiver.send_message(u'maindisplay_active')
if self.isLive:
Receiver.send_message(u'maindisplay_active')
def resetVideo(self):
"""
@ -279,7 +290,8 @@ class MainDisplay(DisplayWidget):
self.frame.evaluateJavaScript(u'show_video("close");')
self.override = {}
# Update the preview frame.
Receiver.send_message(u'maindisplay_active')
if self.isLive:
Receiver.send_message(u'maindisplay_active')
def videoPlay(self):
"""
@ -319,7 +331,7 @@ class MainDisplay(DisplayWidget):
Changes the volume of a running video
"""
log.debug(u'videoVolume %d' % volume)
vol = float(volume)/float(10)
vol = float(volume) / float(10)
if self.phononActive:
self.audio.setVolume(vol)
else:
@ -335,7 +347,7 @@ class MainDisplay(DisplayWidget):
# We are running a background theme
self.override[u'theme'] = u''
self.override[u'video'] = True
vol = float(volume)/float(10)
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))
@ -345,12 +357,17 @@ class MainDisplay(DisplayWidget):
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.mediaObject.setCurrentSource(Phonon.MediaSource(videoPath))
# Need the timer to trigger set the trigger to 200ms
# Value taken from web documentation.
if self.serviceItem.start_time != 0:
self.mediaObject.setTickInterval(200)
self.mediaObject.play()
self.webView.setVisible(False)
self.videoWidget.setVisible(True)
self.audio.setVolume(vol)
# Update the preview frame.
Receiver.send_message(u'maindisplay_active')
if self.isLive:
Receiver.send_message(u'maindisplay_active')
return self.preview()
def videoStart(self, newState, oldState):
@ -358,8 +375,26 @@ class MainDisplay(DisplayWidget):
Start the video at a predetermined point.
"""
if newState == Phonon.PlayingState:
# set start time in milliseconds
self.mediaObject.seek(self.serviceItem.start_time * 1000)
def videoFinished(self):
"""
Blank the Video when it has finished so the final frame is not left
hanging
"""
self.videoStop()
self.hideDisplay(HideMode.Blank)
self.phononActive = False
self.videoHide = True
def videoTick(self, tick):
"""
Triggered on video tick every 200 milli seconds
Will be used to manage stop time later
"""
pass
def isWebLoaded(self):
"""
Called by webView event to show display is fully loaded
@ -388,9 +423,10 @@ class MainDisplay(DisplayWidget):
Receiver.send_message(u'openlp_process_events')
# if was hidden keep it hidden
if self.isLive:
self.setVisible(True)
if self.hideMode:
self.hideDisplay(self.hideMode)
else:
self.setVisible(True)
preview = QtGui.QImage(self.screen[u'size'].width(),
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
@ -416,10 +452,12 @@ class MainDisplay(DisplayWidget):
if u'video' in self.override:
Receiver.send_message(u'video_background_replaced')
self.override = {}
# We have a different theme.
elif self.override[u'theme'] != serviceItem.themedata.theme_name:
Receiver.send_message(u'live_theme_changed')
self.override = {}
else:
# replace the background
background = self.imageManager. \
get_image_bytes(self.override[u'image'])
if self.serviceItem.themedata.background_filename:
@ -435,6 +473,10 @@ class MainDisplay(DisplayWidget):
# if was hidden keep it hidden
if self.hideMode and self.isLive:
self.hideDisplay(self.hideMode)
# display hidden for video end we have a new item so must be shown
if self.videoHide and self.isLive:
self.videoHide = False
self.showDisplay()
self.__hideMouse()
def footer(self, text):
@ -483,7 +525,8 @@ class MainDisplay(DisplayWidget):
self.videoPlay()
self.hideMode = None
# Trigger actions when display is active again
Receiver.send_message(u'maindisplay_active')
if self.isLive:
Receiver.send_message(u'maindisplay_active')
def __hideMouse(self):
# Hide mouse cursor when moved over display if enabled in settings
@ -509,9 +552,6 @@ class AudioPlayer(QtCore.QObject):
``parent``
The parent widget.
``screens``
The list of screens.
"""
log.debug(u'AudioPlayer Initialisation started')
QtCore.QObject.__init__(self, parent)

View File

@ -25,6 +25,8 @@
###############################################################################
import logging
import os
from tempfile import gettempdir
from PyQt4 import QtCore, QtGui
@ -206,7 +208,7 @@ class Ui_MainWindow(object):
mainWindow.actionList.add_action(self.ModeDefaultItem, u'View Mode')
self.ModeSetupItem = checkable_action(mainWindow, u'ModeLiveItem')
mainWindow.actionList.add_action(self.ModeSetupItem, u'View Mode')
self.ModeLiveItem = checkable_action(mainWindow, u'ModeLiveItem')
self.ModeLiveItem = checkable_action(mainWindow, u'ModeLiveItem', True)
mainWindow.actionList.add_action(self.ModeLiveItem, u'View Mode')
self.ModeGroup = QtGui.QActionGroup(mainWindow)
self.ModeGroup.addAction(self.ModeDefaultItem)
@ -215,6 +217,8 @@ class Ui_MainWindow(object):
self.ModeDefaultItem.setChecked(True)
self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem',
u':/tools/tools_add.png')
# Hide the entry, as it does not have any functionality yet.
self.ToolsAddToolItem.setVisible(False)
mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools')
self.ToolsOpenDataFolder = icon_action(mainWindow,
u'ToolsOpenDataFolder', u':/general/general_open.png')
@ -225,19 +229,17 @@ class Ui_MainWindow(object):
u'Settings')
# i18n Language Items
self.AutoLanguageItem = checkable_action(mainWindow,
u'AutoLanguageItem')
u'AutoLanguageItem', LanguageManager.auto_language)
mainWindow.actionList.add_action(self.AutoLanguageItem, u'Settings')
self.LanguageGroup = QtGui.QActionGroup(mainWindow)
self.LanguageGroup.setExclusive(True)
self.LanguageGroup.setObjectName(u'LanguageGroup')
self.AutoLanguageItem.setChecked(LanguageManager.auto_language)
self.LanguageGroup.setDisabled(LanguageManager.auto_language)
add_actions(self.LanguageGroup, [self.AutoLanguageItem])
qmList = LanguageManager.get_qm_list()
savedLanguage = LanguageManager.get_language()
for key in sorted(qmList.keys()):
languageItem = checkable_action(mainWindow, key)
if qmList[key] == savedLanguage:
languageItem.setChecked(True)
languageItem = checkable_action(
mainWindow, key, qmList[key] == savedLanguage)
add_actions(self.LanguageGroup, [languageItem])
self.SettingsShortcutsItem = icon_action(mainWindow,
u'SettingsShortcutsItem',
@ -425,14 +427,14 @@ class Ui_MainWindow(object):
translate('OpenLP.MainWindow', '&Online Help'))
self.helpWebSiteItem.setText(
translate('OpenLP.MainWindow', '&Web Site'))
self.AutoLanguageItem.setText(
translate('OpenLP.MainWindow', '&Auto Detect'))
self.AutoLanguageItem.setStatusTip(translate('OpenLP.MainWindow',
'Use the system language, if available.'))
for item in self.LanguageGroup.actions():
item.setText(item.objectName())
item.setStatusTip(unicode(translate('OpenLP.MainWindow',
'Set the interface language to %s')) % item.objectName())
self.AutoLanguageItem.setText(
translate('OpenLP.MainWindow', '&Autodetect'))
self.AutoLanguageItem.setStatusTip(translate('OpenLP.MainWindow',
'Use the system language, if available.'))
self.ToolsAddToolItem.setText(
translate('OpenLP.MainWindow', 'Add &Tool...'))
self.ToolsAddToolItem.setStatusTip(translate('OpenLP.MainWindow',
@ -468,7 +470,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
"""
QtGui.QMainWindow.__init__(self)
self.screens = screens
self.actionList = ActionList()
self.applicationVersion = applicationVersion
self.clipboard = clipboard
# Set up settings sections for the main application
@ -478,6 +479,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.serviceSettingsSection = u'servicemanager'
self.songsSettingsSection = u'songs'
self.serviceNotSaved = False
self.actionList = ActionList()
self.settingsmanager = SettingsManager(screens)
self.aboutForm = AboutForm(self, applicationVersion)
self.settingsForm = SettingsForm(self.screens, self, self)
@ -550,8 +552,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.printServiceOrder)
# i18n set signals for languages
QtCore.QObject.connect(self.AutoLanguageItem,
QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage)
self.LanguageGroup.triggered.connect(LanguageManager.set_language)
QtCore.QObject.connect(self.ModeDefaultItem,
QtCore.SIGNAL(u'triggered()'), self.onModeDefaultItemClicked)
@ -650,8 +650,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Show the main form, as well as the display form
"""
QtGui.QWidget.show(self)
self.liveController.display.setup()
self.previewController.display.setup()
if self.liveController.display.isVisible():
self.liveController.display.setFocus()
self.activateWindow()
@ -670,6 +668,20 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.setViewMode(False, True, False, False, True)
self.ModeLiveItem.setChecked(True)
def firstTime(self):
# Import themes if first time
Receiver.send_message(u'openlp_process_events')
self.themeManagerContents.firstTime()
for plugin in self.pluginManager.plugins:
if hasattr(plugin, u'firstTime'):
Receiver.send_message(u'openlp_process_events')
plugin.firstTime()
Receiver.send_message(u'openlp_process_events')
temp_dir = os.path.join(unicode(gettempdir()), u'openlp')
for filename in os.listdir(temp_dir):
os.remove(os.path.join(temp_dir, filename))
os.removedirs(temp_dir)
def blankCheck(self):
"""
Check and display message if screen blank on setup.

View File

@ -25,11 +25,15 @@
###############################################################################
"""
The :mod:`screen` module provides management functionality for a machines'
displays
displays.
"""
import logging
import copy
from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate
log = logging.getLogger(__name__)
class ScreenList(object):
@ -38,7 +42,14 @@ class ScreenList(object):
"""
log.info(u'Screen loaded')
def __init__(self):
def __init__(self, desktop):
"""
Initialise the screen list.
``desktop``
A ``QDesktopWidget`` object.
"""
self.desktop = desktop
self.preview = None
self.current = None
self.override = None
@ -48,19 +59,120 @@ class ScreenList(object):
self.current_display = 0
# save config display number
self.monitor_number = 0
self.screen_count_changed()
QtCore.QObject.connect(desktop,
QtCore.SIGNAL(u'resized(int)'), self.screen_resolution_changed)
QtCore.QObject.connect(desktop,
QtCore.SIGNAL(u'screenCountChanged(int)'),
self.screen_count_changed)
def screen_resolution_changed(self, number):
"""
Called when the resolution of a screen has changed.
``number``
The number of the screen, which size has changed.
"""
log.info(u'screenResolutionChanged %d' % number)
for screen in self.screen_list:
if number == screen[u'number']:
newScreen = {
u'number': number,
u'size': self.desktop.screenGeometry(number),
u'primary': self.desktop.primaryScreen() == number
}
self.remove_screen(number)
self.add_screen(newScreen)
# The screen's default size is used, that is why we have to
# update the override screen.
if screen == self.override:
self.override = copy.deepcopy(newScreen)
self.set_override_display()
Receiver.send_message(u'config_screen_changed')
break
def screen_count_changed(self, changed_screen=-1):
"""
Called when a screen has been added or removed.
``changed_screen``
The screen's number which has been (un)plugged.
"""
# Remove unplugged screens.
for screen in copy.deepcopy(self.screen_list):
if screen[u'number'] == self.desktop.numScreens():
self.remove_screen(screen[u'number'])
# Add new screens.
for number in xrange(0, self.desktop.numScreens()):
if not self.screen_exists(number):
self.add_screen({
u'number': number,
u'size': self.desktop.screenGeometry(number),
u'primary': (self.desktop.primaryScreen() == number)
})
# We do not want to send this message, when the method is called the
# first time.
if changed_screen != -1:
# Reload setting tabs to apply possible changes.
Receiver.send_message(u'config_screen_changed')
def get_screen_list(self):
"""
Returns a list with the screens. This should only be used to display
available screens to the user::
[u'Screen 1 (primary)', u'Screen 2']
"""
screen_list = []
for screen in self.screen_list:
screen_name = u'%s %d' % (translate('OpenLP.ScreenList', 'Screen'),
screen[u'number'] + 1)
if screen[u'primary']:
screen_name = u'%s (%s)' % (screen_name,
translate('OpenLP.ScreenList', 'primary'))
screen_list.append(screen_name)
return screen_list
def add_screen(self, screen):
"""
Add a screen to the list of known screens
Add a screen to the list of known screens.
``screen``
A dict with the screen properties::
{
u'primary': True,
u'number': 0,
u'size': PyQt4.QtCore.QRect(0, 0, 1024, 768)
}
"""
log.info(u'Screen %d found with resolution %s',
screen[u'number'], screen[u'size'])
if screen[u'primary']:
self.current = screen
self.screen_list.append(screen)
self.display_count += 1
def remove_screen(self, number):
"""
Remove a screen from the list of known screens.
``number``
The screen number (int).
"""
log.info(u'remove_screen %d' % number)
for screen in self.screen_list:
if screen[u'number'] == number:
self.screen_list.remove(screen)
self.display_count -= 1
break
def screen_exists(self, number):
"""
Confirms a screen is known
Confirms a screen is known.
``number``
The screen number (int).
"""
for screen in self.screen_list:
if screen[u'number'] == number:
@ -69,7 +181,10 @@ class ScreenList(object):
def set_current_display(self, number):
"""
Set up the current screen dimensions
Set up the current screen dimensions.
``number``
The screen number (int).
"""
log.debug(u'set_current_display %s', number)
if number + 1 > self.display_count:
@ -86,8 +201,8 @@ class ScreenList(object):
def set_override_display(self):
"""
replace the current size with the override values
user wants to have their own screen attributes
Replace the current size with the override values, as the user wants to
have their own screen attributes.
"""
log.debug(u'set_override_display')
self.current = copy.deepcopy(self.override)
@ -95,8 +210,8 @@ class ScreenList(object):
def reset_current_display(self):
"""
replace the current values with the correct values
user wants to use the correct screen attributes
Replace the current values with the correct values, as the user wants to
use the correct screen attributes.
"""
log.debug(u'reset_current_display')
self.set_current_display(self.current_display)

View File

@ -415,47 +415,75 @@ class ServiceManager(QtGui.QWidget):
"""
if not self.fileName():
return self.saveFileAs()
else:
fileName = self.fileName()
log.debug(u'ServiceManager.saveFile - %s' % fileName)
SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
split_filename(fileName)[0])
service = []
serviceFileName = fileName.replace(u'.osz', u'.osd')
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'].get_service_repr()})
if item[u'service_item'].uses_file():
for frame in item[u'service_item'].get_frames():
if item[u'service_item'].is_image():
path_from = frame[u'path']
else:
path_from = unicode(os.path.join(
frame[u'path'],
frame[u'title']))
# 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(serviceFileName, u'wb')
cPickle.dump(service, file)
file.close()
zip.write(serviceFileName.encode(u'utf-8'))
except IOError:
log.exception(u'Failed to save service to disk')
finally:
if file:
file.close()
if zip:
zip.close()
delete_file(serviceFileName)
self.mainwindow.addRecentFile(fileName)
self.setModified(False)
path_file_name = unicode(self.fileName())
(path, file_name) = os.path.split(path_file_name)
(basename, extension) = os.path.splitext(file_name)
service_file_name = basename + '.osd'
log.debug(u'ServiceManager.saveFile - %s' % path_file_name)
SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
path)
service = []
write_list = []
total_size = 0
for item in self.serviceItems:
service.append({u'serviceitem':
item[u'service_item'].get_service_repr()})
if not item[u'service_item'].uses_file():
continue
for frame in item[u'service_item'].get_frames():
if item[u'service_item'].is_image():
path_from = frame[u'path']
else:
path_from = os.path.join(frame[u'path'], frame[u'title'])
# Only write a file once
if path_from in write_list:
continue
file_size = os.path.getsize(path_from)
size_limit = 52428800 # 50MiB
#if file_size > size_limit:
# # File exeeds size_limit bytes, ask user
# message = unicode(translate('OpenLP.ServiceManager',
# 'Do you want to include \n%.1f MB file "%s"\n'
# 'into the service file?\nThis may take some time.\n\n'
# 'Please note that you need to\ntake care of that file'
# ' yourself,\nif you leave it out.')) % \
# (file_size/1048576, os.path.split(path_from)[1])
# ans = QtGui.QMessageBox.question(self.mainwindow,
# translate('OpenLP.ServiceManager', 'Including Large '
# 'File'), message, QtGui.QMessageBox.StandardButtons(
# QtGui.QMessageBox.Ok|QtGui.QMessageBox.Cancel),
# QtGui.QMessageBox.Ok)
# if ans == QtGui.QMessageBox.Cancel:
# continue
write_list.append(path_from)
total_size += file_size
log.debug(u'ServiceManager.saveFile - ZIP contents size is %i bytes' %
total_size)
service_content = cPickle.dumps(service)
# Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be
# extracted using unzip in UNIX.
allow_zip_64 = (total_size > 2147483648 + len(service_content))
log.debug(u'ServiceManager.saveFile - allowZip64 is %s' %
allow_zip_64)
zip = None
try:
zip = zipfile.ZipFile(path_file_name, 'w', zipfile.ZIP_STORED,
allow_zip_64)
# First we add service contents.
# We save ALL filenames into ZIP using UTF-8.
zip.writestr(service_file_name.encode(u'utf-8'),
service_content)
# Finally add all the listed media files.
for path_from in write_list:
zip.write(path_from, path_from.encode(u'utf-8'))
except IOError:
log.exception(u'Failed to save service to disk')
return False
finally:
if zip:
zip.close()
self.mainwindow.addRecentFile(path_file_name)
self.setModified(False)
return True
def saveFileAs(self):
@ -943,6 +971,7 @@ class ServiceManager(QtGui.QWidget):
for item in self.serviceItems:
if item[u'service_item']._uuid == uuid:
item[u'service_item'].edit_id = editId
self.setModified(True)
def replaceServiceItem(self, newItem):
"""
@ -1123,13 +1152,14 @@ class ServiceManager(QtGui.QWidget):
self.serviceItems.remove(serviceItem)
self.serviceItems.insert(endpos, serviceItem)
self.repaintServiceList(endpos, child)
self.setModified(True)
else:
# we are not over anything so drop
replace = False
if item is None:
self.dropPosition = len(self.serviceItems)
else:
# we are over somthing so lets investigate
# we are over something so lets investigate
pos = self._getParentItemData(item) - 1
serviceItem = self.serviceItems[pos]
if (plugin == serviceItem[u'service_item'].name and

View File

@ -32,7 +32,7 @@ from PyQt4.phonon import Phonon
from openlp.core.lib import OpenLPToolbar, Receiver, resize_image, \
ItemCapabilities, translate
from openlp.core.lib.ui import UiStrings, shortcut_action
from openlp.core.lib.ui import icon_action, UiStrings, shortcut_action
from openlp.core.ui import HideMode, MainDisplay
log = logging.getLogger(__name__)
@ -114,8 +114,7 @@ class SlideController(QtGui.QWidget):
self.previewListWidget = SlideList(self)
self.previewListWidget.setColumnCount(1)
self.previewListWidget.horizontalHeader().setVisible(False)
self.previewListWidget.setColumnWidth(
0, self.controller.width())
self.previewListWidget.setColumnWidth(0, self.controller.width())
self.previewListWidget.isLive = self.isLive
self.previewListWidget.setObjectName(u'PreviewListWidget')
self.previewListWidget.setSelectionBehavior(1)
@ -146,36 +145,30 @@ class SlideController(QtGui.QWidget):
u':/slides/slide_next.png',
translate('OpenLP.SlideController', 'Move to next'),
self.onSlideSelectedNext)
self.toolbar.addToolbarSeparator(u'Close Separator')
if self.isLive:
self.toolbar.addToolbarSeparator(u'Close Separator')
self.hideMenu = QtGui.QToolButton(self.toolbar)
self.hideMenu.setText(translate('OpenLP.SlideController', 'Hide'))
self.hideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.toolbar.addToolbarWidget(u'Hide Menu', self.hideMenu)
self.hideMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Hide'), self.toolbar))
self.blankScreen = QtGui.QAction(QtGui.QIcon(
u':/slides/slide_blank.png'),
translate('OpenLP.SlideController',
'Blank Screen'), self.hideMenu)
self.blankScreen.setCheckable(True)
self.themeScreen = QtGui.QAction(QtGui.QIcon(
u':/slides/slide_theme.png'),
translate('OpenLP.SlideController',
'Blank to Theme'), self.hideMenu)
self.themeScreen.setCheckable(True)
self.blankScreen = icon_action(self.hideMenu, u'Blank Screen',
u':/slides/slide_blank.png', False)
self.blankScreen.setText(
translate('OpenLP.SlideController', 'Blank Screen'))
self.themeScreen = icon_action(self.hideMenu, u'Blank Theme',
u':/slides/slide_theme.png', False)
self.themeScreen.setText(
translate('OpenLP.SlideController', 'Blank to Theme'))
self.desktopScreen = icon_action(self.hideMenu, u'Desktop Screen',
u':/slides/slide_desktop.png', False)
self.desktopScreen.setText(
translate('OpenLP.SlideController', 'Show Desktop'))
self.hideMenu.setDefaultAction(self.blankScreen)
self.hideMenu.menu().addAction(self.blankScreen)
self.hideMenu.menu().addAction(self.themeScreen)
if self.screens.display_count > 1:
self.desktopScreen = QtGui.QAction(QtGui.QIcon(
u':/slides/slide_desktop.png'),
translate('OpenLP.SlideController',
'Show Desktop'), self.hideMenu)
self.hideMenu.menu().addAction(self.desktopScreen)
self.desktopScreen.setCheckable(True)
QtCore.QObject.connect(self.desktopScreen,
QtCore.SIGNAL(u'triggered(bool)'), self.onHideDisplay)
self.hideMenu.menu().addAction(self.desktopScreen)
self.toolbar.addToolbarSeparator(u'Loop Separator')
self.toolbar.addToolbarButton(
# Does not need translating - control string.
@ -195,7 +188,6 @@ class SlideController(QtGui.QWidget):
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
'Delay between slides in seconds'))
else:
self.toolbar.addToolbarSeparator(u'Close Separator')
self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Go Live', u':/general/general_live.png',
@ -226,8 +218,7 @@ class SlideController(QtGui.QWidget):
if self.isLive:
# Build the Song Toolbar
self.songMenu = QtGui.QToolButton(self.toolbar)
self.songMenu.setText(translate('OpenLP.SlideController',
'Go To'))
self.songMenu.setText(translate('OpenLP.SlideController', 'Go To'))
self.songMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
self.toolbar.addToolbarWidget(u'Song Menu', self.songMenu)
self.songMenu.setMenu(QtGui.QMenu(
@ -303,6 +294,8 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'triggered(bool)'), self.onBlankDisplay)
QtCore.QObject.connect(self.themeScreen,
QtCore.SIGNAL(u'triggered(bool)'), self.onThemeDisplay)
QtCore.QObject.connect(self.desktopScreen,
QtCore.SIGNAL(u'triggered(bool)'), self.onHideDisplay)
QtCore.QObject.connect(self.volumeSlider,
QtCore.SIGNAL(u'sliderReleased()'), self.mediaVolume)
QtCore.QObject.connect(Receiver.get_receiver(),
@ -469,6 +462,9 @@ class SlideController(QtGui.QWidget):
self.onSlideSelected()
def receiveSpinDelay(self, value):
"""
Adjusts the value of the ``delaySpinBox`` to the given one.
"""
self.delaySpinBox.setValue(int(value))
def enableToolBar(self, item):
@ -624,6 +620,11 @@ class SlideController(QtGui.QWidget):
self.parent.renderManager.width,
self.parent.renderManager.height)
else:
# If current slide set background to image
if framenumber == slideno:
self.serviceItem.bg_image_bytes = \
self.parent.renderManager.image_manager. \
get_image_bytes(frame[u'title'])
image = self.parent.renderManager.image_manager. \
get_image(frame[u'title'])
label.setPixmap(QtGui.QPixmap.fromImage(image))
@ -747,8 +748,7 @@ class SlideController(QtGui.QWidget):
self.hideMenu.setDefaultAction(self.blankScreen)
self.blankScreen.setChecked(checked)
self.themeScreen.setChecked(False)
if self.screens.display_count > 1:
self.desktopScreen.setChecked(False)
self.desktopScreen.setChecked(False)
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Blank)
QtCore.QSettings().setValue(
@ -769,8 +769,7 @@ class SlideController(QtGui.QWidget):
self.hideMenu.setDefaultAction(self.themeScreen)
self.blankScreen.setChecked(False)
self.themeScreen.setChecked(checked)
if self.screens.display_count > 1:
self.desktopScreen.setChecked(False)
self.desktopScreen.setChecked(False)
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Theme)
QtCore.QSettings().setValue(
@ -791,9 +790,6 @@ class SlideController(QtGui.QWidget):
self.hideMenu.setDefaultAction(self.desktopScreen)
self.blankScreen.setChecked(False)
self.themeScreen.setChecked(False)
# On valid if more than 1 display
if self.screens.display_count <= 1:
return
self.desktopScreen.setChecked(checked)
if checked:
Receiver.send_message(u'maindisplay_hide', HideMode.Screen)
@ -857,6 +853,8 @@ class SlideController(QtGui.QWidget):
frame = self.display.text(toDisplay)
else:
frame = self.display.image(toDisplay)
# reset the store used to display first image
self.serviceItem.bg_image_bytes = None
self.slidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
self.selectedRow = row
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
@ -1096,15 +1094,15 @@ class SlideController(QtGui.QWidget):
Used by command items which provide their own displays to reset the
screen hide attributes
"""
blank = None
if self.blankScreen.isChecked:
self.blankScreen.setChecked(False)
self.hideMenu.setDefaultAction(self.blankScreen)
blank = self.blankScreen
if self.themeScreen.isChecked:
blank = self.themeScreen
if self.desktopScreen.isChecked:
blank = self.desktopScreen
if blank:
blank.setChecked(False)
self.hideMenu.setDefaultAction(blank)
QtCore.QSettings().remove(
self.parent.generalSettingsSection + u'/screen blank')
if self.themeScreen.isChecked:
self.themeScreen.setChecked(False)
self.hideMenu.setDefaultAction(self.themeScreen)
if self.screens.display_count > 1:
if self.desktopScreen.isChecked:
self.desktopScreen.setChecked(False)
self.hideMenu.setDefaultAction(self.desktopScreen)

View File

@ -145,6 +145,20 @@ class ThemeManager(QtGui.QWidget):
# Last little bits of setting up
self.configUpdated()
def firstTime(self):
"""
Import new themes downloaded by the first time wizard
"""
Receiver.send_message(u'cursor_busy')
encoding = get_filesystem_encoding()
files = SettingsManager.get_files(self.settingsSection, u'.otz')
for file in files:
file = os.path.join(self.path, file).encode(encoding)
self.unzipTheme(file, self.path)
delete_file(file)
self.loadThemes()
Receiver.send_message(u'cursor_normal')
def configUpdated(self, firstTime=False):
"""
Triggered when Config dialog is updated.
@ -370,6 +384,7 @@ class ThemeManager(QtGui.QWidget):
'Save Theme - (%s)')) % theme,
SettingsManager.get_last_dir(self.settingsSection, 1))
path = unicode(path)
Receiver.send_message(u'cursor_busy')
if path:
SettingsManager.set_last_dir(self.settingsSection, path, 1)
themePath = os.path.join(path, theme + u'.otz')
@ -395,6 +410,7 @@ class ThemeManager(QtGui.QWidget):
finally:
if zip:
zip.close()
Receiver.send_message(u'cursor_normal')
def onImportTheme(self):
"""
@ -408,12 +424,14 @@ class ThemeManager(QtGui.QWidget):
unicode(translate('OpenLP.ThemeManager',
'OpenLP Themes (*.theme *.otz)')))
log.info(u'New Themes %s', unicode(files))
Receiver.send_message(u'cursor_busy')
if files:
for file in files:
SettingsManager.set_last_dir(
self.settingsSection, unicode(file))
self.unzipTheme(file, self.path)
self.loadThemes()
Receiver.send_message(u'cursor_normal')
def loadThemes(self):
"""

View File

@ -135,7 +135,7 @@ class AppLocation(object):
elif dir_type == AppLocation.LanguageDir:
app_path = _get_frozen_path(
os.path.abspath(os.path.split(sys.argv[0])[0]),
os.path.split(openlp.__file__)[0])
_get_os_dir_path(dir_type))
return os.path.join(app_path, u'i18n')
else:
return _get_os_dir_path(dir_type)
@ -170,15 +170,21 @@ def _get_os_dir_path(dir_type):
if dir_type == AppLocation.DataDir:
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding),
u'openlp', u'data')
elif dir_type == AppLocation.LanguageDir:
return os.path.split(openlp.__file__)[0]
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding),
u'openlp')
elif sys.platform == u'darwin':
if dir_type == AppLocation.DataDir:
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
u'Library', u'Application Support', u'openlp', u'Data')
elif dir_type == AppLocation.LanguageDir:
return os.path.split(openlp.__file__)[0]
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
u'Library', u'Application Support', u'openlp')
else:
if dir_type == AppLocation.LanguageDir:
return os.path.join(u'/usr', u'share', u'openlp')
if XDG_BASE_AVAILABLE:
if dir_type == AppLocation.ConfigDir:
return os.path.join(unicode(BaseDirectory.xdg_config_home,
@ -338,6 +344,7 @@ def get_web_page(url, header=None, update_openlp=False):
return None
if update_openlp:
Receiver.send_message(u'openlp_process_events')
log.debug(page)
return page
def file_is_unicode(filename):

View File

@ -63,6 +63,8 @@ class LanguageManager(object):
"""
Find all available language files in this OpenLP install
"""
log.debug(u'Translation files: %s', AppLocation.get_directory(
AppLocation.LanguageDir))
trans_dir = QtCore.QDir(AppLocation.get_directory(
AppLocation.LanguageDir))
file_names = trans_dir.entryList(QtCore.QStringList(u'*.qm'),
@ -100,27 +102,37 @@ class LanguageManager(object):
return language
@staticmethod
def set_language(action):
def set_language(action, message=True):
"""
Set the language to translate OpenLP into
``action``
The language menu option
``message``
Display the message option
"""
language = u'en'
if action:
action_name = u'%s' % action.objectName()
qm_list = LanguageManager.get_qm_list()
language = u'%s' % qm_list[action_name]
action_name = unicode(action.objectName())
if action_name == u'AutoLanguageItem':
LanguageManager.auto_language = True
else:
LanguageManager.auto_language = False
qm_list = LanguageManager.get_qm_list()
language = unicode(qm_list[action_name])
if LanguageManager.auto_language:
language = u'[%s]' % language
QtCore.QSettings().setValue(
# This needs to be here for the setValue to work
settings = QtCore.QSettings(u'OpenLP', u'OpenLP')
settings.setValue(
u'general/language', QtCore.QVariant(language))
log.info(u'Language file: \'%s\' written to conf file' % language)
QtGui.QMessageBox.information(None,
translate('OpenLP.LanguageManager', 'Language'),
translate('OpenLP.LanguageManager',
'Please restart OpenLP to use your new language setting.'))
if message:
QtGui.QMessageBox.information(None,
translate('OpenLP.LanguageManager', 'Language'),
translate('OpenLP.LanguageManager',
'Please restart OpenLP to use your new language setting.'))
@staticmethod
def init_qm_list():

View File

@ -40,7 +40,7 @@ class AlertsPlugin(Plugin):
log.info(u'Alerts Plugin loaded')
def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Alerts', u'1.9.4', plugin_helpers,
Plugin.__init__(self, u'Alerts', plugin_helpers,
settingsTabClass=AlertsTab)
self.weight = -3
self.icon = build_icon(u':/plugins/plugin_alerts.png')

View File

@ -37,7 +37,7 @@ class BiblePlugin(Plugin):
log.info(u'Bible Plugin loaded')
def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Bibles', u'1.9.4', plugin_helpers,
Plugin.__init__(self, u'Bibles', plugin_helpers,
BibleMediaItem, BiblesTab)
self.weight = -9
self.icon_path = u':/plugins/plugin_bibles.png'

View File

@ -568,7 +568,8 @@ class BibleImportForm(OpenLPWizard):
"""
self.getFileName(WizardStrings.OpenTypeFile % UiStrings.OLPV1,
self.openlp1FileEdit, u'%s (*.bible)' %
translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x bible'))
translate('BiblesPlugin.ImportWizardForm',
'openlp.org 1.x Bible Files'))
def registerFields(self):
"""

View File

@ -69,8 +69,6 @@ import logging
import chardet
import csv
from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate
from openlp.plugins.bibles.lib.db import BibleDB, Testament

View File

@ -25,14 +25,14 @@
###############################################################################
import logging
import os
from PyQt4 import QtCore
from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.utils import AppLocation
from openlp.core.utils import AppLocation, delete_file
from openlp.plugins.bibles.lib import parse_reference
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from csvbible import CSVBible
from http import HTTPBible
from opensong import OpenSongBible
@ -144,6 +144,10 @@ class BibleManager(object):
for filename in files:
bible = BibleDB(self.parent, path=self.path, file=filename)
name = bible.get_name()
# Remove corrupted files.
if name is None:
delete_file(os.path.join(self.path, filename))
continue
log.debug(u'Bible Name: "%s"', name)
self.db_cache[name] = bible
# Look to see if lazy load bible exists and get create getter.
@ -250,7 +254,7 @@ class BibleManager(object):
if not bible:
Receiver.send_message(u'openlp_information_message', {
u'title': translate('BiblesPlugin.BibleManager',
'No Bibles available'),
'No Bibles Available'),
u'message': translate('BiblesPlugin.BibleManager',
'There are no Bibles currently installed. Please use the '
'Import Wizard to install one or more Bibles.')

View File

@ -346,7 +346,7 @@ class BibleMediaItem(MediaManagerItem):
self.advancedSearchButton.setEnabled(False)
critical_error_message_box(
message=translate('BiblePlugin.MediaItem',
'Bible not fully loaded'))
'Bible not fully loaded.'))
else:
self.advancedSearchButton.setEnabled(True)
self.adjustComboBox(1, self.chapter_count, self.advancedFromChapter)
@ -449,8 +449,7 @@ class BibleMediaItem(MediaManagerItem):
if restore:
old_text = unicode(combo.currentText())
combo.clear()
for i in range(range_from, range_to + 1):
combo.addItem(unicode(i))
combo.addItems([unicode(i) for i in range(range_from, range_to + 1)])
if restore and combo.findText(old_text) != -1:
combo.setCurrentIndex(combo.findText(old_text))
@ -539,8 +538,9 @@ class BibleMediaItem(MediaManagerItem):
self.displayResults(bible, second_bible)
elif critical_error_message_box(
message=translate('BiblePlugin.MediaItem',
'You cannot combine single and second bible verses. Do you '
'want to delete your search results and start a new search?'),
'You cannot combine single and dual Bible verse search results. '
'Do you want to delete your search results and start a new '
'search?'),
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.listView.clear()
self.displayResults(bible, second_bible)
@ -635,7 +635,6 @@ class BibleMediaItem(MediaManagerItem):
bible_text = u''
old_item = None
old_chapter = -1
raw_footer = []
raw_slides = []
raw_title = []
for item in items:
@ -656,13 +655,13 @@ class BibleMediaItem(MediaManagerItem):
second_text = self._decodeQtObject(bitem, 'second_text')
verse_text = self.formatVerse(old_chapter, chapter, verse)
footer = u'%s (%s %s %s)' % (book, version, copyright, permissions)
if footer not in raw_footer:
raw_footer.append(footer)
if footer not in service_item.raw_footer:
service_item.raw_footer.append(footer)
if second_bible:
footer = u'%s (%s %s %s)' % (book, second_version,
second_copyright, second_permissions)
if footer not in raw_footer:
raw_footer.append(footer)
if footer not in service_item.raw_footer:
service_item.raw_footer.append(footer)
bible_text = u'%s&nbsp;%s\n\n%s&nbsp;%s' % (verse_text, text,
verse_text, second_text)
raw_slides.append(bible_text.rstrip())
@ -704,13 +703,7 @@ class BibleMediaItem(MediaManagerItem):
service_item.theme = None
else:
service_item.theme = self.settings.bible_theme
for slide in raw_slides:
service_item.add_from_text(slide[:30], slide)
if service_item.raw_footer:
for footer in raw_footer:
service_item.raw_footer.append(footer)
else:
service_item.raw_footer = raw_footer
[service_item.add_from_text(slide[:30], slide) for slide in raw_slides]
return True
def formatTitle(self, start_item, old_item):
@ -749,8 +742,7 @@ class BibleMediaItem(MediaManagerItem):
else:
verse_range = start_chapter + verse_separator + start_verse + \
range_separator + old_chapter + verse_separator + old_verse
title = u'%s %s (%s)' % (start_book, verse_range, bibles)
return title
return u'%s %s (%s)' % (start_book, verse_range, bibles)
def checkTitle(self, item, old_item):
"""

View File

@ -27,8 +27,6 @@
import logging
import sqlite
from PyQt4 import QtCore
from openlp.core.lib import Receiver
from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.bibles.lib.db import BibleDB

View File

@ -25,9 +25,7 @@
###############################################################################
import logging
from lxml import objectify
from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate
from openlp.plugins.bibles.lib.db import BibleDB

View File

@ -31,8 +31,6 @@ import chardet
import codecs
import re
from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate
from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.db import BibleDB

View File

@ -47,7 +47,7 @@ class CustomPlugin(Plugin):
log.info(u'Custom Plugin loaded')
def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Custom', u'1.9.4', plugin_helpers,
Plugin.__init__(self, u'Custom', plugin_helpers,
CustomMediaItem, CustomTab)
self.weight = -5
self.manager = Manager(u'custom', init_schema)

View File

@ -35,8 +35,7 @@ class ImagePlugin(Plugin):
log.info(u'Image Plugin loaded')
def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Images', u'1.9.4', plugin_helpers,
ImageMediaItem)
Plugin.__init__(self, u'Images', plugin_helpers, ImageMediaItem)
self.weight = -7
self.icon_path = u':/plugins/plugin_images.png'
self.icon = build_icon(self.icon_path)

View File

@ -38,13 +38,25 @@ class MediaPlugin(Plugin):
log.info(u'%s MediaPlugin loaded', __name__)
def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Media', u'1.9.4', plugin_helpers,
Plugin.__init__(self, u'Media', plugin_helpers,
MediaMediaItem, MediaTab)
self.weight = -6
self.icon_path = u':/plugins/plugin_media.png'
self.icon = build_icon(self.icon_path)
# passed with drag and drop messages
self.dnd_id = u'Media'
self.additional_extensions = {
u'audio/ac3': [u'.ac3'],
u'audio/flac': [u'.flac'],
u'audio/x-m4a': [u'.m4a'],
u'audio/x-mp3': [u'.mp3'],
u'audio/mpeg': [u'.mp3', u'.mp2', u'.mpga', u'.mpega', u'.m4a'],
u'audio/qcelp': [u'.qcp'],
u'audio/x-wma': [u'.wma'],
u'audio/x-ms-wma': [u'.wma'],
u'video/x-matroska': [u'.mpv', u'.mkv'],
u'video/x-wmv': [u'.wmv'],
u'video/x-ms-wmv': [u'.wmv']}
self.audio_extensions_list = []
self.video_extensions_list = []
mimetypes.init()
@ -65,6 +77,17 @@ class MediaPlugin(Plugin):
self.serviceManager.supportedSuffixes(extension[1:])
log.info(u'MediaPlugin: %s extensions: %s' % (mimetype,
u' '.join(extensions)))
# Add extensions for this mimetype from self.additional_extensions.
# This hack clears mimetypes' and operating system's shortcomings
# by providing possibly missing extensions.
if mimetype in self.additional_extensions.keys():
for extension in self.additional_extensions[mimetype]:
ext = u'*%s' % extension
if ext not in list:
list.append(ext)
self.serviceManager.supportedSuffixes(extension[1:])
log.info(u'MediaPlugin: %s additional extensions: %s' % (mimetype,
u' '.join(self.additional_extensions[mimetype])))
def about(self):
about_text = translate('MediaPlugin', '<strong>Media Plugin</strong>'

View File

@ -51,7 +51,7 @@ class PresentationPlugin(Plugin):
"""
log.debug(u'Initialised')
self.controllers = {}
Plugin.__init__(self, u'Presentations', u'1.9.4', plugin_helpers)
Plugin.__init__(self, u'Presentations', plugin_helpers)
self.weight = -8
self.icon_path = u':/plugins/plugin_presentations.png'
self.icon = build_icon(self.icon_path)

View File

@ -38,7 +38,7 @@ class RemotesPlugin(Plugin):
"""
remotes constructor
"""
Plugin.__init__(self, u'Remotes', u'1.9.4', plugin_helpers,
Plugin.__init__(self, u'Remotes', plugin_helpers,
settingsTabClass=RemoteTab)
self.icon = build_icon(u':/plugins/plugin_remote.png')
self.weight = -1

View File

@ -810,4 +810,4 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
# This method must only be run after the self.song = Song() assignment.
log.debug(u'processTitle')
self.song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'',
unicode(self.song.search_title)).lower()
unicode(self.song.search_title)).lower().strip()

View File

@ -98,7 +98,10 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
match = self.verse_regex.match(text)
if match:
verse_tag = match.group(1)
verse_num = int(match.group(2))
try:
verse_num = int(match.group(2))
except ValueError:
verse_num = 1
verse_type_index = VerseType.from_loose_input(verse_tag)
if verse_type_index is not None:
self.verseNumberBox.setValue(verse_num)
@ -127,7 +130,10 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
if match:
verse_type = match.group(1)
verse_type_index = VerseType.from_loose_input(verse_type)
verse_number = int(match.group(2))
try:
verse_number = int(match.group(2))
except ValueError:
verse_number = 1
if verse_type_index is not None:
self.verseTypeComboBox.setCurrentIndex(verse_type_index)
self.verseNumberBox.setValue(verse_number)

View File

@ -355,7 +355,8 @@ class SongExportForm(OpenLPWizard):
the path to *directoryLineEdit*.
"""
path = unicode(QtGui.QFileDialog.getExistingDirectory(self,
translate('SongsPlugin.ExportWizardForm', 'Select Destination Folder'),
translate('SongsPlugin.ExportWizardForm',
'Select Destination Folder'),
SettingsManager.get_last_dir(self.plugin.settingsSection, 1),
options=QtGui.QFileDialog.ShowDirsOnly))
SettingsManager.set_last_dir(self.plugin.settingsSection, path, 1)

View File

@ -256,7 +256,7 @@ def init_schema(url):
mapper(Song, songs_table,
properties={
'authors': relation(Author, backref='songs',
secondary=authors_songs_table),
secondary=authors_songs_table, lazy=False),
'book': relation(Book, backref='songs'),
'media_files': relation(MediaFile, backref='songs',
secondary=media_files_songs_table),

View File

@ -540,7 +540,7 @@ class FoilPresenter(object):
song.alternate_title = self._child(titelstring)
song.search_title += u'@' + song.alternate_title
song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'',
unicode(song.search_title)).lower()
unicode(song.search_title)).lower().strip()
def _process_topics(self, foilpresenterfolie, song):
"""

View File

@ -159,15 +159,15 @@ class SongMediaItem(MediaManagerItem):
def onSearchTextButtonClick(self):
search_keywords = unicode(self.searchTextEdit.displayText())
search_results = []
# search_type = self.searchTypeComboBox.currentIndex()
search_type = self.searchTextEdit.currentSearchType()
if search_type == SongSearch.Entire:
log.debug(u'Entire Song Search')
search_results = self.parent.manager.get_all_objects(Song,
or_(Song.search_title.like(u'%' + self.whitespace.sub(u' ',
search_keywords.lower()) + u'%'),
Song.search_lyrics.like(u'%' + search_keywords.lower() + \
u'%')), Song.search_title.asc())
Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'),
Song.comments.like(u'%' + search_keywords.lower() + u'%')),
Song.search_title.asc())
self.displayResultsSong(search_results)
elif search_type == SongSearch.Titles:
log.debug(u'Titles Search')
@ -198,7 +198,7 @@ class SongMediaItem(MediaManagerItem):
Handle the exit from the edit dialog and trigger remote updates
of songs
"""
log.debug(u'onSongListLoad')
log.debug(u'onSongListLoad - start')
# Called to redisplay the song list screen edit from a search
# or from the exit of the Song edit dialog. If remote editing is active
# Trigger it and clean up so it will not update again.
@ -213,6 +213,7 @@ class SongMediaItem(MediaManagerItem):
self.parent.serviceManager.replaceServiceItem(item)
self.onRemoteEditClear()
self.onSearchTextButtonClick()
log.debug(u'onSongListLoad - finished')
def displayResultsSong(self, searchresults):
log.debug(u'display results Song')
@ -252,11 +253,13 @@ class SongMediaItem(MediaManagerItem):
if self.searchAsYouType:
search_length = 1
if self.searchTextEdit.currentSearchType() == SongSearch.Entire:
search_length = 3
search_length = 4
elif self.searchTextEdit.currentSearchType() == SongSearch.Lyrics:
search_length = 7
search_length = 3
if len(text) > search_length:
self.onSearchTextButtonClick()
elif len(text) == 0:
self.onClearTextButtonClick()
def onImportClick(self):
if not hasattr(self, u'import_wizard'):
@ -307,6 +310,7 @@ class SongMediaItem(MediaManagerItem):
item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0]
self.edit_song_form.loadSong(item_id, False)
self.edit_song_form.exec_()
self.editItem = None
def onDeleteClick(self):
"""
@ -330,7 +334,6 @@ class SongMediaItem(MediaManagerItem):
def generateSlideData(self, service_item, item=None, xmlVersion=False):
log.debug(u'generateSlideData (%s:%s)' % (service_item, item))
raw_footer = []
item_id = self._getIdOfItemToGenerate(item, self.remoteSong)
service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview)
@ -392,16 +395,15 @@ class SongMediaItem(MediaManagerItem):
service_item.add_from_text(slide[:30], unicode(slide))
service_item.title = song.title
author_list = [unicode(author.display_name) for author in song.authors]
raw_footer.append(song.title)
raw_footer.append(u', '.join(author_list))
raw_footer.append(song.copyright)
service_item.raw_footer.append(song.title)
service_item.raw_footer.append(u', '.join(author_list))
service_item.raw_footer.append(song.copyright)
if QtCore.QSettings().value(u'general/ccli number',
QtCore.QVariant(u'')).toString():
raw_footer.append(unicode(
service_item.raw_footer.append(unicode(
translate('SongsPlugin.MediaItem', 'CCLI License: ') +
QtCore.QSettings().value(u'general/ccli number',
QtCore.QVariant(u'')).toString()))
service_item.raw_footer = raw_footer
service_item.audit = [
song.title, author_list, song.copyright, unicode(song.ccli_number)
]
@ -447,10 +449,9 @@ class SongMediaItem(MediaManagerItem):
add_song = False
editId = song.id
break
if add_song:
if self.addSongFromService:
editId = self.openLyrics.xml_to_song(item.xml_version)
self.onSearchTextButtonClick()
if add_song and self.addSongFromService:
editId = self.openLyrics.xml_to_song(item.xml_version)
self.onSearchTextButtonClick()
# Update service with correct song id.
if editId:
Receiver.send_message(u'service_item_update',

View File

@ -151,12 +151,14 @@ class OpenLPSongImport(SongImport):
source_songs = self.source_session.query(OldSong).all()
song_total = len(source_songs)
self.import_wizard.progressBar.setMaximum(song_total)
if self.import_wizard:
self.import_wizard.progressBar.setMaximum(song_total)
song_count = 1
for song in source_songs:
self.import_wizard.incrementProgressBar(unicode(translate(
'SongsPlugin.OpenLPSongImport', 'Importing song %d of %d.')) %
(song_count, song_total))
if self.import_wizard:
self.import_wizard.incrementProgressBar(
unicode(translate('SongsPlugin.OpenLPSongImport',
'Importing song %d of %d.')) % (song_count, song_total))
new_song = Song()
new_song.title = song.title
if has_media_files and hasattr(song, 'alternate_title'):
@ -167,7 +169,7 @@ class OpenLPSongImport(SongImport):
new_song.alternate_title = old_titles[1]
else:
new_song.alternate_title = u''
new_song.search_title = song.search_title
new_song.search_title = song.search_title.strip()
new_song.song_number = song.song_number
new_song.lyrics = song.lyrics
new_song.search_lyrics = song.search_lyrics

View File

@ -96,7 +96,7 @@ class OooImport(SongImport):
"""
if os.name == u'nt':
self.start_ooo_process()
self.desktop = self.manager.createInstance(
self.desktop = self.ooo_manager.createInstance(
u'com.sun.star.frame.Desktop')
else:
context = uno.getComponentContext()
@ -118,9 +118,9 @@ class OooImport(SongImport):
def start_ooo_process(self):
try:
if os.name == u'nt':
self.manager = Dispatch(u'com.sun.star.ServiceManager')
self.manager._FlagAsMethod(u'Bridge_GetStruct')
self.manager._FlagAsMethod(u'Bridge_GetValueObject')
self.ooo_manager = Dispatch(u'com.sun.star.ServiceManager')
self.ooo_manager._FlagAsMethod(u'Bridge_GetStruct')
self.ooo_manager._FlagAsMethod(u'Bridge_GetValueObject')
else:
cmd = get_uno_command()
process = QtCore.QProcess()
@ -134,9 +134,11 @@ class OooImport(SongImport):
"""
Open the passed file in OpenOffice.org Impress
"""
self.filepath = filepath
if os.name == u'nt':
url = u'file:///' + filepath.replace(u'\\', u'/')
url = filepath.replace(u'\\', u'/')
url = url.replace(u':', u'|').replace(u' ', u'%20')
url = u'file:///' + url
else:
url = uno.systemPathToFileUrl(filepath)
properties = []
@ -190,10 +192,7 @@ class OooImport(SongImport):
if slidetext.strip() == u'':
slidetext = u'\f'
text += slidetext
song = SongImport(self.manager)
songs = SongImport.process_songs_text(self.manager, text)
for song in songs:
song.finish()
self.process_songs_text(text)
return
def process_doc(self):
@ -215,6 +214,16 @@ class OooImport(SongImport):
if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
paratext += u'\f'
text += paratext + u'\n'
songs = SongImport.process_songs_text(self.manager, text)
for song in songs:
song.finish()
self.process_songs_text(text)
def process_songs_text(self, text):
songtexts = self.tidy_text(text).split(u'\f')
self.set_defaults()
for songtext in songtexts:
if songtext.strip():
self.process_song_text(songtext.strip())
if self.check_complete():
self.finish()
self.set_defaults()
if self.check_complete():
self.finish()

View File

@ -29,10 +29,11 @@ songs from the database to the OpenLyrics format.
"""
import logging
import os
import re
from lxml import etree
from openlp.core.lib import Receiver, translate
from openlp.core.lib import check_directory_exists, Receiver, translate
from openlp.plugins.songs.lib import OpenLyrics
log = logging.getLogger(__name__)
@ -50,8 +51,7 @@ class OpenLyricsExport(object):
self.manager = parent.plugin.manager
self.songs = songs
self.save_path = save_path
if not os.path.exists(self.save_path):
os.mkdir(self.save_path)
check_directory_exists(self.save_path)
def do_export(self):
"""
@ -69,6 +69,10 @@ class OpenLyricsExport(object):
song.title)
xml = openLyrics.song_to_xml(song)
tree = etree.ElementTree(etree.fromstring(xml))
tree.write(os.path.join(self.save_path, song.title + u'.xml'),
filename = u'%s (%s).xml' % (song.title,
u', '.join([author.display_name for author in song.authors]))
filename = re.sub(
r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_')
tree.write(os.path.join(self.save_path, filename),
encoding=u'utf-8', xml_declaration=True, pretty_print=True)
return True

View File

@ -72,6 +72,7 @@ class SofImport(OooImport):
to SongImport for writing song to disk
"""
OooImport.__init__(self, manager, **kwargs)
self.song = False
def process_ooo_document(self):
"""
@ -94,8 +95,8 @@ class SofImport(OooImport):
if paragraph.supportsService("com.sun.star.text.Paragraph"):
self.process_paragraph(paragraph)
if self.song:
self.song.finish()
self.song = None
self.finish()
self.song = False
def process_paragraph(self, paragraph):
"""
@ -143,7 +144,7 @@ class SofImport(OooImport):
self.blanklines += 1
if self.blanklines > 1:
return
if self.song.title != u'':
if self.title != u'':
self.finish_verse()
return
self.blanklines = 0
@ -161,17 +162,17 @@ class SofImport(OooImport):
self.skip_to_close_bracket = True
return
if text.startswith(u'Copyright'):
self.song.add_copyright(text)
self.add_copyright(text)
return
if text == u'(Repeat)':
self.finish_verse()
self.song.repeat_verse()
self.repeat_verse()
return
if self.song.title == u'':
if self.song.copyright == u'':
self.add_author(text)
if self.title == u'':
if self.copyright == u'':
self.add_sof_author(text)
else:
self.song.add_copyright(text)
self.add_copyright(text)
return
self.add_verse_line(text)
@ -183,15 +184,15 @@ class SofImport(OooImport):
into line
"""
text = textportion.getString()
text = SongImport.tidy_text(text)
text = self.tidy_text(text)
if text.strip() == u'':
return text
if textportion.CharWeight == BOLD:
boldtext = text.strip()
if boldtext.isdigit() and self.song.song_number == '':
if boldtext.isdigit() and self.song_number == '':
self.add_songnumber(boldtext)
return u''
if self.song.title == u'':
if self.title == u'':
text = self.uncap_text(text)
self.add_title(text)
return text
@ -207,10 +208,11 @@ class SofImport(OooImport):
"""
if self.song:
self.finish_verse()
if not self.song.check_complete():
if not self.check_complete():
return
self.song.finish()
self.song = SongImport(self.manager)
self.finish()
self.song = True
self.set_defaults()
self.skip_to_close_bracket = False
self.is_chorus = False
self.italics = False
@ -221,17 +223,17 @@ class SofImport(OooImport):
Add a song number, store as alternate title. Also use the song
number to work out which songbook we're in
"""
self.song.song_number = song_no
self.song.alternate_title = song_no + u'.'
self.song.song_book_pub = u'Kingsway Publications'
self.song_number = song_no
self.alternate_title = song_no + u'.'
self.song_book_pub = u'Kingsway Publications'
if int(song_no) <= 640:
self.song.song_book = u'Songs of Fellowship 1'
self.song_book = u'Songs of Fellowship 1'
elif int(song_no) <= 1150:
self.song.song_book = u'Songs of Fellowship 2'
self.song_book = u'Songs of Fellowship 2'
elif int(song_no) <= 1690:
self.song.song_book = u'Songs of Fellowship 3'
self.song_book = u'Songs of Fellowship 3'
else:
self.song.song_book = u'Songs of Fellowship 4'
self.song_book = u'Songs of Fellowship 4'
def add_title(self, text):
"""
@ -243,10 +245,10 @@ class SofImport(OooImport):
title = title[1:]
if title.endswith(u','):
title = title[:-1]
self.song.title = title
self.title = title
self.import_wizard.incrementProgressBar(u'Processing song ' + title, 0)
def add_author(self, text):
def add_sof_author(self, text):
"""
Add the author. OpenLP stores them individually so split by 'and', '&'
and comma.
@ -254,7 +256,7 @@ class SofImport(OooImport):
"Mr Smith" and "Mrs Smith".
"""
text = text.replace(u' and ', u' & ')
self.song.parse_author(text)
self.parse_author(text)
def add_verse_line(self, text):
"""
@ -262,7 +264,7 @@ class SofImport(OooImport):
we're beyond the second line of first verse, then this indicates
a change of verse. Italics are a chorus
"""
if self.italics != self.is_chorus and ((len(self.song.verses) > 0) or
if self.italics != self.is_chorus and ((len(self.verses) > 0) or
(self.currentverse.count(u'\n') > 1)):
self.finish_verse()
if self.italics:
@ -282,14 +284,14 @@ class SofImport(OooImport):
splitat = None
else:
versetag = u'V'
splitat = self.verse_splits(self.song.song_number)
splitat = self.verse_splits(self.song_number)
if splitat:
ln = 0
verse = u''
for line in self.currentverse.split(u'\n'):
ln += 1
if line == u'' or ln > splitat:
self.song.add_verse(verse, versetag)
self.add_sof_verse(verse, versetag)
ln = 0
if line:
verse = line + u'\n'
@ -298,12 +300,18 @@ class SofImport(OooImport):
else:
verse += line + u'\n'
if verse:
self.song.add_verse(verse, versetag)
self.add_sof_verse(verse, versetag)
else:
self.song.add_verse(self.currentverse, versetag)
self.add_sof_verse(self.currentverse, versetag)
self.currentverse = u''
self.is_chorus = False
def add_sof_verse(self, lyrics, tag):
self.add_verse(lyrics, tag)
if not self.is_chorus and u'C1' in self.verse_order_list_generated:
self.verse_order_list_generated.append(u'C1')
self.verse_order_list_generated_useful = True
def uncap_text(self, text):
"""
Words in the title are in all capitals, so we lowercase them.

View File

@ -62,6 +62,7 @@ class SongImport(QtCore.QObject):
else:
raise KeyError(u'Keyword arguments "filename[s]" not supplied.')
log.debug(self.import_source)
self.import_wizard = None
self.song = None
self.stop_import_flag = False
self.set_defaults()
@ -103,23 +104,7 @@ class SongImport(QtCore.QObject):
def register(self, import_wizard):
self.import_wizard = import_wizard
@staticmethod
def process_songs_text(manager, text):
songs = []
songtexts = SongImport.tidy_text(text).split(u'\f')
song = SongImport(manager)
for songtext in songtexts:
if songtext.strip():
song.process_song_text(songtext.strip())
if song.check_complete():
songs.append(song)
song = SongImport(manager)
if song.check_complete():
songs.append(song)
return songs
@staticmethod
def tidy_text(text):
def tidy_text(self, text):
"""
Get rid of some dodgy unicode and formatting characters we're not
interested in. Some can be converted to ascii.
@ -146,12 +131,12 @@ class SongImport(QtCore.QObject):
def process_verse_text(self, text):
lines = text.split(u'\n')
if text.lower().find(self.copyright_string) >= 0 \
or text.find(SongStrings.CopyrightSymbol) >= 0:
or text.find(unicode(SongStrings.CopyrightSymbol)) >= 0:
copyright_found = False
for line in lines:
if (copyright_found or
line.lower().find(self.copyright_string) >= 0 or
line.find(SongStrings.CopyrightSymbol) >= 0):
line.find(unicode(SongStrings.CopyrightSymbol)) >= 0):
copyright_found = True
self.add_copyright(line)
else:
@ -276,6 +261,7 @@ class SongImport(QtCore.QObject):
song.alternate_title = self.alternate_title
song.search_title = self.remove_punctuation(self.title).lower() \
+ '@' + self.remove_punctuation(self.alternate_title).lower()
song.search_title = song.search_title.strip()
song.song_number = self.song_number
song.search_lyrics = u''
verses_changed_to_other = {}

View File

@ -444,7 +444,6 @@ class OpenLyrics(object):
"""
sxml = SongXML()
search_text = u''
temp_verse_order = []
for verse in lyrics.verse:
text = u''
for lines in verse.lines:
@ -455,11 +454,10 @@ class OpenLyrics(object):
verse_type_index = VerseType.from_tag(verse_name[0])
verse_type = VerseType.Names[verse_type_index]
verse_number = re.compile(u'[a-zA-Z]*').sub(u'', verse_name)
verse_part = re.compile(u'[0-9]*').sub(u'', verse_name[1:])
# OpenLyrics allows e. g. "c", but we need "c1".
# OpenLyrics allows e. g. "c", but we need "c1". However, this does
# not correct the verse order.
if not verse_number:
verse_number = u'1'
temp_verse_order.append((verse_type, verse_number, verse_part))
lang = None
if self._get(verse, u'lang'):
lang = self._get(verse, u'lang')
@ -470,24 +468,6 @@ class OpenLyrics(object):
# Process verse order
if hasattr(properties, u'verseOrder'):
song.verse_order = self._text(properties.verseOrder)
else:
# We have to process the temp_verse_order, as the verseOrder
# property is not present.
previous_type = u''
previous_number = u''
previous_part = u''
verse_order = []
# Currently we do not support different "parts"!
for name in temp_verse_order:
if name[0] == previous_type:
if name[1] != previous_number:
verse_order.append(u''.join((name[0][0], name[1])))
else:
verse_order.append(u''.join((name[0][0], name[1])))
previous_type = name[0]
previous_number = name[1]
previous_part = name[2]
song.verse_order = u' '.join(verse_order)
def _process_songbooks(self, properties, song):
"""
@ -536,7 +516,7 @@ class OpenLyrics(object):
song.alternate_title = self._text(title)
song.search_title += u'@' + song.alternate_title
song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'',
unicode(song.search_title)).lower()
unicode(song.search_title)).lower().strip()
def _process_topics(self, properties, song):
"""

View File

@ -26,16 +26,20 @@
import logging
import re
import os
from tempfile import gettempdir
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib import Plugin, StringContent, build_icon, translate, \
Receiver
from openlp.core.lib.db import Manager
from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.lib import add_author_unknown, SongMediaItem, \
SongsTab, SongXML
from openlp.plugins.songs.lib.db import init_schema, Song
from openlp.plugins.songs.lib.importer import SongFormat
from openlp.plugins.songs.lib.olpimport import OpenLPSongImport
log = logging.getLogger(__name__)
@ -53,8 +57,7 @@ class SongsPlugin(Plugin):
"""
Create and set up the Songs plugin.
"""
Plugin.__init__(self, u'Songs', u'1.9.4', plugin_helpers,
SongMediaItem, SongsTab)
Plugin.__init__(self, u'Songs', plugin_helpers, SongMediaItem, SongsTab)
self.weight = -10
self.manager = Manager(u'songs', init_schema)
self.icon_path = u':/plugins/plugin_songs.png'
@ -154,7 +157,7 @@ class SongsPlugin(Plugin):
if song.alternate_title is None:
song.alternate_title = u''
song.search_title = self.whitespace.sub(u' ', song.title.lower() +
u' ' + song.alternate_title.lower())
u' ' + song.alternate_title.lower()).strip()
# Remove the "language" attribute from lyrics tag. This is not very
# important, but this keeps the database clean. This can be removed
# when everybody has run the reindex tool once.
@ -245,6 +248,35 @@ class SongsPlugin(Plugin):
}
self.setPluginUiTextStrings(tooltips)
def firstTime(self):
"""
If the first time wizard has run, this function is run to import all the
new songs into the database.
"""
db_dir = unicode(os.path.join(gettempdir(), u'openlp'))
song_dbs = []
for sfile in os.listdir(db_dir):
if sfile.startswith(u'songs_') and sfile.endswith(u'.sqlite'):
song_dbs.append(os.path.join(db_dir, sfile))
if len(song_dbs) == 0:
return
progress = QtGui.QProgressDialog(self.formparent)
progress.setWindowModality(QtCore.Qt.WindowModal)
progress.setLabelText(translate('OpenLP.Ui', 'Starting import...'))
progress.setCancelButton(None)
progress.setRange(0, len(song_dbs))
progress.setMinimumDuration(0)
progress.forceShow()
for idx, db in enumerate(song_dbs):
progress.setValue(idx)
Receiver.send_message(u'openlp_process_events')
importer = OpenLPSongImport(self.manager, filename=db)
importer.do_import()
progress.setValue(len(song_dbs))
self.mediaItem.displayResultsSong(
self.manager.get_all_objects(Song, order_by_ref=Song.search_title))
self.onToolsReindexItemTriggered()
def finalise(self):
"""
Time to tidy up on exit

View File

@ -88,6 +88,15 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
"""
log.debug(u'accept')
path = unicode(self.fileLineEdit.text())
if path == u'':
Receiver.send_message(u'openlp_error_message', {
u'title': translate('SongUsagePlugin.SongUsageDetailForm',
'Output Path Not Selected'),
u'message': unicode(translate(
'SongUsagePlugin.SongUsageDetailForm', 'You have not set a '
'valid output location for your song usage report. Please '
'select an existing path on your computer.'))})
return
check_directory_exists(path)
filename = unicode(translate('SongUsagePlugin.SongUsageDetailForm',
'usage_detail_%s_%s.txt')) % (

View File

@ -42,7 +42,7 @@ class SongUsagePlugin(Plugin):
log.info(u'SongUsage Plugin loaded')
def __init__(self, plugin_helpers):
Plugin.__init__(self, u'SongUsage', u'1.9.4', plugin_helpers)
Plugin.__init__(self, u'SongUsage', plugin_helpers)
self.weight = -4
self.icon = build_icon(u':/plugins/plugin_songusage.png')
self.manager = None

17
resources/debian/Makefile Normal file
View File

@ -0,0 +1,17 @@
#!/usr/bin/make -f
# -*- makefile -*-
build:
mkdir -p resources/i18n/qm
for TSFILE in resources/i18n/*.ts; do\
lrelease-qt4 $$TSFILE -qm resources/i18n/qm/`basename $$TSFILE .ts`.qm;\
done
install:
mkdir -p $(DESTDIR)/usr/share/openlp/i18n
cd resources/i18n/qm && for QMFILE in*.qm; do\
mv $QMFILE $(DESTDIR)/usr/share/openlp/i18n;\
done
clean:
rm -fR resources/i18n/qm

View File

@ -0,0 +1,389 @@
openlp (1.9.4+bzr1355-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 06 Mar 2011 00:10:03 -0500
openlp (1.9.4+bzr1355-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 06 Mar 2011 00:07:03 -0500
openlp (1.9.4+bzr1355-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 06 Mar 2011 00:05:27 -0500
openlp (1.9.4+bzr1355-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 06 Mar 2011 00:03:17 -0500
openlp (1.9.4+bzr1350-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 05 Mar 2011 00:08:15 -0500
openlp (1.9.4+bzr1350-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 05 Mar 2011 00:06:40 -0500
openlp (1.9.4+bzr1350-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 05 Mar 2011 00:05:09 -0500
openlp (1.9.4+bzr1350-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 05 Mar 2011 00:03:14 -0500
openlp (1.9.4+bzr1347-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Fri, 04 Mar 2011 00:04:49 -0500
openlp (1.9.4+bzr1347-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Fri, 04 Mar 2011 00:04:15 -0500
openlp (1.9.4+bzr1347-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Fri, 04 Mar 2011 00:03:34 -0500
openlp (1.9.4+bzr1347-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Fri, 04 Mar 2011 00:02:43 -0500
openlp (1.9.4+bzr1344-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Thu, 03 Mar 2011 00:03:56 -0500
openlp (1.9.4+bzr1344-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Thu, 03 Mar 2011 00:03:30 -0500
openlp (1.9.4+bzr1344-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Thu, 03 Mar 2011 00:03:05 -0500
openlp (1.9.4+bzr1344-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Thu, 03 Mar 2011 00:02:26 -0500
openlp (1.9.4+bzr1342-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Tue, 01 Mar 2011 00:03:44 -0500
openlp (1.9.4+bzr1342-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Tue, 01 Mar 2011 00:03:28 -0500
openlp (1.9.4+bzr1342-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Tue, 01 Mar 2011 00:03:03 -0500
openlp (1.9.4+bzr1342-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Tue, 01 Mar 2011 00:02:28 -0500
openlp (1.9.4+bzr1341-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 27 Feb 2011 00:04:05 -0500
openlp (1.9.4+bzr1341-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 27 Feb 2011 00:03:48 -0500
openlp (1.9.4+bzr1341-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 27 Feb 2011 00:03:20 -0500
openlp (1.9.4+bzr1341-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 27 Feb 2011 00:02:34 -0500
openlp (1.9.4+bzr1337-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 26 Feb 2011 00:04:02 -0500
openlp (1.9.4+bzr1337-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 26 Feb 2011 00:03:44 -0500
openlp (1.9.4+bzr1337-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 26 Feb 2011 00:03:18 -0500
openlp (1.9.4+bzr1337-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 26 Feb 2011 00:02:32 -0500
openlp (1.9.4+bzr1332-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Fri, 25 Feb 2011 00:04:00 -0500
openlp (1.9.4+bzr1332-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Fri, 25 Feb 2011 00:03:41 -0500
openlp (1.9.4+bzr1332-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Fri, 25 Feb 2011 00:03:16 -0500
openlp (1.9.4+bzr1332-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Fri, 25 Feb 2011 00:02:36 -0500
openlp (1.9.4+bzr1328-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Thu, 24 Feb 2011 00:03:47 -0500
openlp (1.9.4+bzr1328-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Thu, 24 Feb 2011 00:03:31 -0500
openlp (1.9.4+bzr1328-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Thu, 24 Feb 2011 00:03:07 -0500
openlp (1.9.4+bzr1328-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Thu, 24 Feb 2011 00:02:28 -0500
openlp (1.9.4+bzr1324-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Wed, 23 Feb 2011 00:03:48 -0500
openlp (1.9.4+bzr1324-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Wed, 23 Feb 2011 00:03:33 -0500
openlp (1.9.4+bzr1324-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Wed, 23 Feb 2011 00:03:08 -0500
openlp (1.9.4+bzr1324-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Wed, 23 Feb 2011 00:02:28 -0500
openlp (1.9.4+bzr1322-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Tue, 22 Feb 2011 00:04:06 -0500
openlp (1.9.4+bzr1322-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Tue, 22 Feb 2011 00:03:52 -0500
openlp (1.9.4+bzr1322-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Tue, 22 Feb 2011 00:03:28 -0500
openlp (1.9.4+bzr1322-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Tue, 22 Feb 2011 00:02:42 -0500
openlp (1.9.4+bzr1320-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Mon, 21 Feb 2011 00:03:59 -0500
openlp (1.9.4+bzr1320-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Mon, 21 Feb 2011 00:03:45 -0500
openlp (1.9.4+bzr1320-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Mon, 21 Feb 2011 00:03:21 -0500
openlp (1.9.4+bzr1320-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Mon, 21 Feb 2011 00:02:41 -0500
openlp (1.9.4+bzr1316-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 20 Feb 2011 05:32:08 -0500
openlp (1.9.4+bzr1316-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 20 Feb 2011 05:31:51 -0500
openlp (1.9.4+bzr1316-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 20 Feb 2011 05:31:28 -0500
openlp (1.9.4+bzr1316-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sun, 20 Feb 2011 05:30:49 -0500
openlp (1.9.4+bzr1315-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 16:24:12 -0500
openlp (1.9.4+bzr1315-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 16:23:51 -0500
openlp (1.9.4+bzr1315-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 16:23:28 -0500
openlp (1.9.4+bzr1315-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 16:22:49 -0500
openlp (1.9.4+bzr1314-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 15:35:36 -0500
openlp (1.9.4+bzr1314-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 15:35:21 -0500
openlp (1.9.4+bzr1314-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 15:34:53 -0500
openlp (1.9.4+bzr1314-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 15:34:10 -0500
openlp (1.9.4+bzr1313-0ubuntu1~natty1) natty; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 13:58:14 -0500
openlp (1.9.4+bzr1313-0ubuntu1~maverick1) maverick; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 13:57:40 -0500
openlp (1.9.4+bzr1313-0ubuntu1~lucid1) lucid; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 13:57:11 -0500
openlp (1.9.4+bzr1313-0ubuntu1~karmic1) karmic; urgency=low
* Autobuild
-- <openlp@projecthq.biz> Sat, 19 Feb 2011 13:56:17 -0500
openlp (0.0.0+bzr664-0ubuntu1) karmic; urgency=low
* Initial release
-- Michael Gorven <michael@gorven.za.net> Fri, 06 Nov 2009 09:46:40 +0200

View File

@ -0,0 +1 @@
5

View File

@ -0,0 +1,19 @@
Source: openlp
Section: python
Priority: extra
Maintainer: OpenLP Developers <openlp-dev@lists.launchpad.net>
Build-Depends: cdbs, debhelper (>= 5), python-setuptools, python-support,
python, qt4-dev-tools
Standards-Version: 3.8.3
Homepage: http://openlp.org/
Package: openlp
Architecture: all
Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python-qt4,
python-qt4-phonon, python-sqlalchemy, python-chardet, python-beautifulsoup,
python-lxml, python-sqlite, python-enchant
Conflicts: python-openlp
Description: Church lyrics projection application
OpenLP is free church presentation software, or lyrics projection software,
used to display slides of songs, Bible verses, videos, images, and even
presentations for church worship using a computer and a data projector.

View File

@ -0,0 +1,10 @@
Format-Specification: http://wiki.debian.org/Proposals/CopyrightFormat
Upstream-Name: OpenLP
Upstream-Maintainer: OpenLP Developers <openlp-dev@lists.launchpad.net>
Upstream-Source: http://openlp.org/
Files: *
Copyright: (c) 2008-2009 Raoul Snyman
License: GPL-2
X-Comment: On Debian GNU/Linux systems, the complete text of the
GPL-2 License can be found in /usr/share/common-licenses/GPL-2

View File

@ -0,0 +1 @@
documentation

View File

@ -0,0 +1 @@
resources/openlp.desktop /usr/share/applications

View File

@ -0,0 +1 @@
2

View File

@ -0,0 +1 @@
2.5-

21
resources/debian/debian/rules Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/make -f
DEB_PYTHON_SYSTEM := pysupport
DEB_MAKE_BUILD_TARGET := build
DEB_MAKE_INSTALL_TARGET := install
DEB_MAKE_CLEAN_TARGET := clean
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/python-distutils.mk
include /usr/share/cdbs/1/class/makefile.mk
binary-post-install/openlp::
for SIZE in 16x16 32x32 48x48 64x64 128x128 256x256; do \
mkdir -p debian/openlp/usr/share/icons/hicolor/$$SIZE/apps && \
cp resources/images/openlp-logo-$$SIZE.png debian/openlp/usr/share/icons/hicolor/$$SIZE/apps/openlp.png; \
done
mkdir -p debian/openlp/usr/share/icons/hicolor/scalable/apps && \
cp resources/images/openlp-logo.svg debian/openlp/usr/share/icons/hicolor/scalable/apps/openlp.svg
cd debian/openlp/usr/bin/ && mv openlp.pyw openlp

View File

@ -0,0 +1,375 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FirstTimeWizard</class>
<widget class="QWizard" name="FirstTimeWizard">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>550</width>
<height>386</height>
</rect>
</property>
<property name="windowTitle">
<string>First Time Wizard</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<property name="wizardStyle">
<enum>QWizard::ModernStyle</enum>
</property>
<property name="options">
<set>QWizard::IndependentPages|QWizard::NoBackButtonOnStartPage</set>
</property>
<widget class="QWizardPage" name="welcomePage">
<property name="title">
<string/>
</property>
<property name="subTitle">
<string/>
</property>
<layout class="QHBoxLayout" name="welcomeLayout">
<property name="spacing">
<number>8</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="importBibleImage">
<property name="minimumSize">
<size>
<width>163</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>163</width>
<height>16777215</height>
</size>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images/openlp-2.qrc">:/wizards/wizard_importbible.bmp</pixmap>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="welcomePageLayout">
<property name="spacing">
<number>8</number>
</property>
<item>
<widget class="QLabel" name="titleLabel">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Welcome to the First Time Wizard&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="welcomeTopSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="informationLabel">
<property name="text">
<string>This wizard will help you to configure OpenLP for initial use . Click the next button below to start the process of selection your initial options. </string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>10</number>
</property>
</widget>
</item>
<item>
<spacer name="welcomeBottomSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="PluginPagePage">
<property name="title">
<string>Activate required Plugins</string>
</property>
<property name="subTitle">
<string>Select the Plugins you wish to use. </string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="songsCheckBox">
<property name="text">
<string>Songs</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="customCheckBox">
<property name="text">
<string>Custom Text</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="bibleCheckBox">
<property name="text">
<string>Bible</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="imageCheckBox">
<property name="text">
<string>Images</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="presentationCheckBox">
<property name="text">
<string>Presentations</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="mediaCheckBox">
<property name="text">
<string>Media (Audio and Video)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="remoteCheckBox">
<property name="text">
<string>Allow remote access</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="songUsageCheckBox">
<property name="text">
<string>Monitor Song Usage</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="alertCheckBox">
<property name="text">
<string>Allow Alerts</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWizardPage" name="downloadDefaultsPage">
<property name="title">
<string>Download Samples from OpenLP.org</string>
</property>
<property name="subTitle">
<string>Select samples to downlaod and install for use.</string>
</property>
<widget class="QLabel" name="noInternetLabel">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>461</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>No Internet connection found so unable to download any default files.</string>
</property>
</widget>
<widget class="QGroupBox" name="internetGroupBox">
<property name="geometry">
<rect>
<x>20</x>
<y>0</y>
<width>501</width>
<height>281</height>
</rect>
</property>
<property name="title">
<string>Download Example Files</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QTreeWidget" name="selectionTreeWidget">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QWizardPage" name="DefaultsPage">
<property name="title">
<string>Default Settings</string>
</property>
<property name="subTitle">
<string>Set up default values to be used by OpenLP</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>491</width>
<height>113</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="displaySelectionLabel">
<property name="text">
<string>Default output display</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="displaySelectionComboBox">
<property name="editable">
<bool>false</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="themeSelectionLabel">
<property name="text">
<string>Select the default Theme</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="themeSelectionComboBox">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QLabel" name="messageLabel">
<property name="geometry">
<rect>
<x>60</x>
<y>160</y>
<width>471</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Press Finish to apply all you changes and start OpenLP</string>
</property>
</widget>
<widget class="QLabel" name="updateLabel">
<property name="geometry">
<rect>
<x>60</x>
<y>220</y>
<width>351</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
</widget>
<resources>
<include location="../images/openlp-2.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,30 @@
# Copyright 1999-2009 Gentoo Foundation
# Copyright 2010 Jaak Ristioja
# Distributed under the terms of the GNU General Public License v2
# $Header: $
EAPI=2
RESTRICT_PYTHON_ABIS="3.*"
inherit python
DESCRIPTION="Free church presentation software"
HOMEPAGE="http://openlp.org/"
SRC_URI="mirror://sourceforge/${PN}/${PV}/OpenLP-${PV}-src.tar.gz"
LICENSE="GPL-2"
SLOT="0"
KEYWORDS="alpha amd64 arm hppa ia64 ppc ppc64 sparc x86 x86-fbsd x86-freebsd amd64-linux x86-linux x86-macos x86-solaris"
RDEPEND=">=dev-lang/python-2.5.0
dev-python/beautifulsoup
dev-python/chardet
dev-python/lxml
dev-python/pyenchant
dev-python/PyQt4[X,multimedia]
dev-python/sqlalchemy"
DEPEND="${RDEPEND}"
PYTHON_DEPEND="2:2.5"
PYTHON_MODNAME="openlp"
S=${WORKDIR}/OpenLP-${PV}-src

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

4929
resources/i18n/zh_CN.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -92,6 +92,7 @@
<file>wizard_exportsong.bmp</file>
<file>wizard_importsong.bmp</file>
<file>wizard_importbible.bmp</file>
<file>wizard_firsttime.bmp</file>
<file>wizard_createtheme.bmp</file>
</qresource>
<qresource prefix="services">

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB