diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py
index ad762e326..1245988b4 100644
--- a/openlp/core/lib/serviceitem.py
+++ b/openlp/core/lib/serviceitem.py
@@ -35,7 +35,7 @@ import logging
import os
import uuid
-from openlp.core.lib import build_icon, clean_tags, expand_tags
+from openlp.core.lib import build_icon, clean_tags, expand_tags, translate
from openlp.core.lib.ui import UiStrings
log = logging.getLogger(__name__)
@@ -352,6 +352,9 @@ class ServiceItem(object):
Updates the _uuid with the value from the original one
The _uuid is unique for a given service item but this allows one to
replace an original version.
+
+ ``other``
+ The service item to be merged with
"""
self._uuid = other._uuid
self.notes = other.notes
@@ -447,10 +450,12 @@ class ServiceItem(object):
start = None
end = None
if self.start_time != 0:
- start = UiStrings().StartTimeCode % \
+ start = unicode(translate('OpenLP.ServiceItem',
+ 'Start: %s')) % \
unicode(datetime.timedelta(seconds=self.start_time))
if self.media_length != 0:
- end = UiStrings().LengthTime % \
+ end = unicode(translate('OpenLP.ServiceItem',
+ 'Length: %s')) % \
unicode(datetime.timedelta(seconds=self.media_length))
if not start and not end:
return None
@@ -459,5 +464,16 @@ class ServiceItem(object):
elif not start and end:
return end
else:
- return u'%s : %s' % (start, end)
+ return u'%s
%s' % (start, end)
+
+ def update_theme(self, theme):
+ """
+ updates the theme in the service item
+
+ ``theme``
+ The new theme to be replaced in the service item
+ """
+ self.theme = theme
+ self._new_item()
+ self.render()
diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py
index 1d7f8ae3f..756df36c3 100644
--- a/openlp/core/lib/ui.py
+++ b/openlp/core/lib/ui.py
@@ -83,7 +83,6 @@ class UiStrings(object):
self.Image = translate('OpenLP.Ui', 'Image')
self.Import = translate('OpenLP.Ui', 'Import')
self.LayoutStyle = translate('OpenLP.Ui', 'Layout style:')
- self.LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
self.Live = translate('OpenLP.Ui', 'Live')
self.LiveBGError = translate('OpenLP.Ui', 'Live Background Error')
self.LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar')
@@ -126,8 +125,10 @@ class UiStrings(object):
self.SplitToolTip = translate('OpenLP.Ui', 'Split a slide into two '
'only if it does not fit on the screen as one slide.')
self.StartTimeCode = unicode(translate('OpenLP.Ui', 'Start %s'))
- self.StopPlaySlidesInLoop = translate('OpenLP.Ui','Stop Play Slides in Loop')
- self.StopPlaySlidesToEnd = translate('OpenLP.Ui','Stop Play Slides to End')
+ self.StopPlaySlidesInLoop = translate('OpenLP.Ui',
+ 'Stop Play Slides in Loop')
+ self.StopPlaySlidesToEnd = translate('OpenLP.Ui',
+ 'Stop Play Slides to End')
self.Theme = translate('OpenLP.Ui', 'Theme', 'Singular')
self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural')
self.Tools = translate('OpenLP.Ui', 'Tools')
diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py
index e850ef335..c88508672 100644
--- a/openlp/core/ui/mainwindow.py
+++ b/openlp/core/ui/mainwindow.py
@@ -276,31 +276,22 @@ class Ui_MainWindow(object):
u'settingsConfigureItem', u':/system/system_settings.png',
category=UiStrings().Settings)
action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu)
- self.helpDocumentationItem = icon_action(mainWindow,
- u'helpDocumentationItem', u':/system/system_help_contents.png',
- category=None)#UiStrings().Help)
- self.helpDocumentationItem.setEnabled(False)
- self.helpAboutItem = shortcut_action(mainWindow, u'helpAboutItem',
- [QtGui.QKeySequence(u'Ctrl+F1')], self.onHelpAboutItemClicked,
+ self.aboutItem = shortcut_action(mainWindow, u'aboutItem',
+ [QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked,
u':/system/system_about.png', category=UiStrings().Help)
if os.name == u'nt':
self.localHelpFile = os.path.join(
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
- self.helpLocalHelpItem = shortcut_action(
- mainWindow, u'helpLocalHelpItem', [QtGui.QKeySequence(u'F1')],
- self.onHelpLocalHelpClicked, u':/system/system_about.png',
- category=UiStrings().Help)
- self.helpOnlineHelpItem = shortcut_action(
- mainWindow, u'helpOnlineHelpItem', [QtGui.QKeySequence(u'Alt+F1')],
- self.onHelpOnlineHelpClicked, u':/system/system_online_help.png',
- category=UiStrings().Help)
- else:
- self.helpOnlineHelpItem = shortcut_action(
- mainWindow, u'helpOnlineHelpItem', [QtGui.QKeySequence(u'F1')],
- self.onHelpOnlineHelpClicked, u':/system/system_online_help.png',
- category=UiStrings().Help)
- self.helpWebSiteItem = base_action(
- mainWindow, u'helpWebSiteItem', category=UiStrings().Help)
+ self.offlineHelpItem = shortcut_action(
+ mainWindow, u'offlineHelpItem', [QtGui.QKeySequence(u'F1')],
+ self.onOfflineHelpClicked,
+ u':/system/system_help_contents.png', category=UiStrings().Help)
+ self.onlineHelpItem = shortcut_action(
+ mainWindow, u'onlineHelpItem',
+ [QtGui.QKeySequence(u'Alt+F1')], self.onOnlineHelpClicked,
+ u':/system/system_online_help.png', category=UiStrings().Help)
+ self.webSiteItem = base_action(
+ mainWindow, u'webSiteItem', category=UiStrings().Help)
add_actions(self.fileImportMenu,
(self.importThemeItem, self.importLanguageItem))
add_actions(self.fileExportMenu,
@@ -333,14 +324,13 @@ class Ui_MainWindow(object):
add_actions(self.toolsMenu, (self.toolsAddToolItem, None))
add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None))
add_actions(self.toolsMenu, [self.updateThemeImages])
- add_actions(self.helpMenu, (self.helpDocumentationItem, None))
if os.name == u'nt':
- add_actions(self.helpMenu, (self.helpLocalHelpItem,
- self.helpOnlineHelpItem, None, self.helpWebSiteItem,
- self.helpAboutItem))
+ add_actions(self.helpMenu, (self.offlineHelpItem,
+ self.onlineHelpItem, None, self.webSiteItem,
+ self.aboutItem))
else:
- add_actions(self.helpMenu, (self.helpOnlineHelpItem, None,
- self.helpWebSiteItem, self.helpAboutItem))
+ add_actions(self.helpMenu, (self.onlineHelpItem, None,
+ self.webSiteItem, self.aboutItem))
add_actions(self.menuBar, (self.fileMenu.menuAction(),
self.viewMenu.menuAction(), self.toolsMenu.menuAction(),
self.settingsMenu.menuAction(), self.helpMenu.menuAction()))
@@ -355,7 +345,6 @@ class Ui_MainWindow(object):
self.toolsAddToolItem.setVisible(False)
self.importLanguageItem.setVisible(False)
self.exportLanguageItem.setVisible(False)
- self.helpDocumentationItem.setVisible(False)
self.setLockPanel(panelLocked)
def retranslateUi(self, mainWindow):
@@ -456,17 +445,15 @@ class Ui_MainWindow(object):
'&Plugin List'))
self.settingsPluginListItem.setStatusTip(
translate('OpenLP.MainWindow', 'List the Plugins'))
- self.helpDocumentationItem.setText(
- translate('OpenLP.MainWindow', '&User Guide'))
- self.helpAboutItem.setText(translate('OpenLP.MainWindow', '&About'))
- self.helpAboutItem.setStatusTip(
+ self.aboutItem.setText(translate('OpenLP.MainWindow', '&About'))
+ self.aboutItem.setStatusTip(
translate('OpenLP.MainWindow', 'More information about OpenLP'))
if os.name == u'nt':
- self.helpLocalHelpItem.setText(
- translate('OpenLP.MainWindow', '&Help'))
- self.helpOnlineHelpItem.setText(
+ self.offlineHelpItem.setText(
+ translate('OpenLP.MainWindow', '&User Guide'))
+ self.onlineHelpItem.setText(
translate('OpenLP.MainWindow', '&Online Help'))
- self.helpWebSiteItem.setText(
+ self.webSiteItem.setText(
translate('OpenLP.MainWindow', '&Web Site'))
for item in self.languageGroup.actions():
item.setText(item.objectName())
@@ -555,7 +542,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
QtCore.QObject.connect(self.themeManagerDock,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.viewThemeManagerItem.setChecked)
- QtCore.QObject.connect(self.helpWebSiteItem,
+ QtCore.QObject.connect(self.webSiteItem,
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
QtCore.QObject.connect(self.toolsOpenDataFolder,
QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked)
@@ -762,20 +749,20 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
import webbrowser
webbrowser.open_new(u'http://openlp.org/')
- def onHelpLocalHelpClicked(self):
+ def onOfflineHelpClicked(self):
"""
Load the local OpenLP help file
"""
os.startfile(self.localHelpFile)
- def onHelpOnlineHelpClicked(self):
+ def onOnlineHelpClicked(self):
"""
Load the online OpenLP manual
"""
import webbrowser
webbrowser.open_new(u'http://manual.openlp.org/')
- def onHelpAboutItemClicked(self):
+ def onAboutItemClicked(self):
"""
Show the About form
"""
diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py
index 6a34dc1e6..f6c069525 100644
--- a/openlp/core/ui/servicemanager.py
+++ b/openlp/core/ui/servicemanager.py
@@ -956,7 +956,19 @@ class ServiceManager(QtGui.QWidget):
treewidgetitem.setIcon(0,
build_icon(u':/general/general_delete.png'))
treewidgetitem.setText(0, serviceitem.get_display_title())
- treewidgetitem.setToolTip(0, serviceitem.notes)
+ tips = []
+ if serviceitem.theme and serviceitem.theme != -1:
+ tips.append(u'%s: %s' %
+ (unicode(translate('OpenLP.ServiceManager', 'Slide theme')),
+ serviceitem.theme))
+ if serviceitem.notes:
+ tips.append(u'%s: %s' %
+ (unicode(translate('OpenLP.ServiceManager', 'Notes')),
+ unicode(serviceitem.notes)))
+ if item[u'service_item'] \
+ .is_capable(ItemCapabilities.AllowsVariableStartTime):
+ tips.append(item[u'service_item'].get_media_time())
+ treewidgetitem.setToolTip(0, u'
'.join(tips))
treewidgetitem.setData(0, QtCore.Qt.UserRole,
QtCore.QVariant(item[u'order']))
treewidgetitem.setSelected(item[u'selected'])
@@ -966,11 +978,6 @@ class ServiceManager(QtGui.QWidget):
text = frame[u'title'].replace(u'\n', u' ')
child.setText(0, text[:40])
child.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(count))
- if item[u'service_item'] \
- .is_capable(ItemCapabilities.AllowsVariableStartTime):
- tip = item[u'service_item'].get_media_time()
- if tip:
- child.setToolTip(0, tip)
if serviceItem == itemcount:
if item[u'expanded'] and serviceItemChild == count:
self.serviceManagerList.setCurrentItem(child)
@@ -1338,7 +1345,7 @@ class ServiceManager(QtGui.QWidget):
if not theme:
theme = None
item = self.findServiceItem()[0]
- self.serviceItems[item][u'service_item'].theme = theme
+ self.serviceItems[item][u'service_item'].update_theme(theme)
self.regenerateServiceItems()
def _getParentItemData(self, item):
diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py
index fbd29f820..9f9541ba4 100644
--- a/openlp/core/ui/slidecontroller.py
+++ b/openlp/core/ui/slidecontroller.py
@@ -28,6 +28,7 @@
import logging
import os
import time
+import copy
from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
@@ -598,7 +599,8 @@ class SlideController(QtGui.QWidget):
log.debug(u'processManagerItem live = %s' % self.isLive)
self.onStopLoop()
old_item = self.serviceItem
- self.serviceItem = serviceItem
+ # take a copy not a link to the servicemeanager copy.
+ self.serviceItem = copy.copy(serviceItem)
if old_item and self.isLive and old_item.is_capable(
ItemCapabilities.ProvidesOwnDisplay):
self._resetBlank()
diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py
index 7304b5196..575295f37 100644
--- a/openlp/plugins/songusage/songusageplugin.py
+++ b/openlp/plugins/songusage/songusageplugin.py
@@ -48,8 +48,10 @@ class SongUsagePlugin(Plugin):
Plugin.__init__(self, u'SongUsage', plugin_helpers)
self.weight = -4
self.icon = build_icon(u':/plugins/plugin_songusage.png')
+ self.activeIcon = build_icon(u':/songusage/song_usage_active.png')
+ self.inactiveIcon = build_icon(u':/songusage/song_usage_inactive.png')
self.manager = None
- self.songusageActive = False
+ self.songUsageActive = False
def addToolsMenuItem(self, tools_menu):
"""
@@ -84,17 +86,29 @@ class SongUsagePlugin(Plugin):
self.songUsageStatus.setText(translate(
'SongUsagePlugin', 'Toggle Tracking'))
self.songUsageStatus.setStatusTip(translate('SongUsagePlugin',
- 'Toggle the tracking of song usage.'))
- #Add Menus together
+ 'Toggle the tracking of song usage.'))
+ # Add Menus together
self.toolsMenu.addAction(self.songUsageMenu.menuAction())
self.songUsageMenu.addAction(self.songUsageStatus)
self.songUsageMenu.addSeparator()
self.songUsageMenu.addAction(self.songUsageDelete)
self.songUsageMenu.addAction(self.songUsageReport)
+ self.songUsageActiveButton = QtGui.QToolButton(
+ self.formparent.statusBar)
+ self.songUsageActiveButton.setCheckable(True)
+ self.songUsageActiveButton.setStatusTip(translate('SongUsagePlugin',
+ 'Toggle the tracking of song usage.'))
+ self.songUsageActiveButton.setObjectName(u'songUsageActiveButton')
+ self.formparent.statusBar.insertPermanentWidget(1,
+ self.songUsageActiveButton)
+ self.songUsageActiveButton.hide()
# Signals and slots
QtCore.QObject.connect(self.songUsageStatus,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.songUsageStatus.setChecked)
+ QtCore.QObject.connect(self.songUsageActiveButton,
+ QtCore.SIGNAL(u'toggled(bool)'),
+ self.toggleSongUsageState)
QtCore.QObject.connect(self.songUsageDelete,
QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete)
QtCore.QObject.connect(self.songUsageReport,
@@ -107,23 +121,25 @@ class SongUsagePlugin(Plugin):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_live_started'),
self.onReceiveSongUsage)
- self.SongUsageActive = QtCore.QSettings().value(
+ self.songUsageActive = QtCore.QSettings().value(
self.settingsSection + u'/active',
QtCore.QVariant(False)).toBool()
- self.songUsageStatus.setChecked(self.SongUsageActive)
+ # Set the button and checkbox state
+ self.setButtonState()
action_list = ActionList.get_instance()
+ action_list.add_action(self.songUsageStatus,
+ translate('SongUsagePlugin', 'Song Usage'))
action_list.add_action(self.songUsageDelete,
translate('SongUsagePlugin', 'Song Usage'))
action_list.add_action(self.songUsageReport,
translate('SongUsagePlugin', 'Song Usage'))
- action_list.add_action(self.songUsageStatus,
- translate('SongUsagePlugin', 'Song Usage'))
if self.manager is None:
self.manager = Manager(u'songusage', init_schema)
self.songUsageDeleteForm = SongUsageDeleteForm(self.manager,
self.formparent)
self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent)
self.songUsageMenu.menuAction().setVisible(True)
+ self.songUsageActiveButton.show()
def finalise(self):
"""
@@ -134,26 +150,55 @@ class SongUsagePlugin(Plugin):
Plugin.finalise(self)
self.songUsageMenu.menuAction().setVisible(False)
action_list = ActionList.get_instance()
+ action_list.remove_action(self.songUsageStatus,
+ translate('SongUsagePlugin', 'Song Usage'))
action_list.remove_action(self.songUsageDelete,
translate('SongUsagePlugin', 'Song Usage'))
action_list.remove_action(self.songUsageReport,
translate('SongUsagePlugin', 'Song Usage'))
- action_list.remove_action(self.songUsageStatus,
- translate('SongUsagePlugin', 'Song Usage'))
- #stop any events being processed
- self.SongUsageActive = False
+ self.songUsageActiveButton.hide()
+ # stop any events being processed
+ self.songUsageActive = False
def toggleSongUsageState(self):
- self.SongUsageActive = not self.SongUsageActive
+ """
+ Manage the state of the audit collection and amend
+ the UI when necessary,
+ """
+ self.songUsageActive = not self.songUsageActive
QtCore.QSettings().setValue(self.settingsSection + u'/active',
- QtCore.QVariant(self.SongUsageActive))
+ QtCore.QVariant(self.songUsageActive))
+ self.setButtonState()
+
+ def setButtonState(self):
+ """
+ Keep buttons inline. Turn of signals to stop dead loop but we need the
+ button and check box set correctly.
+ """
+ self.songUsageActiveButton.blockSignals(True)
+ self.songUsageStatus.blockSignals(True)
+ if self.songUsageActive:
+ self.songUsageActiveButton.setIcon(self.activeIcon)
+ self.songUsageStatus.setChecked(True)
+ self.songUsageActiveButton.setChecked(True)
+ self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin',
+ 'Song usage tracking is active.'))
+ else:
+ self.songUsageActiveButton.setIcon(self.inactiveIcon)
+ self.songUsageStatus.setChecked(False)
+ self.songUsageActiveButton.setChecked(False)
+ self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin',
+ 'Song usage tracking is inactive.'))
+ self.songUsageActiveButton.blockSignals(False)
+ self.songUsageStatus.blockSignals(False)
+
def onReceiveSongUsage(self, item):
"""
Song Usage for live song from SlideController
"""
audit = item[0].audit
- if self.SongUsageActive and audit:
+ if self.songUsageActive and audit:
song_usage_item = SongUsageItem()
song_usage_item.usagedate = datetime.today()
song_usage_item.usagetime = datetime.now().time()
diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc
index 4dca475f4..fff1f75b8 100644
--- a/resources/images/openlp-2.qrc
+++ b/resources/images/openlp-2.qrc
@@ -138,6 +138,10 @@
messagebox_info.png
messagebox_warning.png
+
+ song_usage_active.png
+ song_usage_inactive.png
+
tools_add.png
tools_alert.png
diff --git a/resources/images/song_usage_active.png b/resources/images/song_usage_active.png
new file mode 100644
index 000000000..1221e1310
Binary files /dev/null and b/resources/images/song_usage_active.png differ
diff --git a/resources/images/song_usage_inactive.png b/resources/images/song_usage_inactive.png
new file mode 100644
index 000000000..cdcf944ee
Binary files /dev/null and b/resources/images/song_usage_inactive.png differ
diff --git a/scripts/check_dependencies.py b/scripts/check_dependencies.py
new file mode 100755
index 000000000..4abd1504d
--- /dev/null
+++ b/scripts/check_dependencies.py
@@ -0,0 +1,192 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2011 Raoul Snyman #
+# --------------------------------------------------------------------------- #
+# 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 #
+###############################################################################
+
+"""
+This script is used to check dependencies of OpenLP. It checks availability
+of required python modules and their version. To verify availability of Python
+modules, simply run this script::
+
+ @:~$ ./check_dependencies.py
+
+"""
+import os
+import sys
+
+is_win = sys.platform.startswith('win')
+
+VERS = {
+ 'Python': '2.6',
+ 'PyQt4': '4.6',
+ 'Qt4': '4.6',
+ 'sqlalchemy': '0.5',
+ # pyenchant 1.6 required on Windows
+ 'enchant': '1.6' if is_win else '1.3'
+ }
+
+# pywin32
+WIN32_MODULES = [
+ 'win32com',
+ 'win32ui',
+ 'pywintypes',
+ ]
+
+MODULES = [
+ 'PyQt4',
+ 'PyQt4.QtCore',
+ 'PyQt4.QtGui',
+ 'PyQt4.QtNetwork',
+ 'PyQt4.QtOpenGL',
+ 'PyQt4.QtSvg',
+ 'PyQt4.QtTest',
+ 'PyQt4.QtWebKit',
+ 'PyQt4.phonon',
+ 'sqlalchemy',
+ 'sqlite3',
+ 'lxml',
+ 'chardet',
+ 'enchant',
+ 'BeautifulSoup',
+ 'mako',
+ ]
+
+
+OPTIONAL_MODULES = [
+ ('sqlite', ' (SQLite 2 support)'),
+ ('MySQLdb', ' (MySQL support)'),
+ ('psycopg2', ' (PostgreSQL support)'),
+ ]
+
+w = sys.stdout.write
+
+
+def check_vers(version, required, text):
+ if type(version) is str:
+ version = version.split('.')
+ version = [int(x) for x in version]
+ if type(required) is str:
+ required = required.split('.')
+ required = [int(x) for x in required]
+ w(' %s >= %s ... ' % (text, '.'.join([str(x) for x in required])))
+ if version >= required:
+ w('.'.join([str(x) for x in version]) + os.linesep)
+ return True
+ else:
+ w('FAIL' + os.linesep)
+ return False
+
+
+def print_vers_fail(required, text):
+ print(' %s >= %s ... FAIL' % (text, required))
+
+
+def verify_python():
+ if not check_vers(list(sys.version_info), VERS['Python'], text='Python'):
+ exit(1)
+
+
+def verify_versions():
+ print('Verifying version of modules...')
+ try:
+ from PyQt4 import QtCore
+ check_vers(QtCore.PYQT_VERSION_STR, VERS['PyQt4'],
+ 'PyQt4')
+ check_vers(QtCore.qVersion(), VERS['Qt4'],
+ 'Qt4')
+ except ImportError:
+ print_vers_fail(VERS['PyQt4'], 'PyQt4')
+ print_vers_fail(VERS['Qt4'], 'Qt4')
+ try:
+ import sqlalchemy
+ check_vers(sqlalchemy.__version__, VERS['sqlalchemy'], 'sqlalchemy')
+ except ImportError:
+ print_vers_fail(VERS['sqlalchemy'], 'sqlalchemy')
+ try:
+ import enchant
+ check_vers(enchant.__version__, VERS['enchant'], 'enchant')
+ except ImportError:
+ print_vers_fail(VERS['enchant'], 'enchant')
+
+
+def check_module(mod, text='', indent=' '):
+ space = (30 - len(mod) - len(text)) * ' '
+ w(indent + '%s%s... ' % (mod, text) + space)
+ try:
+ __import__(mod)
+ w('OK')
+ except ImportError:
+ w('FAIL')
+ w(os.linesep)
+
+
+def verify_pyenchant():
+ w('Enchant (spell checker)... ')
+ try:
+ import enchant
+ w(os.linesep)
+ backends = ', '.join([x.name for x in enchant.Broker().describe()])
+ print(' available backends: %s' % backends)
+ langs = ', '.join(enchant.list_languages())
+ print(' available languages: %s' % langs)
+ except ImportError:
+ w('FAIL' + os.linesep)
+
+
+def verify_pyqt():
+ w('Qt4 image formats... ')
+ try:
+ from PyQt4 import QtGui
+ read_f = ', '.join([unicode(format).lower() \
+ for format in QtGui.QImageReader.supportedImageFormats()])
+ write_f= ', '.join([unicode(format).lower() \
+ for format in QtGui.QImageWriter.supportedImageFormats()])
+ w(os.linesep)
+ print(' read: %s' % read_f)
+ print(' write: %s' % write_f)
+ except ImportError:
+ w('FAIL' + os.linesep)
+
+
+def main():
+
+ verify_python()
+
+ print('Checking for modules...')
+ for m in MODULES:
+ check_module(m)
+
+ print('Checking for optional modules...')
+ for m in OPTIONAL_MODULES:
+ check_module(m[0], text=m[1])
+
+ if is_win:
+ print('Checking for Windows specific modules...')
+ for m in WIN32_MODULES:
+ check_module(m)
+
+ verify_versions()
+ verify_pyqt()
+ verify_pyenchant()
+
+
+if __name__ == u'__main__':
+ main()