This commit is contained in:
Tim Bentley 2010-10-11 17:14:46 +01:00
commit 026c25facb
33 changed files with 1670 additions and 630 deletions

View File

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

View File

@ -17,7 +17,7 @@ import sys
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.append(os.path.abspath(os.path.join('..', '..')))
sys.path.insert(0, os.path.abspath(os.path.join('..', '..')))
# -- General configuration -----------------------------------------------------

View File

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

View File

@ -0,0 +1,22 @@
.. OpenLP documentation master file, created by
sphinx-quickstart on Thu Sep 30 21:24:54 2010.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to OpenLP's documentation
==================================
Contents:
.. toctree::
:maxdepth: 2
introduction
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -0,0 +1,46 @@
=============
Introduction
=============
About
-----
OpenLP is an open source lyrics projection application developed specifically
for churches. It is licensed under the GNU Generic Public License, which means
that it is free to use and distribute, and it stays free.
Lyrics Projection
-----------------
OpenLP's purpose is to project the lyrics of songs and Bible verses using a
computer and a data projector. OpenLP also has the ability to project videos,
images, and also play audio. OpenLP also is highly customizable providing users
with the ability to set up a wide variety of themes, including themes with
video backgrounds.
Open Source
-----------
OpenLP is open source software. This means that the source code (the
programming instructions the developers write) is open to anyone who wants to
look at it. This gives you, the end user, a few freedoms.
From a developer's perspective, it gives you the freedom to inspect the code
and make sure that it is not malicious. Also, it gives you the freedom to
change the code and the freedom to "fork" the project and make it your own.
For end users open source software gives you the freedom to use software as
you wish. You are not required to pay for the software and you are free to
make copies and distribute it to anyone you want.
GNU General Public License
--------------------------
The GNU General Public License was specifically chosen because it ensures the
above mentioned freedoms. It specifically states that you are not allowed
to charge for the software, and that you have to distribute the source code as
well.
You can find a copy of the GNU General Public License from the Help menu
selecting about OpenLP or on-line
at: http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt

View File

@ -6,8 +6,8 @@
.. automodule:: openlp.plugins.songs
:members:
:mod:`SongsPlugin` Class
------------------------
:class:`SongsPlugin` Class
--------------------------
.. autoclass:: openlp.plugins.songs.songsplugin.SongsPlugin
:members:
@ -18,8 +18,8 @@
.. automodule:: openlp.plugins.songs.forms
:members:
:mod:`AuthorsForm`
^^^^^^^^^^^^^^^^^^
:class:`AuthorsForm`
^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.authorsdialog.Ui_AuthorsDialog
:members:
@ -27,8 +27,8 @@
.. autoclass:: openlp.plugins.songs.forms.authorsform.AuthorsForm
:members:
:mod:`EditSongForm`
^^^^^^^^^^^^^^^^^^^
:class:`EditSongForm`
^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.editsongdialog.Ui_EditSongDialog
:members:
@ -36,11 +36,158 @@
.. autoclass:: openlp.plugins.songs.forms.editsongform.EditSongForm
:members:
:mod:`EditVerseForm`
^^^^^^^^^^^^^^^^^^^^
:class:`EditVerseForm`
^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.editversedialog.Ui_EditVerseDialog
:members:
.. autoclass:: openlp.plugins.songs.forms.editverseform.EditVerseForm
:members:
:class:`SongBookForm`
^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.songbookdialog.Ui_SongBookDialog
:members:
.. autoclass:: openlp.plugins.songs.forms.songbookform.SongBookForm
:members:
:class:`SongImportForm`
^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.songimportwizard.Ui_SongImportWizard
:members:
.. autoclass:: openlp.plugins.songs.forms.songimportform.ImportWizardForm
:members:
:class:`SongMaintenanceForm`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.songmaintenancedialog.Ui_SongMaintenanceDialog
:members:
.. autoclass:: openlp.plugins.songs.forms.songmaintenanceform.SongMaintenanceForm
:members:
:class:`TopicsForm`
^^^^^^^^^^^^^^^^^^^
.. autoclass:: openlp.plugins.songs.forms.topicsdialog.Ui_TopicsDialog
:members:
.. autoclass:: openlp.plugins.songs.forms.topicsform.TopicsForm
:members:
:mod:`lib` Submodule
--------------------
.. automodule:: openlp.plugins.songs.lib
:members:
:mod:`cclifileimport` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.cclifileimport
:members:
.. autoclass:: openlp.plugins.songs.lib.cclifileimport.CCLIFileImportError
:members:
:mod:`db` Submodule
^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.db
:members:
:mod:`ewimport` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.ewimport
:members:
.. autoclass:: openlp.plugins.songs.lib.ewimport.FieldDescEntry
:members:
:mod:`importer` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.importer
:members:
:mod:`mediaitem` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.mediaitem
:members:
.. autoclass:: openlp.plugins.songs.lib.mediaitem.SongListView
:members:
:mod:`olp1import` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.olp1import
:members:
:mod:`olpimport` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.olpimport
:members:
:mod:`oooimport` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.oooimport
:members:
:mod:`opensongimport` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.opensongimport
:members:
:mod:`sofimport` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.sofimport
:members:
:mod:`songbeamerimport` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.songbeamerimport
:members:
:mod:`songimport` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.songimport
:members:
:mod:`songstab` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.songstab
:members:
:mod:`wowimport` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.wowimport
:members:
:mod:`songxml` Submodule
^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.songxml
:members:
:mod:`xml` Submodule
^^^^^^^^^^^^^^^^^^^^
.. automodule:: openlp.plugins.songs.lib.xml
:members:

View File

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

View File

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

View File

@ -282,7 +282,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.LicenseDetailsPage.registerField(
u'license_copyright', self.CopyrightEdit)
self.LicenseDetailsPage.registerField(
u'license_permission', self.PermissionEdit)
u'license_permissions', self.PermissionsEdit)
def setDefaults(self):
settings = QtCore.QSettings()
@ -308,8 +308,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
QtCore.QVariant(self.VersionNameEdit.text()))
self.setField(u'license_copyright',
QtCore.QVariant(self.CopyrightEdit.text()))
self.setField(u'license_permission',
QtCore.QVariant(self.PermissionEdit.text()))
self.setField(u'license_permissions',
QtCore.QVariant(self.PermissionsEdit.text()))
self.onLocationComboBoxChanged(WebDownload.Crosswalk)
settings.endGroup()
@ -391,8 +391,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
bible_type = self.field(u'source_format').toInt()[0]
license_version = unicode(self.field(u'license_version').toString())
license_copyright = unicode(self.field(u'license_copyright').toString())
license_permission = \
unicode(self.field(u'license_permission').toString())
license_permissions = \
unicode(self.field(u'license_permissions').toString())
importer = None
if bible_type == BibleFormat.OSIS:
# Import an OSIS bible
@ -436,7 +436,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
)
if importer.do_import():
self.manager.save_meta_data(license_version, license_version,
license_copyright, license_permission)
license_copyright, license_permissions)
self.manager.reload_bibles()
self.ImportProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Finished import.'))

View File

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

View File

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

View File

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

View File

@ -32,6 +32,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \
ItemCapabilities, translate
from openlp.plugins.bibles.forms import ImportWizardForm
from openlp.plugins.bibles.lib.db import BibleDB
log = logging.getLogger(__name__)
@ -374,7 +375,7 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedSecondBibleComboBox.clear()
self.QuickSecondBibleComboBox.addItem(u'')
self.AdvancedSecondBibleComboBox.addItem(u'')
bibles = self.parent.manager.get_bibles()
bibles = self.parent.manager.get_bibles().keys()
# load bibles into the combo boxes
first = True
for bible in bibles:
@ -497,6 +498,7 @@ class BibleMediaItem(MediaManagerItem):
def onAdvancedSearchButton(self):
log.debug(u'Advanced Search Button pressed')
self.AdvancedSearchButton.setEnabled(False)
bible = unicode(self.AdvancedVersionComboBox.currentText())
dual_bible = unicode(self.AdvancedSecondBibleComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText())
@ -529,16 +531,30 @@ class BibleMediaItem(MediaManagerItem):
self.displayResults(bible, dual_bible)
else:
self.displayResults(bible, dual_bible)
self.AdvancedSearchButton.setEnabled(True)
def onQuickSearchButton(self):
log.debug(u'Quick Search Button pressed')
self.QuickSearchButton.setEnabled(False)
bible = unicode(self.QuickVersionComboBox.currentText())
dual_bible = unicode(self.QuickSecondBibleComboBox.currentText())
text = unicode(self.QuickSearchEdit.text())
self.search_results = self.parent.manager.get_verses(bible, text)
if dual_bible:
self.dual_search_results = self.parent.manager.get_verses(
dual_bible, text)
if self.QuickSearchComboBox.currentIndex() == 0:
# We are doing a 'Verse Search'.
self.search_results = self.parent.manager.get_verses(bible, text)
if dual_bible and self.search_results:
self.dual_search_results = self.parent.manager.get_verses(
dual_bible, text)
else:
# We are doing a ' Text Search'.
bibles = self.parent.manager.get_bibles()
self.search_results = self.parent.manager.verse_search(bible, text)
if dual_bible and self.search_results:
text = []
for verse in self.search_results:
text.append((verse.book.name, verse.chapter, verse.verse,
verse.verse))
self.dual_search_results = bibles[dual_bible].get_verses(text)
if self.ClearQuickSearchComboBox.currentIndex() == 0:
self.listView.clear()
if self.listView.count() != 0 and self.search_results:
@ -558,6 +574,7 @@ class BibleMediaItem(MediaManagerItem):
self.displayResults(bible, dual_bible)
elif self.search_results:
self.displayResults(bible, dual_bible)
self.QuickSearchButton.setEnabled(True)
def displayResults(self, bible, dual_bible=u''):
"""
@ -566,16 +583,16 @@ class BibleMediaItem(MediaManagerItem):
"""
version = self.parent.manager.get_meta_data(bible, u'Version')
copyright = self.parent.manager.get_meta_data(bible, u'Copyright')
permission = self.parent.manager.get_meta_data(bible, u'Permissions')
permissions = self.parent.manager.get_meta_data(bible, u'Permissions')
if dual_bible:
dual_version = self.parent.manager.get_meta_data(dual_bible,
u'Version')
dual_copyright = self.parent.manager.get_meta_data(dual_bible,
u'Copyright')
dual_permission = self.parent.manager.get_meta_data(dual_bible,
dual_permissions = self.parent.manager.get_meta_data(dual_bible,
u'Permissions')
if not dual_permission:
dual_permission = u''
if not dual_permissions:
dual_permissions = u''
# We count the number of rows which are maybe already present.
start_count = self.listView.count()
for count, verse in enumerate(self.search_results):
@ -587,12 +604,12 @@ class BibleMediaItem(MediaManagerItem):
'bible': QtCore.QVariant(bible),
'version': QtCore.QVariant(version.value),
'copyright': QtCore.QVariant(copyright.value),
'permission': QtCore.QVariant(permission.value),
'permissions': QtCore.QVariant(permissions.value),
'text': QtCore.QVariant(verse.text),
'dual_bible': QtCore.QVariant(dual_bible),
'dual_version': QtCore.QVariant(dual_version.value),
'dual_copyright': QtCore.QVariant(dual_copyright.value),
'dual_permission': QtCore.QVariant(dual_permission.value),
'dual_permissions': QtCore.QVariant(dual_permissions.value),
'dual_text': QtCore.QVariant(
self.dual_search_results[count].text)
}
@ -607,12 +624,12 @@ class BibleMediaItem(MediaManagerItem):
'bible': QtCore.QVariant(bible),
'version': QtCore.QVariant(version.value),
'copyright': QtCore.QVariant(copyright.value),
'permission': QtCore.QVariant(permission.value),
'permissions': QtCore.QVariant(permissions.value),
'text': QtCore.QVariant(verse.text),
'dual_bible': QtCore.QVariant(u''),
'dual_version': QtCore.QVariant(u''),
'dual_copyright': QtCore.QVariant(u''),
'dual_permission': QtCore.QVariant(u''),
'dual_permissions': QtCore.QVariant(u''),
'dual_text': QtCore.QVariant(u'')
}
bible_text = u' %s %d:%d (%s)' % (verse.book.name,
@ -658,20 +675,20 @@ class BibleMediaItem(MediaManagerItem):
bible = self._decodeQtObject(bitem, 'bible')
version = self._decodeQtObject(bitem, 'version')
copyright = self._decodeQtObject(bitem, 'copyright')
permission = self._decodeQtObject(bitem, 'permission')
permissions = self._decodeQtObject(bitem, 'permissions')
text = self._decodeQtObject(bitem, 'text')
dual_bible = self._decodeQtObject(bitem, 'dual_bible')
dual_version = self._decodeQtObject(bitem, 'dual_version')
dual_copyright = self._decodeQtObject(bitem, 'dual_copyright')
dual_permission = self._decodeQtObject(bitem, 'dual_permission')
dual_permissions = self._decodeQtObject(bitem, 'dual_permissions')
dual_text = self._decodeQtObject(bitem, 'dual_text')
verse_text = self.formatVerse(old_chapter, chapter, verse)
footer = u'%s (%s %s %s)' % (book, version, copyright, permission)
footer = u'%s (%s %s %s)' % (book, version, copyright, permissions)
if footer not in raw_footer:
raw_footer.append(footer)
if dual_bible:
footer = u'%s (%s %s %s)' % (book, dual_version, dual_copyright,
dual_permission)
dual_permissions)
if footer not in raw_footer:
raw_footer.append(footer)
bible_text = u'%s %s\n\n%s %s' % (verse_text, text, verse_text,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -38,9 +38,9 @@ class CCLIFileImportError(Exception):
class CCLIFileImport(SongImport):
"""
The :class:`CCLIFileImport` class provides OpenLP with the
ability to import CCLI SongSelect song files in both .txt and
.usr formats. See http://www.ccli.com
The :class:`CCLIFileImport` class provides OpenLP with the ability to
import CCLI SongSelect song files in both .txt and .usr formats.
See http://www.ccli.com/ for more details.
"""
def __init__(self, manager, **kwargs):
@ -49,6 +49,7 @@ class CCLIFileImport(SongImport):
``manager``
The song manager for the running OpenLP installation.
``filenames``
The files to be imported.
"""
@ -97,7 +98,7 @@ class CCLIFileImport(SongImport):
def do_import_usr_file(self, textList):
"""
The :method:`do_import_usr_file` method provides OpenLP
The :func:`do_import_usr_file` method provides OpenLP
with the ability to import CCLI SongSelect songs in
*USR* file format
@ -105,6 +106,7 @@ class CCLIFileImport(SongImport):
An array of strings containing the usr file content.
**SongSelect .usr file format**
``[File]``
USR file format first line
``Type=``
@ -140,6 +142,7 @@ class CCLIFileImport(SongImport):
Contains the songs various lyrics in order as shown by the
*Fields* description
e.g. *Words=Above all powers....* [/n = CR, /n/t = CRLF]
"""
log.debug(u'USR file text: %s', textList)
lyrics = []
@ -191,48 +194,32 @@ class CCLIFileImport(SongImport):
def do_import_txt_file(self, textList):
"""
The :method:`do_import_txt_file` method provides OpenLP
The :func:`do_import_txt_file` method provides OpenLP
with the ability to import CCLI SongSelect songs in
*TXT* file format
``textList``
An array of strings containing the txt file content.
**SongSelect .txt file format**
SongSelect .txt file format::
``Song Title``
Contains the song title
<Empty line>
``Title of following verse/chorus and number``
e.g. Verse 1, Chorus 1
``Verse/Chorus lyrics``
<Empty line>
<Empty line>
``Title of next verse/chorus (repeats)``
``Verse/Chorus lyrics``
<Empty line>
<Empty line>
``Song CCLI Number``
e.g. CCLI Number (e.g.CCLI-Liednummer: 2672885)
``Song Copyright``
e.g. © 1999 Integrity's Hosanna! Music | LenSongs Publishing
``Song Authors``
e.g. Lenny LeBlanc | Paul Baloche
``Licencing info``
e.g. For use solely with the SongSelect Terms of Use.
Song Title # Contains the song title
<Empty line>
Verse type and number # e.g. Verse 1, Chorus 1
Verse lyrics
<Empty line>
<Empty line>
Verse type and number (repeats)
Verse lyrics
<Empty line>
<Empty line>
Song CCLI number # e.g. CCLI Number (e.g.CCLI-Liednummer: 2672885)
Song copyright # e.g. © 1999 Integrity's Hosanna! Music | LenSongs Publishing
Song authors # e.g. Lenny LeBlanc | Paul Baloche
Licencing info # e.g. For use solely with the SongSelect Terms of Use.
All rights Reserved. www.ccli.com
``CCLI Licence number of user``
e.g. CCL-Liedlizenznummer: 14 / CCLI License No. 14
CCLI Licence number of user # e.g. CCL-Liedlizenznummer: 14 / CCLI License No. 14
"""
log.debug(u'TXT file text: %s', textList)
self.set_defaults()

View File

@ -282,11 +282,9 @@ class Song(object):
def get_author_list(self, asOneString = True):
"""Return the list of authors as a string
asOneString
True -- string:
'John Newton, A Parker'
False -- list of strings
['John Newton', u'A Parker']
``asOneString``
If ``True``, returns 'John Newton, A Parker'. If ``False``, returns
[u'John Newton', u'A Parker']
"""
if asOneString:
res = self._assure_string(self.author_list)
@ -297,7 +295,8 @@ class Song(object):
def set_author_list(self, author_list):
"""Set the author_list
author_list -- a string or list of strings
``author_list``
a string or list of strings
"""
if author_list is None:
self.author_list = None
@ -307,11 +306,9 @@ class Song(object):
def get_category_array(self, asOneString = True):
"""Return the list of categories as a string
asOneString
True -- string:
'Hymn, Gospel'
False -- list of strings
['Hymn', u'Gospel']
``asOneString``
If ``True``, returns 'Hymn, Gospel'. If ``False``, returns
[u'Hymn', u'Gospel']
"""
if asOneString:
res = self._assure_string(self.category_array)
@ -381,6 +378,7 @@ class Song(object):
properties
slideNumber -- 1 .. numberOfSlides
Returns a list as:
[theme_name (string),
title (string),

View File

@ -24,7 +24,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`wowimport` module provides the functionality for importing Words of
The :mod:`wowimport` module provides the functionality for importing Words of
Worship songs into the OpenLP database.
"""
import os
@ -38,19 +38,18 @@ log = logging.getLogger(__name__)
class WowImport(SongImport):
"""
The :class:`WowImport` class provides the ability to import song files from
The :class:`WowImport` class provides the ability to import song files from
Words of Worship.
Words Of Worship Song File Format
`````````````````````````````````
**Words Of Worship Song File Format:**
The Words Of Worship song file format is as follows:
* The song title is the file name minus the extension.
* The song has a header, a number of blocks, followed by footer containing
the author and the copyright.
* The song has a header, a number of blocks, followed by footer containing
the author and the copyright.
* A block can be a verse, chorus or bridge.
File Header:
Bytes are counted from one, i.e. the first byte is byte 1. These bytes,
up to the 56 byte, can change but no real meaning has been found. The
@ -65,29 +64,29 @@ class WowImport(SongImport):
Each block ends with 4 bytes, the first of which defines what type of
block it is, and the rest which are null bytes:
* ``NUL`` (\x00) - Verse
* ``SOH`` (\x01) - Chorus
* ``STX`` (\x02) - Bridge
* ``NUL`` (0x00) - Verse
* ``SOH`` (0x01) - Chorus
* ``STX`` (0x02) - Bridge
Blocks are seperated by two bytes. The first byte is ``SOH`` (\x01),
and the second byte is ```` (\x80).
Blocks are seperated by two bytes. The first byte is 0x01, and the
second byte is 0x80.
Lines:
Each line starts with a byte which specifies how long that line is,
the line text, and ends with a null byte.
Footer:
The footer follows on after the last block, the first byte specifies
the length of the author text, followed by the author text, if
this byte is null, then there is no author text. The byte after the
author text specifies the length of the copyright text, followed
by the copyright text.
The footer follows on after the last block, the first byte specifies
the length of the author text, followed by the author text, if
this byte is null, then there is no author text. The byte after the
author text specifies the length of the copyright text, followed
by the copyright text.
The file is ended with four null bytes.
Valid extensions for a Words of Worship song file are:
* .wsg
* .wow-song
"""
@ -111,7 +110,7 @@ class WowImport(SongImport):
"""
Recieve a single file, or a list of files to import.
"""
if isinstance(self.import_source, list):
self.import_wizard.importProgressBar.setMaximum(
len(self.import_source))
@ -127,14 +126,14 @@ class WowImport(SongImport):
if self.songData.read(19) != u'WoW File\nSong Words':
continue
# Seek to byte which stores number of blocks in the song
self.songData.seek(56)
self.songData.seek(56)
self.no_of_blocks = ord(self.songData.read(1))
# Seek to the beging of the first block
self.songData.seek(82)
self.songData.seek(82)
for block in range(self.no_of_blocks):
self.lines_to_read = ord(self.songData.read(1))
# Skip 3 nulls to the beginnig of the 1st line
self.songData.seek(3, os.SEEK_CUR)
self.songData.seek(3, os.SEEK_CUR)
self.block_text = u''
while self.lines_to_read:
self.length_of_line = ord(self.songData.read(1))
@ -148,7 +147,7 @@ class WowImport(SongImport):
self.block_type = BLOCK_TYPES[ord(self.songData.read(1))]
# Skip 3 nulls at the end of the block
self.songData.seek(3, os.SEEK_CUR)
# Blocks are seperated by 2 bytes, skip them, but not if
# Blocks are seperated by 2 bytes, skip them, but not if
# this is the last block!
if (block + 1) < self.no_of_blocks:
self.songData.seek(2, os.SEEK_CUR)
@ -170,4 +169,4 @@ class WowImport(SongImport):
self.import_wizard.incrementProgressBar(
"Importing %s" % (self.file_name))
return True

View File

@ -18,20 +18,48 @@
<normaloff>:/icon/openlp.org-icon-32.bmp</normaloff>:/icon/openlp.org-icon-32.bmp</iconset>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="TitleLabel">
<widget class="QLabel" name="ThemeLabel">
<property name="text">
<string>Title:</string>
<string>Theme:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="TitleEdit"/>
<widget class="QComboBox" name="ThemeComboBox">
<property name="toolTip">
<string extracomment="Select custom theme for slide"/>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="CreditLabel">
<property name="text">
<string>Credits:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="CreditEdit"/>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="toolTip">
<string extracomment="Edit dialog"/>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
@ -44,16 +72,42 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="UpButton">
<widget class="QPushButton" name="AddButton">
<property name="toolTip">
<string extracomment="Move slide up 1"/>
<string extracomment="Adds a new slide at bottom"/>
</property>
<property name="text">
<string/>
<string>Add New</string>
</property>
<property name="icon">
<iconset resource="../images/openlp-2.qrc">
<normaloff>:/services/service_up.png</normaloff>:/services/service_up.png</iconset>
</widget>
</item>
<item>
<widget class="QPushButton" name="EditButton">
<property name="toolTip">
<string extracomment="Edit selected slide"/>
</property>
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="EditAllButton">
<property name="toolTip">
<string extracomment="Edit all slides"/>
</property>
<property name="text">
<string>Edit All</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="DeleteButton">
<property name="toolTip">
<string extracomment="Delete selected slide"/>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
@ -70,6 +124,20 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="UpButton">
<property name="toolTip">
<string extracomment="Move slide up 1"/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../images/openlp-2.qrc">
<normaloff>:/services/service_up.png</normaloff>:/services/service_up.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="DownButton">
<property name="toolTip">
@ -88,166 +156,26 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QWidget" name="EditWidget" native="true">
<layout class="QHBoxLayout" name="EditLayout_3">
<property name="spacing">
<number>8</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QTextEdit" name="VerseTextEdit"/>
</item>
<item>
<widget class="QWidget" name="ButtonWidge" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="AddButton">
<property name="toolTip">
<string extracomment="Adds a new slide at bottom"/>
</property>
<property name="text">
<string>Add New</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="EditButton">
<property name="toolTip">
<string extracomment="Edit selected slide"/>
</property>
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="EditAllButton">
<property name="toolTip">
<string extracomment="Edit all slides"/>
</property>
<property name="text">
<string>Edit All</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="SaveButton">
<property name="toolTip">
<string extracomment="Replace edited slide"/>
</property>
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="DeleteButton">
<property name="toolTip">
<string extracomment="Delete selected slide"/>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ClearButton">
<property name="toolTip">
<string extracomment="Clear selection"/>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="SplitButton">
<property name="toolTip">
<string extracomment="Add new slide split"/>
</property>
<property name="text">
<string>Split Slide</string>
</property>
</widget>
</item>
<item>
<spacer name="ButtonSpacer">
<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>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="ThemeLabel">
<widget class="QLabel" name="TitleLabel">
<property name="text">
<string>Theme:</string>
<string>Title:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="ThemeComboBox">
<property name="toolTip">
<string extracomment="Select custom theme for slide"/>
</property>
</widget>
<widget class="QLineEdit" name="TitleEdit"/>
</item>
</layout>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="CreditLabel">
<property name="text">
<string>Credits:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="CreditEdit"/>
</item>
</layout>
</item>
<item row="5" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="toolTip">
<string extracomment="Edit dialog"/>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>TitleEdit</tabstop>
<tabstop>VerseTextEdit</tabstop>
<tabstop>AddButton</tabstop>
<tabstop>VerseListView</tabstop>
<tabstop>EditButton</tabstop>
<tabstop>EditAllButton</tabstop>
<tabstop>SaveButton</tabstop>
<tabstop>DeleteButton</tabstop>
<tabstop>CreditEdit</tabstop>
<tabstop>UpButton</tabstop>
<tabstop>DownButton</tabstop>
<tabstop>ThemeComboBox</tabstop>
</tabstops>
<resources>

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>customSlideEditDialog</class>
<widget class="QDialog" name="customSlideEditDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>474</width>
<height>442</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>8</x>
<y>407</y>
<width>458</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
</property>
</widget>
<widget class="QTextEdit" name="VerseTextEdit">
<property name="geometry">
<rect>
<x>8</x>
<y>8</y>
<width>458</width>
<height>349</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="SplitButton">
<property name="geometry">
<rect>
<x>380</x>
<y>370</y>
<width>85</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string extracomment="Add new slide split"/>
</property>
<property name="text">
<string>Split Slide</string>
</property>
</widget>
</widget>
<resources>
<include location="../images/openlp-2.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>customSlideEditDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>customSlideEditDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -27,6 +27,7 @@ DefaultDirName={pf}\{#AppName}
DefaultGroupName={#AppVerName}
AllowNoIcons=true
LicenseFile=LICENSE.txt
OutputDir=..\..\dist
OutputBaseFilename=OpenLP-{#RealVersion}-setup
Compression=lzma
SolidCompression=true

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

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

View File

@ -0,0 +1,611 @@
W: no module named openlp.core.lib.build_html (top-level import by openlp.core.ui.maindisplay)
W: no module named mx (top-level import by sqlite.main)
W: no module named ctypes.create_string_buffer (delayed import by urllib)
W: no module named openlp.core.ui.ServiceNoteForm (top-level import by openlp.core.ui.servicemanager)
W: no module named openlp.core.lib.MediaManagerItem (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.core.ui.mainwindow)
W: no module named email.Iterators (delayed import by email.message)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.custom.lib.mediaitem)
W: no module named sqlalchemy.sql.join (top-level import by sqlalchemy)
W: no module named java (conditional import by xml.sax._exceptions)
W: no module named openlp.plugins.images.lib.ImageMediaItem (top-level import by openlp.plugins.images.imageplugin)
W: no module named sqlalchemy.SMALLINT (top-level import by sqlalchemy.databases.sybase)
W: no module named sqlalchemy.engine.create_engine (top-level import by sqlalchemy)
W: no module named sqlalchemy.sql.asc (top-level import by sqlalchemy)
W: no module named openlp.plugins.bibles.lib.BiblesTab (top-level import by openlp.plugins.bibles.bibleplugin)
W: no module named PyQt4._qt (top-level import by PyQt4.QtCore)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.alerts.lib.alertstab)
W: no module named sqlalchemy.Column (top-level import by openlp.plugins.custom.lib.db)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.songusage.songusageplugin)
W: no module named openlp.plugins.alerts.lib.AlertsManager (top-level import by openlp.plugins.alerts.alertsplugin)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.ui.generaltab)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.alerts.forms.alertdialog)
W: no module named openlp.core.lib.check_item_selected (top-level import by openlp.plugins.custom.lib.mediaitem)
W: no module named sqlalchemy.orm.MapperExtension (top-level import by sqlalchemy.orm.scoping)
W: no module named pyodbc (delayed import by sqlalchemy.databases.access)
W: no module named openlp.core.lib.expand_tags (top-level import by openlp.core.lib.renderer)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.ui.servicemanager)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.dynamic)
W: no module named ctypes._SimpleCData (top-level import by ctypes.wintypes)
W: no module named openlp.core.lib.SettingsTab (top-level import by openlp.core.ui.generaltab)
W: no module named simplejson (conditional import by openlp.plugins.remotes.lib.httpserver)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.alerts.forms.alertdialog)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.collections)
W: no module named openlp.core.lib.resize_image (top-level import by openlp.core.lib.serviceitem)
W: no module named openlp.plugins.songs.lib.SongXMLParser (top-level import by openlp.plugins.songs.forms.editsongform)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.bibles.bibleplugin)
W: no module named xml.dom.XMLNS_NAMESPACE (top-level import by xml.dom.minidom)
W: no module named openlp.plugins.songs.lib.VerseType (top-level import by openlp.plugins.songs.lib.songimport)
W: no module named openlp.plugins.songs.lib.SongXMLBuilder (top-level import by openlp.plugins.songs.forms.editsongform)
W: no module named openlp.core.ui.GeneralTab (top-level import by openlp.core.ui.settingsform)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named openlp.core.lib.BaseListWithDnD (top-level import by openlp.plugins.presentations.lib.mediaitem)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.presentations.presentationplugin)
W: no module named informixdb (delayed import by sqlalchemy.databases.informix)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.plugins.custom.customplugin)
W: no module named cjkcodecs (top-level import by BeautifulSoup)
W: no module named readline (delayed, conditional import by cmd)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.songs.lib.songimport)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.plugins.media.mediaplugin)
W: no module named openlp.core.lib.ThemeXML (top-level import by openlp.core.ui.amendthemeform)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.bibles.lib.manager)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.custom.lib.mediaitem)
W: no module named openlp.core.lib.ServiceItem (top-level import by openlp.core.ui.maindisplay)
W: no module named openlp.plugins.songs.forms.EditVerseForm (top-level import by openlp.plugins.songs.forms.editsongform)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.lib.ewimport)
W: no module named openlp.core.lib.SettingsTab (top-level import by openlp.plugins.songs.lib.songstab)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.ui.HideMode (top-level import by openlp.core.ui.maindisplay)
W: no module named sqlalchemy.Column (top-level import by sqlalchemy.databases.sybase)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.core.ui.servicemanager)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.slidecontroller)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.songs.forms.songimportform)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.presentations.lib.mediaitem)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.aboutdialog)
W: no module named sqlalchemy.sql.insert (top-level import by sqlalchemy)
W: no module named openlp.core.lib.str_to_bool (top-level import by openlp.core.ui.thememanager)
W: no module named sqlalchemy.MetaData (top-level import by sqlalchemy.databases.sybase)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.bibles.lib.biblestab)
W: no module named openlp.plugins.bibles.lib.BibleManager (top-level import by openlp.plugins.bibles.bibleplugin)
W: no module named openlp.core.ui.SlideController (top-level import by openlp.core.ui.mainwindow)
W: no module named MacOS (delayed import by platform)
W: no module named openlp.core.lib.ThemeXML (top-level import by openlp.core.ui.thememanager)
W: no module named cx_Oracle (delayed import by sqlalchemy.databases.oracle)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.ui.slidecontroller)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.servicenotedialog)
W: no module named sqlalchemy.sql.except_ (top-level import by sqlalchemy)
W: no module named openlp.core.ui.AboutForm (top-level import by openlp.core.ui.mainwindow)
W: no module named EasyDialogs (conditional import by getpass)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.core.lib.mediamanageritem)
W: no module named sqlalchemy.orm.SessionExtension (top-level import by sqlalchemy.orm.session)
W: no module named sqlalchemy.orm.relation (top-level import by openlp.plugins.bibles.lib.db)
W: no module named openlp.plugins.songs.lib.VerseType (top-level import by openlp.plugins.songs.forms.editsongform)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.plugins.bibles.lib.http)
W: no module named sqlalchemy.sql.func (top-level import by sqlalchemy)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.utils.languagemanager)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.ui.mainwindow)
W: no module named uno (conditional import by openlp.plugins.songs.lib.oooimport)
W: no module named kinterbasdb (delayed import by sqlalchemy.databases.firebird)
W: no module named multiprocessing.RLock (top-level import by multiprocessing.sharedctypes)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.filerenameform)
W: no module named sqlalchemy.ForeignKey (top-level import by sqlalchemy.databases.mssql)
W: no module named openlp.core.lib.Renderer (top-level import by openlp.core.lib.rendermanager)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.songmaintenancedialog)
W: no module named openlp.core.lib.check_item_selected (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.core.lib.mediamanageritem)
W: no module named openlp.core.ui.FileRenameForm (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.songsplugin)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.bibles.bibleplugin)
W: no module named vms_lib (delayed, conditional import by platform)
W: no module named openlp.core.lib.resize_image (top-level import by openlp.core.ui.slidecontroller)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.alerts.lib.alertsmanager)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songusage.forms.songusagedetaildialog)
W: no module named openlp.plugins.remotes.lib.RemoteTab (top-level import by openlp.plugins.remotes.remoteplugin)
W: no module named openlp.core.ui.ServiceManager (top-level import by openlp.core.ui.mainwindow)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.plugins.songusage.forms.songusagedetailform)
W: no module named openlp.core.ui.SettingsForm (top-level import by openlp.core.ui.mainwindow)
W: no module named openlp.plugins.alerts.lib.AlertsTab (top-level import by openlp.plugins.alerts.alertsplugin)
W: no module named xdg (delayed, conditional import by openlp.core.utils)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.custom.customplugin)
W: no module named openlp.core.ui.AmendThemeForm (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.lib.ItemCapabilities (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named openlp.core.lib.ItemCapabilities (top-level import by openlp.plugins.custom.lib.mediaitem)
W: no module named posix (delayed, conditional import by iu)
W: no module named openlp.plugins.songs.lib.VerseType (top-level import by openlp.plugins.songs.forms.editversedialog)
W: no module named multiprocessing.dummy.Process (delayed import by __main__)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.presentations.presentationplugin)
W: no module named sqlalchemy.String (top-level import by sqlalchemy.databases.mssql)
W: no module named xml.dom.EMPTY_PREFIX (top-level import by xml.dom.expatbuilder)
W: no module named openlp.core.lib.MediaManagerItem (top-level import by openlp.plugins.custom.lib.mediaitem)
W: no module named openlp.core.lib.ServiceItem (top-level import by openlp.core.lib.mediamanageritem)
W: no module named openlp.core.lib.PluginManager (top-level import by openlp.core.ui.mainwindow)
W: no module named multiprocessing.current_process (top-level import by multiprocessing.reduction)
W: no module named openlp.core.lib.MediaManagerItem (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.songbookform)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.plugins.presentations.presentationplugin)
W: no module named xmltok (top-level import by pyexpat)
W: no module named openlp.plugins.bibles.lib.SearchResults (top-level import by openlp.plugins.bibles.lib.http)
W: no module named sqlalchemy.sql.delete (top-level import by sqlalchemy)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.songs.lib.oooimport)
W: no module named _emx_link (conditional import by os)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.core.ui.aboutdialog)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.bibles.forms.bibleimportwizard)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.core.lib.pluginmanager)
W: no module named openlp.plugins.songs.lib.SongsTab (top-level import by openlp.plugins.songs.songsplugin)
W: no module named sqlalchemy.CHAR (top-level import by sqlalchemy.databases.sybase)
W: no module named sqlalchemy.sql.collate (top-level import by sqlalchemy)
W: no module named sqlalchemy.sql.outparam (top-level import by sqlalchemy)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.core.lib.db)
W: no module named openlp.core.ui.PluginForm (top-level import by openlp.core.ui.mainwindow)
W: no module named gobject (top-level import by enchant.checker.GtkSpellCheckerDialog)
W: no module named openlp.core.utils.VersionThread (top-level import by __main__)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.topicsform)
W: no module named sqlalchemy.Integer (top-level import by sqlalchemy.databases.mssql)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.exceptiondialog)
W: no module named pwd (delayed, conditional import by distutils.util)
W: no module named uno (conditional import by openlp.plugins.presentations.lib.impresscontroller)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.utils)
W: no module named sqlalchemy.orm.class_mapper (top-level import by openlp.plugins.songs.lib.olpimport)
W: no module named sqlalchemy.orm.relation (top-level import by openlp.plugins.songs.lib.olpimport)
W: no module named readline (delayed import by pdb)
W: no module named openlp.core.ui.MainDisplay (top-level import by openlp.core.lib.rendermanager)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.media.lib.mediaitem)
W: no module named sqlalchemy.Table (top-level import by openlp.plugins.songusage.lib.db)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.alerts.alertsplugin)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.plugins.media.lib.mediaitem)
W: no module named openlp.core.lib.BaseListWithDnD (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.bibles.forms.importwizardform)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.remotes.remoteplugin)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.images.imageplugin)
W: no module named openlp.core.lib.SettingsTab (top-level import by openlp.plugins.alerts.lib.alertstab)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.editversedialog)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.songusage.songusageplugin)
W: no module named openlp.core.ui.HideMode (top-level import by openlp.core.ui.slidecontroller)
W: no module named sqlalchemy.sql.between (top-level import by sqlalchemy)
W: no module named xml.dom.EMPTY_PREFIX (top-level import by xml.dom.minidom)
W: no module named pysqlite2 (delayed import by sqlalchemy.databases.sqlite)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.custom.lib.customtab)
W: no module named gtk (top-level import by enchant.checker.GtkSpellCheckerDialog)
W: no module named xml.dom.EMPTY_NAMESPACE (top-level import by xml.dom.expatbuilder)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.remotes.lib.httpserver)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songusage.forms.songusagedeleteform)
W: no module named sqlalchemy.orm.scoped_session (top-level import by openlp.core.lib.db)
W: no module named openlp.core.lib.clean_tags (top-level import by openlp.core.lib.serviceitem)
W: no module named openlp.core.utils.get_filesystem_encoding (top-level import by openlp.core.ui.thememanager)
W: no module named xml.dom.EMPTY_NAMESPACE (top-level import by xml.dom.minidom)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.core.lib.toolbar)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.remotes.remoteplugin)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.attributes)
W: no module named sqlalchemy.ForeignKey (top-level import by sqlalchemy.databases.sybase)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.servicemanager)
W: no module named sqlalchemy.Column (top-level import by openlp.plugins.alerts.lib.db)
W: no module named openlp.core.lib.SettingsTab (top-level import by openlp.core.ui.advancedtab)
W: no module named AES (delayed, conditional import by archive)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.songs.forms.songmaintenanceform)
W: no module named openlp.core.lib.context_menu_separator (top-level import by openlp.core.lib.mediamanageritem)
W: no module named fcntl (top-level import by tempfile)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.thememanager)
W: no module named mx (top-level import by sqlalchemy.databases.mxODBC)
W: no module named sqlalchemy.sql.union (top-level import by sqlalchemy)
W: no module named openlp.plugins.songs.forms.TopicsForm (top-level import by openlp.plugins.songs.forms.songmaintenanceform)
W: no module named openlp.core.lib.ItemCapabilities (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named MacOS (delayed import by distutils.sysconfig)
W: no module named openlp.core.lib.SpellTextEdit (top-level import by openlp.plugins.custom.forms.editcustomdialog)
W: no module named ic (top-level import by webbrowser)
W: no module named com (conditional import by openlp.plugins.presentations.lib.impresscontroller)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.media.mediaplugin)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.custom.forms.editcustomform)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.lib.spelltextedit)
W: no module named openlp.core.lib.html_expands (top-level import by openlp.core.lib.spelltextedit)
W: no module named openlp.core.lib.context_menu_action (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named sqlalchemy.Column (top-level import by openlp.plugins.songs.lib.db)
W: no module named py2exe (delayed import by enchant.tests)
W: no module named openlp.plugins.songs.forms.AuthorsForm (top-level import by openlp.plugins.songs.forms.songmaintenanceform)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.authorsform)
W: no module named openlp.plugins.remotes.lib.HttpServer (top-level import by openlp.plugins.remotes.remoteplugin)
W: no module named sqlalchemy.Table (top-level import by openlp.plugins.bibles.lib.db)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.plugins.remotes.remoteplugin)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.filerenamedialog)
W: no module named openlp.core.lib.BaseListWithDnD (top-level import by openlp.plugins.media.lib.mediaitem)
W: no module named sapdb (delayed import by sqlalchemy.databases.maxdb)
W: no module named ctypes.cdll (delayed import by ctypes.util)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.presentations.lib.presentationtab)
W: no module named openlp.core.lib.MediaManagerItem (top-level import by openlp.plugins.presentations.lib.mediaitem)
W: no module named sqlalchemy.sql.text (top-level import by sqlalchemy)
W: no module named openlp.core.lib.image_to_byte (top-level import by openlp.core.lib.renderer)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.plugins.bibles.forms.importwizardform)
W: no module named openlp.core.lib.image_to_byte (top-level import by openlp.core.ui.maindisplay)
W: no module named iconv_codec (top-level import by BeautifulSoup)
W: no module named openlp.plugins.songs.forms.SongBookForm (top-level import by openlp.plugins.songs.forms.songmaintenanceform)
W: no module named sqlalchemy.sql.not_ (top-level import by sqlalchemy)
W: no module named multiprocessing.Pipe (top-level import by multiprocessing.queues)
W: no module named openlp.core.lib.check_item_selected (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songusage.forms.songusagedetailform)
W: no module named sqlalchemy.sql.subquery (top-level import by sqlalchemy)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.songs.songsplugin)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.editsongdialog)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.plugins.bibles.bibleplugin)
W: no module named openlp.plugins.songs.forms.SongMaintenanceForm (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named xmlparse (top-level import by pyexpat)
W: no module named sqlalchemy.sql.exists (top-level import by sqlalchemy)
W: no module named sqlalchemy.sql.and_ (top-level import by openlp.plugins.songs.forms.songmaintenanceform)
W: no module named multiprocessing.Process (top-level import by multiprocessing.pool)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.settingsdialog)
W: no module named sqlalchemy.exceptions (top-level import by openlp.core.lib.db)
W: no module named sqlalchemy.sql.outerjoin (top-level import by sqlalchemy)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.songs.forms.editsongdialog)
W: no module named openlp.plugins.custom.lib.CustomXMLParser (top-level import by openlp.plugins.custom.lib.mediaitem)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.custom.forms.editcustomdialog)
W: no module named sqlalchemy.Integer (top-level import by sqlalchemy.databases.sybase)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.properties)
W: no module named multiprocessing.current_process (top-level import by multiprocessing.managers)
W: no module named openlp.core.ui.SplashScreen (top-level import by __main__)
W: no module named multiprocessing.TimeoutError (top-level import by multiprocessing.dummy)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.plugins.songs.forms.songimportform)
W: no module named xml.dom.XMLNS_NAMESPACE (top-level import by xml.dom.expatbuilder)
W: no module named ctypes.c_int32 (delayed import by urllib)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.amendthemedialog)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.core.lib.serviceitem)
W: no module named openlp.core.utils.LanguageManager (top-level import by __main__)
W: no module named sqlalchemy.orm.object_mapper (top-level import by sqlalchemy.orm.properties)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.core.utils.languagemanager)
W: no module named sqlalchemy.sql.literal_column (top-level import by sqlalchemy)
W: no module named openlp.plugins.songs.lib.SongXMLParser (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named ctypes.c_char_p (delayed import by urllib)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.plugins.images.imageplugin)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.remotes.lib.remotetab)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.core.ui.mainwindow)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.bibles.lib.opensong)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.songimportform)
W: no module named sqlalchemy.sql.select (top-level import by sqlalchemy)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.songbookdialog)
W: no module named openlp.plugins.bibles.lib.BibleMediaItem (top-level import by openlp.plugins.bibles.bibleplugin)
W: no module named PyQt4._qt (top-level import by PyQt4.QtNetwork)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.plugins.songs.songsplugin)
W: no module named sqlalchemy.sql.case (top-level import by sqlalchemy)
W: no module named wx (top-level import by enchant.checker.wxSpellCheckerDialog)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.alerts.alertsplugin)
W: no module named com (conditional import by openlp.plugins.songs.lib.sofimport)
W: no module named PyQt4._qt (top-level import by PyQt4)
W: no module named SOCKS (top-level import by ftplib)
W: no module named openlp.plugins.songusage.forms.SongUsageDetailForm (top-level import by openlp.plugins.songusage.songusageplugin)
W: no module named sqlalchemy.sql.null (top-level import by sqlalchemy)
W: no module named sqlalchemy.MetaData (top-level import by openlp.core.lib.db)
W: no module named openlp.core.lib.ItemCapabilities (top-level import by openlp.core.ui.servicemanager)
W: no module named openlp.plugins.custom.forms.EditCustomForm (top-level import by openlp.plugins.custom.customplugin)
W: no module named org (delayed import by xml.sax)
W: no module named openlp.core.lib.SpellTextEdit (top-level import by openlp.plugins.songs.forms.editversedialog)
W: no module named sqlalchemy.orm.EXT_CONTINUE (top-level import by sqlalchemy.orm.scoping)
W: no module named openlp.core.lib.build_lyrics_outline_css (top-level import by openlp.core.lib.renderer)
W: no module named openlp.plugins.songs.lib.VerseType (top-level import by openlp.plugins.songs.forms.editverseform)
W: no module named com (conditional import by openlp.plugins.songs.lib.oooimport)
W: no module named openlp.core.lib.str_to_bool (top-level import by openlp.core.lib.theme)
W: no module named sqlalchemy.sql.literal (top-level import by sqlalchemy)
W: no module named termios (top-level import by getpass)
W: no module named openlp.core.lib.build_lyrics_format_css (top-level import by openlp.core.lib.renderer)
W: no module named ctypes.byref (delayed import by urllib)
W: no module named openlp.plugins.custom.lib.CustomTab (top-level import by openlp.plugins.custom.customplugin)
W: no module named openlp.core.lib.BaseListWithDnD (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named openlp.plugins.bibles.lib.parse_reference (top-level import by openlp.plugins.bibles.lib.manager)
W: no module named java (delayed import by platform)
W: no module named openlp.core.ui.ServiceItemEditForm (top-level import by openlp.core.ui.servicemanager)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.custom.customplugin)
W: no module named openlp.core.lib.ThemeLevel (top-level import by openlp.core.lib.rendermanager)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.bibles.lib.db)
W: no module named _xmlrpclib (top-level import by xmlrpclib)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.plugins.presentations.lib.mediaitem)
W: no module named openlp.plugins.media.lib.MediaMediaItem (top-level import by openlp.plugins.media.mediaplugin)
W: no module named openlp.plugins.custom.lib.CustomXMLBuilder (top-level import by openlp.plugins.custom.forms.editcustomform)
W: no module named rourl2path (conditional import by urllib)
W: no module named pwd (delayed import by webbrowser)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.ui.themestab)
W: no module named PyQt4._qt (top-level import by PyQt4.QtWebKit)
W: no module named sqlalchemy.orm.class_mapper (delayed, conditional import by sqlalchemy.orm.interfaces)
W: no module named PyQt4._qt (top-level import by PyQt4.phonon)
W: no module named openlp.core.ui.HideMode (top-level import by openlp.plugins.presentations.lib.messagelistener)
W: no module named openlp.plugins.songusage.forms.SongUsageDeleteForm (top-level import by openlp.plugins.songusage.songusageplugin)
W: no module named openlp.core.lib.context_menu_separator (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.media.lib.mediaitem)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.plugindialog)
W: no module named fcntl (conditional import by subprocess)
W: no module named openlp.core.lib.BaseListWithDnD (top-level import by openlp.plugins.bibles.lib.mediaitem)
W: no module named openlp.core.lib.PluginStatus (top-level import by openlp.core.lib.pluginmanager)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.songs.forms.editsongform)
W: no module named openlp.core.ui.ScreenList (top-level import by __main__)
W: no module named sqlalchemy.or_ (top-level import by openlp.plugins.bibles.lib.db)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.editsongform)
W: no module named openlp.plugins.songs.forms.ImportWizardForm (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named openlp.core.lib.check_item_selected (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.ui.ThemeManager (top-level import by openlp.core.ui.mainwindow)
W: no module named pyodbc (delayed, conditional import by sqlalchemy.databases.mssql)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.core.ui.servicemanager)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.lib.mediamanageritem)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.bibles.lib.biblestab)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songusage.songusageplugin)
W: no module named multiprocessing.active_children (top-level import by multiprocessing.managers)
W: no module named openlp.plugins.songs.forms.EditSongForm (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named email.Generator (delayed import by email.message)
W: no module named mx (delayed import by sqlalchemy.databases.mxODBC)
W: no module named sqlalchemy.sql.or_ (top-level import by sqlalchemy)
W: no module named sqlalchemy.Table (top-level import by openlp.plugins.custom.lib.db)
W: no module named sqlalchemy.Table (top-level import by sqlalchemy.databases.sybase)
W: no module named openlp.core.lib.get_text_file_string (top-level import by openlp.core.ui.thememanager)
W: no module named sqlalchemy.orm.object_session (top-level import by sqlalchemy.orm.scoping)
W: no module named openlp.core.lib.MediaManagerItem (top-level import by openlp.plugins.bibles.lib.mediaitem)
W: no module named sqlalchemy.Table (top-level import by sqlalchemy.databases.mssql)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.core.ui.mainwindow)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.bibles.forms.bibleimportwizard)
W: no module named openlp.core.lib.resize_image (top-level import by openlp.core.lib.renderer)
W: no module named pymssql (delayed import by sqlalchemy.databases.mssql)
W: no module named sqlalchemy.orm.sessionmaker (top-level import by openlp.plugins.songs.lib.olpimport)
W: no module named openlp.core.lib.context_menu_action (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.lib.expand_tags (top-level import by openlp.core.lib.serviceitem)
W: no module named gestalt (delayed import by platform)
W: no module named enchant.checker.SpellChecker (top-level import by enchant.checker.CmdLineChecker)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.themestab)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.lib.olp1import)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.presentations.lib.messagelistener)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.interfaces)
W: no module named sqlalchemy.orm.object_mapper (top-level import by sqlalchemy.orm.query)
W: no module named sqlalchemy.sql.distinct (top-level import by sqlalchemy)
W: no module named openlp.core.lib.context_menu_action (top-level import by openlp.plugins.media.lib.mediaitem)
W: no module named sqlalchemy.sql.extract (top-level import by sqlalchemy)
W: no module named sqlalchemy.Column (top-level import by openlp.plugins.bibles.lib.db)
W: no module named psycopg2 (delayed import by sqlalchemy.databases.postgres)
W: no module named enchant.checker.SpellChecker (delayed import by enchant.checker.GtkSpellCheckerDialog)
W: no module named clr (conditional import by adodbapi.adodbapi)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named openlp.plugins.custom.lib.CustomXMLParser (top-level import by openlp.plugins.custom.forms.editcustomform)
W: no module named openlp.core.theme.Theme (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.custom.forms.editcustomform)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.core.lib.settingsmanager)
W: no module named openlp.core.lib.Receiver (top-level import by __main__)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.plugins.bibles.lib.manager)
W: no module named org (top-level import by pickle)
W: no module named enchant.DictNotFoundError (top-level import by openlp.core.lib.spelltextedit)
W: no module named sqlalchemy.sql.except_all (top-level import by sqlalchemy)
W: no module named openlp.plugins.presentations.lib.PresentationTab (top-level import by openlp.plugins.presentations.presentationplugin)
W: no module named sqlalchemy.sql.cast (top-level import by sqlalchemy)
W: no module named sqlalchemy.orm.relation (top-level import by openlp.plugins.songs.lib.db)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.core.ui.settingsdialog)
W: no module named openlp.core.utils.LanguageManager (top-level import by openlp.core.ui.mainwindow)
W: no module named openlp.core.lib.ItemCapabilities (top-level import by openlp.plugins.media.lib.mediaitem)
W: no module named sqlalchemy.sql.intersect (top-level import by sqlalchemy)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.lib.songimport)
W: no module named sqlalchemy.orm.class_mapper (top-level import by sqlalchemy.orm.scoping)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.util)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.lib.opensongimport)
W: no module named openlp.core.lib.SettingsTab (top-level import by openlp.plugins.bibles.lib.biblestab)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.aboutform)
W: no module named openlp.plugins.custom.lib.CustomMediaItem (top-level import by openlp.plugins.custom.customplugin)
W: no module named sqlalchemy.orm.scoped_session (top-level import by openlp.plugins.songs.lib.olpimport)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.amendthemeform)
W: no module named sqlalchemy.engine.engine_from_config (top-level import by sqlalchemy)
W: no module named openlp.core.lib.SettingsTab (top-level import by openlp.core.ui.themestab)
W: no module named openlp.core.lib.OpenLPToolbar (top-level import by openlp.core.ui.servicemanager)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.ui.maindisplay)
W: no module named openlp.core.lib.PluginStatus (top-level import by openlp.core.ui.pluginform)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.bibles.lib.http)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.plugins.remotes.lib.httpserver)
W: no module named sqlalchemy.Table (top-level import by openlp.plugins.songs.lib.db)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.utils)
W: no module named openlp.core.lib.RenderManager (top-level import by openlp.core.ui.mainwindow)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.plugins.alerts.alertsplugin)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.lib.plugin)
W: no module named sqlalchemy.ForeignKey (top-level import by openlp.plugins.bibles.lib.db)
W: no module named openlp.plugins.songs.lib.SongMediaItem (top-level import by openlp.plugins.songs.songsplugin)
W: no module named sqlalchemy.Index (top-level import by openlp.plugins.songs.lib.db)
W: no module named multiprocessing.TimeoutError (top-level import by multiprocessing.pool)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.songusage.forms.songusagedetaildialog)
W: no module named enchant.DictWithPWL (delayed import by enchant.checker.tests)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.lib.songstab)
W: no module named openlp.core.ui.AdvancedTab (top-level import by openlp.core.ui.settingsform)
W: no module named MySQLdb (delayed import by sqlalchemy.databases.mysql)
W: no module named openlp.plugins.presentations.lib.PresentationMediaItem (top-level import by openlp.plugins.presentations.presentationplugin)
W: no module named openlp.plugins.alerts.forms.AlertForm (top-level import by openlp.plugins.alerts.alertsplugin)
W: no module named ctypes.c_int (delayed import by urllib)
W: no module named xml.dom.XML_NAMESPACE (delayed import by xml.dom.pulldom)
W: no module named ctypes.c_void_p (delayed import by urllib)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.plugins.bibles.lib.osis)
W: no module named sqlalchemy.create_engine (top-level import by openlp.core.lib.db)
W: no module named win32com.client._get_good_object_ (top-level import by win32com.client.util)
W: no module named openlp.core.ui.MainDisplay (top-level import by openlp.core.ui.slidecontroller)
W: no module named openlp.core.lib.resize_image (top-level import by openlp.plugins.presentations.lib.presentationcontroller)
W: no module named openlp.core.lib.SettingsTab (top-level import by openlp.plugins.remotes.lib.remotetab)
W: no module named openlp.core.ui.MediaDockManager (top-level import by openlp.core.ui.mainwindow)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.session)
W: no module named sqlalchemy.Column (top-level import by sqlalchemy.databases.mssql)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.songs.forms.editversedialog)
W: no module named multiprocessing.Process (top-level import by multiprocessing.managers)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.presentations.lib.presentationcontroller)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.lib.mediaitem)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.custom.forms.editcustomdialog)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.alerts.lib.alertsmanager)
W: no module named sgmlop (top-level import by xmlrpclib)
W: no module named MacOS (conditional import by py_compile)
W: no module named multiprocessing.cpu_count (top-level import by multiprocessing.dummy)
W: no module named _dummy_threading (top-level import by dummy_threading)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.mainwindow)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.songmaintenanceform)
W: no module named openlp.plugins.presentations.lib.PresentationController (top-level import by openlp.plugins.presentations.presentationplugin)
W: no module named openlp.core.lib.OpenLPToolbar (top-level import by openlp.core.lib.mediamanageritem)
W: no module named sqlalchemy.sql.union_all (top-level import by sqlalchemy)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.bibles.lib.opensong)
W: no module named openlp.core.lib.ItemCapabilities (top-level import by openlp.plugins.bibles.lib.mediaitem)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.bibles.lib.osis)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.ui.settingsform)
W: no module named enchant.tokenize.get_tokenizer (top-level import by enchant.checker)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.plugins.bibles.lib.manager)
W: no module named org (top-level import by copy)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.core.ui.servicemanager)
W: no module named sqlalchemy.MetaData (top-level import by openlp.plugins.songs.lib.olpimport)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.songs.forms.songmaintenancedialog)
W: no module named sqlalchemy.sql.select (top-level import by sqlalchemy.databases.mssql)
W: no module named openlp.core.lib.SettingsManager (top-level import by openlp.plugins.bibles.forms.importwizardform)
W: no module named multiprocessing.current_process (top-level import by multiprocessing.connection)
W: no module named sqlalchemy.orm.sessionmaker (top-level import by openlp.core.lib.db)
W: no module named sqlalchemy.sql.desc (top-level import by sqlalchemy)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songusage.forms.songusagedeletedialog)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.bibles.lib.mediaitem)
W: no module named ctypes.cdll (delayed import by urllib)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.lib)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.media.mediaplugin)
W: no module named openlp.core.lib.SettingsTab (top-level import by openlp.plugins.presentations.lib.presentationtab)
W: no module named MySQLdb (delayed, conditional import by sqlalchemy.databases.mysql)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.presentations.lib.mediaitem)
W: no module named openlp.core.lib.MediaManagerItem (top-level import by openlp.plugins.media.lib.mediaitem)
W: no module named sqlalchemy.orm.object_session (top-level import by sqlalchemy.orm.dynamic)
W: no module named sqlalchemy.sql.modifier (top-level import by sqlalchemy)
W: no module named _xmlplus (top-level import by xml)
W: no module named sqlalchemy.Column (top-level import by openlp.plugins.songusage.lib.db)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.advancedtab)
W: no module named sqlalchemy.sql.and_ (top-level import by sqlalchemy)
W: no module named sqlalchemy.MetaData (top-level import by sqlalchemy.databases.mssql)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.dependency)
W: no module named openlp.core.lib.ThemeLevel (top-level import by openlp.core.ui.themestab)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.presentations.lib.presentationtab)
W: no module named openlp.core.utils.get_images_filter (top-level import by openlp.core.ui.amendthemeform)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.plugins.presentations.presentationplugin)
W: no module named openlp.plugins.presentations.lib.MessageListener (top-level import by openlp.plugins.presentations.lib.mediaitem)
W: no module named openlp.plugins.bibles.forms.ImportWizardForm (top-level import by openlp.plugins.bibles.lib.mediaitem)
W: no module named openlp.core.utils.AppLocation (top-level import by __main__)
W: no module named sqlalchemy.ForeignKey (top-level import by openlp.plugins.songs.lib.db)
W: no module named openlp.core.lib.OpenLPToolbar (top-level import by openlp.core.ui.thememanager)
W: no module named ctypes.cdll (conditional import by openlp.plugins.presentations.lib.pptviewcontroller)
W: no module named pwd (delayed import by getpass)
W: no module named sqlalchemy.sql.and_ (top-level import by openlp.plugins.songusage.forms.songusagedetailform)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.core.ui.amendthemedialog)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.plugins.songs.forms.songimportwizard)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.serviceitemeditdialog)
W: no module named openlp.core.lib.resize_image (top-level import by openlp.core.ui.maindisplay)
W: no module named openlp.core.lib.BaseListWithDnD (top-level import by openlp.plugins.custom.lib.mediaitem)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.topicsdialog)
W: no module named PyQt4._qt (top-level import by PyQt4.QtGui)
W: no module named sqlalchemy.sql.update (top-level import by sqlalchemy)
W: no module named multiprocessing.current_process (delayed, conditional import by logging)
W: no module named multiprocessing.Pool (top-level import by multiprocessing.managers)
W: no module named sqlalchemy.create_engine (delayed, conditional import by sqlalchemy.schema)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.bibles.forms.importwizardform)
W: no module named openlp.core.lib.context_menu_action (top-level import by openlp.core.lib.mediamanageritem)
W: no module named posix (conditional import by os)
W: no module named sqlalchemy.sql.bindparam (top-level import by sqlalchemy)
W: no module named xml.dom.DOMImplementation (top-level import by xml.dom.domreg)
W: no module named openlp.core.utils.add_actions (top-level import by openlp.core.ui.mainwindow)
W: no module named sqlalchemy.create_engine (top-level import by openlp.plugins.songs.lib.olpimport)
W: no module named multiprocessing.cpu_count (top-level import by multiprocessing.pool)
W: no module named multiprocessing.AuthenticationError (top-level import by multiprocessing.connection)
W: no module named openlp.core.ui.ThemesTab (top-level import by openlp.core.ui.settingsform)
W: no module named openlp.core.lib.check_item_selected (top-level import by openlp.plugins.media.lib.mediaitem)
W: no module named sqlalchemy.orm.class_mapper (top-level import by openlp.plugins.bibles.lib.db)
W: no module named sqlalchemy.String (top-level import by sqlalchemy.databases.sybase)
W: no module named openlp.core.lib.context_menu_action (top-level import by openlp.core.ui.servicemanager)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named pwd (delayed, conditional import by posixpath)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.strategies)
W: no module named mx (top-level import by adodbapi.adodbapi)
W: no module named sqlalchemy.sql.alias (top-level import by sqlalchemy)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.authorsdialog)
W: no module named sqlalchemy.Table (top-level import by openlp.plugins.alerts.lib.db)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.bibles.lib.mediaitem)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.images.imageplugin)
W: no module named sqlalchemy.orm.mapperlib (delayed import by sqlalchemy.orm.util)
W: no module named openlp.core.lib.ServiceItem (top-level import by openlp.core.lib.rendermanager)
W: no module named openlp.core.lib.OpenLPDockWidget (top-level import by openlp.core.ui.mainwindow)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.songs.forms.songimportwizard)
W: no module named openlp.core.lib.Plugin (top-level import by openlp.plugins.songusage.songusageplugin)
W: no module named openlp.core.utils.AppLocation (top-level import by openlp.plugins.presentations.lib.presentationcontroller)
W: no module named openlp.core.lib.context_menu_action (top-level import by openlp.core.lib.spelltextedit)
W: no module named openlp.core.lib.build_icon (top-level import by openlp.core.ui.thememanager)
W: no module named openlp.core.lib.check_item_selected (top-level import by openlp.plugins.presentations.lib.mediaitem)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.pluginform)
W: no module named enchant.checker.SpellChecker (delayed import by enchant.checker.wxSpellCheckerDialog)
W: no module named sqlalchemy.DefaultClause (top-level import by sqlalchemy.databases.sqlite)
W: no module named openlp.core.lib.ServiceItem (top-level import by openlp.core.ui.servicemanager)
W: no module named openlp.core.lib.ItemCapabilities (top-level import by openlp.core.ui.slidecontroller)
W: no module named openlp.core.utils.get_images_filter (top-level import by openlp.plugins.images.lib.mediaitem)
W: no module named pyodbc (delayed import by sqlalchemy.databases.mssql)
W: no module named openlp.core.lib.OpenLPToolbar (top-level import by openlp.core.ui.slidecontroller)
W: no module named System (conditional import by adodbapi.adodbapi)
W: no module named openlp.core.lib.SettingsTab (top-level import by openlp.plugins.custom.lib.customtab)
W: no module named openlp.core.lib.Receiver (top-level import by openlp.plugins.bibles.lib.csvbible)
W: no module named openlp.core.lib.translate (top-level import by openlp.core.ui.generaltab)
W: no module named openlp.core.lib.ThemeLevel (top-level import by openlp.core.ui.servicemanager)
W: no module named sqlalchemy.exceptions (top-level import by sqlalchemy.orm.scoping)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.alerts.forms.alertform)
W: no module named mypyodbc (delayed import by sqlalchemy.databases.sybase)
W: no module named sqlalchemy.sql.intersect_all (top-level import by sqlalchemy)
W: no module named openlp.core.lib.translate (top-level import by openlp.plugins.presentations.lib.mediaitem)
W: __all__ is built strangely at line 0 - dummy_threading (C:\Python26\lib\dummy_threading.pyc)
W: delayed exec statement detected at line 0 - bdb (C:\Python26\lib\bdb.pyc)
W: delayed eval hack detected at line 0 - bdb (C:\Python26\lib\bdb.pyc)
W: delayed eval hack detected at line 0 - bdb (C:\Python26\lib\bdb.pyc)
W: delayed __import__ hack detected at line 0 - optparse (C:\Python26\lib\optparse.pyc)
W: delayed conditional __import__ hack detected at line 0 - pkg_resources (build/bdist.linux-i686/egg/pkg_resources.pyc)
W: delayed conditional exec statement detected at line 0 - pkg_resources (build/bdist.linux-i686/egg/pkg_resources.pyc)
W: delayed conditional __import__ hack detected at line 0 - pkg_resources (build/bdist.linux-i686/egg/pkg_resources.pyc)
W: delayed __import__ hack detected at line 0 - pkg_resources (build/bdist.linux-i686/egg/pkg_resources.pyc)
W: delayed conditional __import__ hack detected at line 0 - doctest (C:\Python26\lib\doctest.pyc)
W: delayed exec statement detected at line 0 - doctest (C:\Python26\lib\doctest.pyc)
W: delayed conditional __import__ hack detected at line 0 - doctest (C:\Python26\lib\doctest.pyc)
W: __all__ is built strangely at line 0 - sqlalchemy.orm.interfaces (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\orm\interfaces.pyc)
W: __all__ is built strangely at line 0 - tokenize (C:\Python26\lib\tokenize.pyc)
W: __all__ is built strangely at line 0 - sqlalchemy.engine (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\engine\__init__.pyc)
W: delayed __import__ hack detected at line 0 - pickle (C:\Python26\lib\pickle.pyc)
W: delayed __import__ hack detected at line 0 - pickle (C:\Python26\lib\pickle.pyc)
W: top-level conditional exec statement detected at line 0 - sqlalchemy.sql.util (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\sql\util.pyc)
W: top-level conditional exec statement detected at line 0 - sqlalchemy.sql.util (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\sql\util.pyc)
W: delayed conditional __import__ hack detected at line 0 - openlp.core.lib.pluginmanager (c:\Documents and Settings\raoul\My Documents\My Projects\openlp\movements\openlp\core\lib\pluginmanager.pyc)
W: delayed conditional exec statement detected at line 0 - multiprocessing.sharedctypes (C:\Python26\lib\multiprocessing\sharedctypes.pyc)
W: delayed __import__ hack detected at line 0 - encodings (C:\Python26\lib\encodings\__init__.pyc)
W: __all__ is built strangely at line 0 - sqlalchemy.databases.mysql (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\databases\mysql.pyc)
W: delayed exec statement detected at line 0 - sqlalchemy.orm.attributes (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\orm\attributes.pyc)
W: delayed conditional __import__ hack detected at line 0 - openlp.plugins.presentations.presentationplugin (c:\Documents and Settings\raoul\My Documents\My Projects\openlp\movements\openlp\plugins\presentations\presentationplugin.pyc)
W: delayed __import__ hack detected at line 0 - enchant.tokenize (C:\Python26\lib\site-packages\enchant\tokenize\__init__.pyc)
W: __all__ is built strangely at line 0 - multiprocessing (C:\Python26\lib\multiprocessing\__init__.pyc)
W: __all__ is built strangely at line 0 - dis (C:\Python26\lib\dis.pyc)
W: __all__ is built strangely at line 0 - sqlalchemy.databases (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\databases\__init__.pyc)
W: delayed __import__ hack detected at line 0 - win32com.server.policy (C:\Python26\lib\site-packages\win32com\server\policy.pyc)
W: __all__ is built strangely at line 0 - sqlalchemy.orm.mapper (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\orm\mapper.pyc)
W: top-level exec statement detected at line 0 - hashlib (C:\Python26\lib\hashlib.pyc)
W: top-level conditional exec statement detected at line 0 - hashlib (C:\Python26\lib\hashlib.pyc)
W: delayed conditional eval hack detected at line 0 - warnings (C:\Python26\lib\warnings.pyc)
W: delayed conditional __import__ hack detected at line 0 - warnings (C:\Python26\lib\warnings.pyc)
W: delayed exec statement detected at line 0 - cgi (C:\Python26\lib\cgi.pyc)
W: delayed __import__ hack detected at line 0 - email (C:\Python26\lib\email\__init__.pyc)
W: __all__ is built strangely at line 0 - sqlalchemy.orm (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\orm\__init__.pyc)
W: delayed __import__ hack detected at line 0 - ctypes (C:\Python26\lib\ctypes\__init__.pyc)
W: delayed __import__ hack detected at line 0 - ctypes (C:\Python26\lib\ctypes\__init__.pyc)
W: delayed conditional __import__ hack detected at line 0 - xml.dom.domreg (C:\Python26\lib\xml\dom\domreg.pyc)
W: delayed exec statement detected at line 0 - pdb (C:\Python26\lib\pdb.pyc)
W: delayed conditional eval hack detected at line 0 - pdb (C:\Python26\lib\pdb.pyc)
W: delayed eval hack detected at line 0 - pdb (C:\Python26\lib\pdb.pyc)
W: delayed conditional eval hack detected at line 0 - pdb (C:\Python26\lib\pdb.pyc)
W: delayed eval hack detected at line 0 - pdb (C:\Python26\lib\pdb.pyc)
W: delayed conditional __import__ hack detected at line 0 - unittest (C:\Python26\lib\unittest.pyc)
W: delayed conditional __import__ hack detected at line 0 - unittest (C:\Python26\lib\unittest.pyc)
W: delayed conditional __import__ hack detected at line 0 - pkgutil (C:\Python26\lib\pkgutil.pyc)
W: delayed conditional __import__ hack detected at line 0 - pkgutil (C:\Python26\lib\pkgutil.pyc)
W: __all__ is built strangely at line 0 - sqlalchemy.orm.properties (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\orm\properties.pyc)
W: delayed conditional exec statement detected at line 0 - iu (c:\Documents and Settings\raoul\My Documents\My Projects\pyinstaller\iu.pyc)
W: delayed conditional exec statement detected at line 0 - iu (c:\Documents and Settings\raoul\My Documents\My Projects\pyinstaller\iu.pyc)
W: __all__ is built strangely at line 0 - sqlalchemy.sql (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\sql\__init__.pyc)
W: __all__ is built strangely at line 0 - collections (C:\Python26\lib\collections.pyc)
W: delayed exec statement detected at line 0 - collections (C:\Python26\lib\collections.pyc)
W: delayed __import__ hack detected at line 0 - sqlalchemy.engine.url (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\engine\url.pyc)
W: delayed exec statement detected at line 0 - multiprocessing.managers (C:\Python26\lib\multiprocessing\managers.pyc)
W: delayed exec statement detected at line 0 - socket (C:\Python26\lib\socket.pyc)
W: delayed conditional __import__ hack detected at line 0 - win32com.client.gencache (C:\Python26\lib\site-packages\win32com\client\gencache.pyc)
W: delayed __import__ hack detected at line 0 - win32com.client.gencache (C:\Python26\lib\site-packages\win32com\client\gencache.pyc)
W: delayed eval hack detected at line 0 - os (C:\Python26\lib\os.pyc)
W: __all__ is built strangely at line 0 - __future__ (C:\Python26\lib\__future__.pyc)
W: delayed __import__ hack detected at line 0 - win32com.client.makepy (C:\Python26\lib\site-packages\win32com\client\makepy.pyc)
W: delayed exec statement detected at line 0 - win32com.client.dynamic (C:\Python26\lib\site-packages\win32com\client\dynamic.pyc)
W: __all__ is built strangely at line 0 - sqlalchemy (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\__init__.pyc)
W: delayed __import__ hack detected at line 0 - xml.sax (C:\Python26\lib\xml\sax\__init__.pyc)
W: delayed eval hack detected at line 0 - gettext (C:\Python26\lib\gettext.pyc)
W: delayed eval hack detected at line 0 - sqlalchemy.util (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\util.pyc)
W: delayed exec statement detected at line 0 - sqlalchemy.util (C:\Python26\lib\site-packages\sqlalchemy-0.5.8-py2.6.egg\sqlalchemy\util.pyc)

View File

@ -63,6 +63,7 @@ IGNORED_PATHS = [u'scripts']
IGNORED_FILES = [u'setup.py']
verbose_mode = False
quiet_mode = False
class Command(object):
"""
@ -128,6 +129,20 @@ class CommandStack(object):
results.append(str((item[u'command'], )))
return u'[%s]' % u', '.join(results)
def print_quiet(text, linefeed=True):
"""
This method checks to see if we are in quiet mode, and if not prints
``text`` out.
``text``
The text to print.
"""
global quiet_mode
if not quiet_mode:
if linefeed:
print text
else:
print text,
def print_verbose(text):
"""
@ -137,8 +152,8 @@ def print_verbose(text):
``text``
The text to print.
"""
global verbose_mode
if verbose_mode:
global verbose_mode, quiet_mode
if not quiet_mode and verbose_mode:
print u' %s' % text
def run(command):
@ -155,7 +170,6 @@ def run(command):
print_verbose(u'ReadyRead: %s' % QtCore.QString(process.readAll()))
print_verbose(u'Error(s):\n%s' % process.readAllStandardError())
print_verbose(u'Output:\n%s' % process.readAllStandardOutput())
print u' Done.'
def update_export_at_pootle(source_filename):
"""
@ -170,7 +184,7 @@ def update_export_at_pootle(source_filename):
print_verbose(u'Accessing: %s' % (REVIEW_URL))
page = urllib.urlopen(REVIEW_URL)
page.close()
def download_file(source_filename, dest_filename):
"""
@ -194,7 +208,7 @@ def download_translations():
"""
This method downloads the translation files from the Pootle server.
"""
print 'Download translation files from Pootle'
print_quiet(u'Download translation files from Pootle')
page = urllib.urlopen(SERVER_URL)
soup = BeautifulSoup(page)
languages = soup.findAll(text=re.compile(r'.*\.ts'))
@ -205,14 +219,14 @@ def download_translations():
language_file)
print_verbose(u'Get Translation File: %s' % filename)
download_file(language_file, filename)
print u' Done.'
print_quiet(u' Done.')
def prepare_project():
"""
This method creates the project file needed to update the translation files
and compile them into .qm files.
"""
print u'Generating the openlp.pro file'
print_quiet(u'Generating the openlp.pro file')
lines = []
start_dir = os.path.abspath(u'..')
start_dir = start_dir + os.sep
@ -251,10 +265,10 @@ def prepare_project():
file = open(os.path.join(start_dir, u'openlp.pro'), u'w')
file.write(u'\n'.join(lines).encode('utf8'))
file.close()
print u' Done.'
print_quiet(u' Done.')
def update_translations():
print u'Update the translation files'
print_quiet(u'Update the translation files')
if not os.path.exists(os.path.join(os.path.abspath(u'..'), u'openlp.pro')):
print u'You have no generated a project file yet, please run this ' + \
u'script with the -p option.'
@ -265,7 +279,7 @@ def update_translations():
os.chdir(os.path.abspath(u'scripts'))
def generate_binaries():
print u'Generate the related *.qm files'
print_quiet(u'Generate the related *.qm files')
if not os.path.exists(os.path.join(os.path.abspath(u'..'), u'openlp.pro')):
print u'You have not generated a project file yet, please run this ' + \
u'script with the -p option. It is also recommended that you ' + \
@ -283,8 +297,9 @@ def generate_binaries():
src_list = os.listdir(src_path)
for file in src_list:
if re.search('.qm$', file):
copy(os.path.join(src_path, u'%s' % file),
copy(os.path.join(src_path, u'%s' % file),
os.path.join(dest_path, u'%s' % file))
print_quiet(u' Done.')
def create_translation(language):
@ -294,17 +309,17 @@ def create_translation(language):
``language``
The language file to create.
"""
print "Create new Translation File"
print_quiet(u'Create new Translation File')
if not language.endswith(u'.ts'):
language += u'.ts'
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n', language)
download_file(u'en.ts', filename)
print u' ** Please Note **'
print u' In order to get this file into OpenLP and onto the Pootle ' + \
u'translation server you will need to subscribe to the OpenLP' + \
u'Translators mailing list, and request that your language file ' + \
u'be added to the project.'
print u' Done'
print_quiet(u' ** Please Note **')
print_quiet(u' In order to get this file into OpenLP and onto the '
u'Pootle translation server you will need to subscribe to the '
u'OpenLP Translators mailing list, and request that your language '
u'file be added to the project.')
print_quiet(u' Done.')
def process_stack(command_stack):
"""
@ -315,9 +330,9 @@ def process_stack(command_stack):
The command stack to process.
"""
if command_stack:
print u'Processing %d commands...' % len(command_stack)
print_quiet(u'Processing %d commands...' % len(command_stack))
for command in command_stack:
print u'%d.' % (command_stack.current_index),
print_quiet(u'%d.' % (command_stack.current_index), False)
if command == Command.Download:
download_translations()
elif command == Command.Prepare:
@ -329,12 +344,12 @@ def process_stack(command_stack):
elif command == Command.Create:
arguments = command_stack.arguments()
create_translation(*arguments)
print u'Finished processing commands.'
print_quiet(u'Finished processing commands.')
else:
print u'No commands to process.'
print_quiet(u'No commands to process.')
def main():
global verbose_mode
global verbose_mode, quiet_mode
# Set up command line options.
usage = u'%prog [options]\nOptions are parsed in the order they are ' + \
u'listed below. If no options are given, "-dpug" will be used.\n\n' + \
@ -352,6 +367,8 @@ def main():
help='compile .ts files into .qm files')
parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
help='show extra information while processing translations')
parser.add_option('-q', '--quiet', dest='quiet', action='store_true',
help='suppress all output other than errors')
(options, args) = parser.parse_args()
# Create and populate the command stack
command_stack = CommandStack()
@ -366,6 +383,7 @@ def main():
if options.generate:
command_stack.append(Command.Generate)
verbose_mode = options.verbose
quiet_mode = options.quiet
if not command_stack:
command_stack.append(Command.Download)
command_stack.append(Command.Prepare)

View File

@ -87,20 +87,33 @@ windows-builder.py
"""
import os
import sys
from shutil import copy
from subprocess import Popen, PIPE
python_exe = sys.executable
innosetup_exe = os.path.join(os.getenv(u'PROGRAMFILES'), 'Inno Setup 5',
u'ISCC.exe')
# Base paths
script_path = os.path.split(os.path.abspath(__file__))[0]
branch_path = os.path.abspath(os.path.join(script_path, u'..'))
site_packages = os.path.join(os.path.split(python_exe)[0], u'Lib',
u'site-packages')
# Files and executables
pyi_build = os.path.abspath(os.path.join(branch_path, u'..', u'..',
u'pyinstaller', u'Build.py'))
lrelease_exe = os.path.join(site_packages, u'PyQt4', u'bin', u'lrelease.exe')
i18n_utils = os.path.join(script_path, u'translation_utils.py')
# Paths
source_path = os.path.join(branch_path, u'openlp')
i18n_path = os.path.join(branch_path, u'resources', u'i18n')
winres_path = os.path.join(branch_path, u'resources', u'windows')
build_path = os.path.join(branch_path, u'build', u'pyi.win32', u'OpenLP')
dist_path = os.path.join(branch_path, u'dist', u'OpenLP')
pyinstaller_path = os.path.abspath(os.path.join(branch_path, u'..', u'..', u'pyinstaller'))
innosetup_path = os.path.join(os.getenv(u'PROGRAMFILES'), 'Inno Setup 5')
iss_path = os.path.join(branch_path, u'resources', u'innosetup')
lrelease_path = u'C:\\Python26\\Lib\\site-packages\\PyQt4\\bin\\lrelease.exe'
enchant_path = u'C:\\Python26\\Lib\\site-packages\\enchant'
enchant_path = os.path.join(site_packages, u'enchant')
def clean_build_directories():
#if not os.path.exists(build_path)
@ -117,11 +130,13 @@ def clean_build_directories():
def run_pyinstaller():
print u'Running PyInstaller...'
os.chdir(branch_path)
pyinstaller = Popen((u'python', os.path.join(pyinstaller_path, u'Build.py'),
u'-y', u'OpenLP.spec'))
pyinstaller = Popen((python_exe, pyi_build, u'-y', u'-o', build_path,
os.path.join(winres_path, u'OpenLP.spec')), stdout=PIPE)
output, error = pyinstaller.communicate()
code = pyinstaller.wait()
if code != 0:
raise Exception(u'Error running PyInstaller Build.py')
print output
raise Exception(u'Error running PyInstaller')
def write_version_file():
print u'Writing version file...'
@ -155,7 +170,7 @@ def copy_enchant():
for root, dirs, files in os.walk(source):
for filename in files:
if not filename.endswith(u'.pyc') and not filename.endswith(u'.pyo'):
dest_path = os.path.join(dest, root[len(source)+1:])
dest_path = os.path.join(dest, root[len(source) + 1:])
if not os.path.exists(dest_path):
os.makedirs(dest_path)
copy(os.path.join(root, filename),
@ -176,16 +191,18 @@ def copy_plugins():
def copy_windows_files():
print u'Copying extra files for Windows...'
copy(os.path.join(iss_path, u'OpenLP.ico'), os.path.join(dist_path, u'OpenLP.ico'))
copy(os.path.join(iss_path, u'LICENSE.txt'), os.path.join(dist_path, u'LICENSE.txt'))
copy(os.path.join(winres_path, u'OpenLP.ico'),
os.path.join(dist_path, u'OpenLP.ico'))
copy(os.path.join(winres_path, u'LICENSE.txt'),
os.path.join(dist_path, u'LICENSE.txt'))
def update_translations():
print u'Updating translations...'
os.chdir(script_path)
translation_utils = Popen(u'python translation_utils.py -dpu')
translation_utils = Popen((python_exe, i18n_utils, u'-qdpu'))
code = translation_utils.wait()
if code != 0:
print u'Error running translation_utils.py'
raise Exception(u'Error running translation_utils.py')
def compile_translations():
print u'Compiling translations...'
@ -197,19 +214,17 @@ def compile_translations():
source_path = os.path.join(i18n_path, file)
dest_path = os.path.join(dist_path, u'i18n',
file.replace(u'.ts', u'.qm'))
lconvert = Popen(u'"%s" "%s" -qm "%s"' % (lrelease_path, \
source_path, dest_path))
lconvert = Popen((lrelease_exe, u'-compress', u'-silent',
source_path, u'-qm', dest_path))
code = lconvert.wait()
if code != 0:
print 'Error running lconvert on %s' % source_path
raise Exception('Error running lconvert on %s' % source_path)
def run_innosetup():
print u'Running Inno Setup...'
os.chdir(iss_path)
run_command = u'"%s" "%s"' % (os.path.join(innosetup_path, u'ISCC.exe'),
os.path.join(iss_path, u'OpenLP-2.0.iss'))
print run_command
innosetup = Popen(run_command)
os.chdir(winres_path)
innosetup = Popen((innosetup_exe,
os.path.join(winres_path, u'OpenLP-2.0.iss'), u'/q'))
code = innosetup.wait()
if code != 0:
raise Exception(u'Error running Inno Setup')
@ -221,9 +236,9 @@ def main():
print "Branch path:", branch_path
print "Source path:", source_path
print "\"dist\" path:", dist_path
print "PyInstaller path:", pyinstaller_path
print "PyInstaller:", pyi_build
print "Inno Setup path:", innosetup_path
print "ISS file path:", iss_path
print "Windows resources:", winres_path
#clean_build_directories()
run_pyinstaller()
write_version_file()