This commit is contained in:
Raoul Snyman 2014-09-02 22:38:36 +02:00
commit 184a397970
40 changed files with 731 additions and 112 deletions

View File

@ -36,14 +36,14 @@ logging and a plugin framework are contained within the openlp.core module.
import os import os
import sys import sys
import platform
import logging import logging
from optparse import OptionParser from optparse import OptionParser
from traceback import format_exception from traceback import format_exception
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.common import Registry, OpenLPMixin, AppLocation, Settings, UiStrings, check_directory_exists from openlp.core.common import Registry, OpenLPMixin, AppLocation, Settings, UiStrings, check_directory_exists, \
is_macosx, is_win
from openlp.core.lib import ScreenList from openlp.core.lib import ScreenList
from openlp.core.resources import qInitResources from openlp.core.resources import qInitResources
from openlp.core.ui.mainwindow import MainWindow from openlp.core.ui.mainwindow import MainWindow
@ -126,7 +126,7 @@ class OpenLP(OpenLPMixin, QtGui.QApplication):
alternate_rows_repair_stylesheet = \ alternate_rows_repair_stylesheet = \
'QTableWidget, QListWidget, QTreeWidget {alternate-background-color: ' + base_color.name() + ';}\n' 'QTableWidget, QListWidget, QTreeWidget {alternate-background-color: ' + base_color.name() + ';}\n'
application_stylesheet += alternate_rows_repair_stylesheet application_stylesheet += alternate_rows_repair_stylesheet
if os.name == 'nt': if is_win():
application_stylesheet += NT_REPAIR_STYLESHEET application_stylesheet += NT_REPAIR_STYLESHEET
if application_stylesheet: if application_stylesheet:
self.setStyleSheet(application_stylesheet) self.setStyleSheet(application_stylesheet)
@ -275,7 +275,7 @@ def main(args=None):
# Throw the rest of the arguments at Qt, just in case. # Throw the rest of the arguments at Qt, just in case.
qt_args.extend(args) qt_args.extend(args)
# Bug #1018855: Set the WM_CLASS property in X11 # Bug #1018855: Set the WM_CLASS property in X11
if platform.system() not in ['Windows', 'Darwin']: if not is_win() and not is_macosx():
qt_args.append('OpenLP') qt_args.append('OpenLP')
# Initialise the resources # Initialise the resources
qInitResources() qInitResources()

View File

@ -127,6 +127,33 @@ def de_hump(name):
sub_name = FIRST_CAMEL_REGEX.sub(r'\1_\2', name) sub_name = FIRST_CAMEL_REGEX.sub(r'\1_\2', name)
return SECOND_CAMEL_REGEX.sub(r'\1_\2', sub_name).lower() return SECOND_CAMEL_REGEX.sub(r'\1_\2', sub_name).lower()
def is_win():
"""
Returns true if running on a system with a nt kernel e.g. Windows, Wine
:return: True if system is running a nt kernel false otherwise
"""
return os.name.startswith('nt')
def is_macosx():
"""
Returns true if running on a system with a darwin kernel e.g. Mac OS X
:return: True if system is running a darwin kernel false otherwise
"""
return sys.platform.startswith('darwin')
def is_linux():
"""
Returns true if running on a system with a linux kernel e.g. Ubuntu, Debian, etc
:return: True if system is running a linux kernel false otherwise
"""
return sys.platform.startswith('linux')
from .openlpmixin import OpenLPMixin from .openlpmixin import OpenLPMixin
from .registry import Registry from .registry import Registry
from .registrymixin import RegistryMixin from .registrymixin import RegistryMixin

View File

@ -33,10 +33,10 @@ import logging
import os import os
import sys import sys
from openlp.core.common import Settings from openlp.core.common import Settings, is_win, is_macosx
if sys.platform != 'win32' and sys.platform != 'darwin': if not is_win() and not is_macosx():
try: try:
from xdg import BaseDirectory from xdg import BaseDirectory
XDG_BASE_AVAILABLE = True XDG_BASE_AVAILABLE = True
@ -145,13 +145,13 @@ def _get_os_dir_path(dir_type):
directory = os.path.abspath(os.path.join(os.path.dirname(openlp.__file__), '..', 'resources')) directory = os.path.abspath(os.path.join(os.path.dirname(openlp.__file__), '..', 'resources'))
if os.path.exists(directory): if os.path.exists(directory):
return directory return directory
if sys.platform == 'win32': if is_win():
if dir_type == AppLocation.DataDir: if dir_type == AppLocation.DataDir:
return os.path.join(str(os.getenv('APPDATA')), 'openlp', 'data') return os.path.join(str(os.getenv('APPDATA')), 'openlp', 'data')
elif dir_type == AppLocation.LanguageDir: elif dir_type == AppLocation.LanguageDir:
return os.path.dirname(openlp.__file__) return os.path.dirname(openlp.__file__)
return os.path.join(str(os.getenv('APPDATA')), 'openlp') return os.path.join(str(os.getenv('APPDATA')), 'openlp')
elif sys.platform == 'darwin': elif is_macosx():
if dir_type == AppLocation.DataDir: if dir_type == AppLocation.DataDir:
return os.path.join(str(os.getenv('HOME')), 'Library', 'Application Support', 'openlp', 'Data') return os.path.join(str(os.getenv('HOME')), 'Library', 'Application Support', 'openlp', 'Data')
elif dir_type == AppLocation.LanguageDir: elif dir_type == AppLocation.LanguageDir:

View File

@ -29,9 +29,7 @@
""" """
Provide Registry values for adding to classes Provide Registry values for adding to classes
""" """
import os from openlp.core.common import Registry, is_win
from openlp.core.common import Registry
class RegistryProperties(object): class RegistryProperties(object):
@ -45,7 +43,7 @@ class RegistryProperties(object):
Adds the openlp to the class dynamically. Adds the openlp to the class dynamically.
Windows needs to access the application in a dynamic manner. Windows needs to access the application in a dynamic manner.
""" """
if os.name == 'nt': if is_win():
return Registry().get('application') return Registry().get('application')
else: else:
if not hasattr(self, '_application') or not self._application: if not hasattr(self, '_application') or not self._application:

View File

@ -36,7 +36,7 @@ import sys
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.common import ThemeLevel, SlideLimits, UiStrings from openlp.core.common import ThemeLevel, SlideLimits, UiStrings, is_win, is_linux
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -44,7 +44,7 @@ log = logging.getLogger(__name__)
# Fix for bug #1014422. # Fix for bug #1014422.
X11_BYPASS_DEFAULT = True X11_BYPASS_DEFAULT = True
if sys.platform.startswith('linux'): if is_linux():
# Default to False on Gnome. # Default to False on Gnome.
X11_BYPASS_DEFAULT = bool(not os.environ.get('GNOME_DESKTOP_SESSION_ID')) X11_BYPASS_DEFAULT = bool(not os.environ.get('GNOME_DESKTOP_SESSION_ID'))
# Default to False on Xfce. # Default to False on Xfce.
@ -86,7 +86,7 @@ class Settings(QtCore.QSettings):
""" """
__default_settings__ = { __default_settings__ = {
'advanced/add page break': False, 'advanced/add page break': False,
'advanced/alternate rows': not sys.platform.startswith('win'), 'advanced/alternate rows': not is_win(),
'advanced/current media plugin': -1, 'advanced/current media plugin': -1,
'advanced/data path': '', 'advanced/data path': '',
'advanced/default color': '#ffffff', 'advanced/default color': '#ffffff',

View File

@ -81,4 +81,4 @@ class OpenLPToolbar(QtGui.QToolBar):
if handle in self.actions: if handle in self.actions:
self.actions[handle].setVisible(visible) self.actions[handle].setVisible(visible)
else: else:
log.warn('No handle "%s" in actions list.', str(handle)) log.warning('No handle "%s" in actions list.', str(handle))

View File

@ -172,7 +172,7 @@ def create_button(parent, name, **kwargs):
kwargs.setdefault('icon', ':/services/service_down.png') kwargs.setdefault('icon', ':/services/service_down.png')
kwargs.setdefault('tooltip', translate('OpenLP.Ui', 'Move selection down one position.')) kwargs.setdefault('tooltip', translate('OpenLP.Ui', 'Move selection down one position.'))
else: else:
log.warn('The role "%s" is not defined in create_push_button().', role) log.warning('The role "%s" is not defined in create_push_button().', role)
if kwargs.pop('btn_class', '') == 'toolbutton': if kwargs.pop('btn_class', '') == 'toolbutton':
button = QtGui.QToolButton(parent) button = QtGui.QToolButton(parent)
else: else:
@ -190,7 +190,7 @@ def create_button(parent, name, **kwargs):
button.clicked.connect(kwargs.pop('click')) button.clicked.connect(kwargs.pop('click'))
for key in list(kwargs.keys()): for key in list(kwargs.keys()):
if key not in ['text', 'icon', 'tooltip', 'click']: if key not in ['text', 'icon', 'tooltip', 'click']:
log.warn('Parameter %s was not consumed in create_button().', key) log.warning('Parameter %s was not consumed in create_button().', key)
return button return button
@ -275,7 +275,7 @@ def create_action(parent, name, **kwargs):
action.triggered.connect(kwargs.pop('triggers')) action.triggered.connect(kwargs.pop('triggers'))
for key in list(kwargs.keys()): for key in list(kwargs.keys()):
if key not in ['text', 'icon', 'tooltip', 'statustip', 'checked', 'can_shortcuts', 'category', 'triggers']: if key not in ['text', 'icon', 'tooltip', 'statustip', 'checked', 'can_shortcuts', 'category', 'triggers']:
log.warn('Parameter %s was not consumed in create_action().' % key) log.warning('Parameter %s was not consumed in create_action().' % key)
return action return action

View File

@ -38,7 +38,7 @@ import bs4
import sqlalchemy import sqlalchemy
from lxml import etree from lxml import etree
from openlp.core.common import RegistryProperties from openlp.core.common import RegistryProperties, is_linux
from PyQt4 import Qt, QtCore, QtGui, QtWebKit from PyQt4 import Qt, QtCore, QtGui, QtWebKit
@ -137,7 +137,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog, RegistryProperties):
'pyICU: %s\n' % ICU_VERSION + \ 'pyICU: %s\n' % ICU_VERSION + \
'pyUNO bridge: %s\n' % self._pyuno_import() + \ 'pyUNO bridge: %s\n' % self._pyuno_import() + \
'VLC: %s\n' % VLC_VERSION 'VLC: %s\n' % VLC_VERSION
if platform.system() == 'Linux': if is_linux():
if os.environ.get('KDE_FULL_SESSION') == 'true': if os.environ.get('KDE_FULL_SESSION') == 'true':
system += 'Desktop: KDE SC\n' system += 'Desktop: KDE SC\n'
elif os.environ.get('GNOME_DESKTOP_SESSION_ID'): elif os.environ.get('GNOME_DESKTOP_SESSION_ID'):

View File

@ -43,7 +43,7 @@ import sys
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
from openlp.core.common import Registry, RegistryProperties, OpenLPMixin, Settings, translate from openlp.core.common import Registry, RegistryProperties, OpenLPMixin, Settings, translate, is_macosx
from openlp.core.lib import ServiceItem, ImageSource, build_html, expand_tags, image_to_byte from openlp.core.lib import ServiceItem, ImageSource, build_html, expand_tags, image_to_byte
from openlp.core.lib.theme import BackgroundType from openlp.core.lib.theme import BackgroundType
@ -74,7 +74,7 @@ class Display(QtGui.QGraphicsView):
# OpenGL. Only white blank screen is shown on the 2nd monitor all the # OpenGL. Only white blank screen is shown on the 2nd monitor all the
# time. We need to investigate more how to use OpenGL properly on Mac OS # time. We need to investigate more how to use OpenGL properly on Mac OS
# X. # X.
if sys.platform != 'darwin': if not is_macosx():
self.setViewport(QtOpenGL.QGLWidget()) self.setViewport(QtOpenGL.QGLWidget())
def setup(self): def setup(self):
@ -143,7 +143,7 @@ class MainDisplay(OpenLPMixin, Display, RegistryProperties):
# on Mac OS X. For next OpenLP version we should test it on other # on Mac OS X. For next OpenLP version we should test it on other
# platforms. For OpenLP 2.0 keep it only for OS X to not cause any # platforms. For OpenLP 2.0 keep it only for OS X to not cause any
# regressions on other platforms. # regressions on other platforms.
if sys.platform == 'darwin': if is_macosx():
window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Window window_flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Window
# For primary screen ensure it stays above the OS X dock # For primary screen ensure it stays above the OS X dock
# and menu bar # and menu bar

View File

@ -41,7 +41,8 @@ from datetime import datetime
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, translate from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, translate, \
is_win, is_macosx
from openlp.core.lib import Renderer, OpenLPDockWidget, PluginManager, ImageManager, PluginStatus, ScreenList, \ from openlp.core.lib import Renderer, OpenLPDockWidget, PluginManager, ImageManager, PluginStatus, ScreenList, \
build_icon build_icon
from openlp.core.lib.ui import UiStrings, create_action from openlp.core.lib.ui import UiStrings, create_action
@ -289,7 +290,7 @@ class Ui_MainWindow(object):
triggers=self.on_about_item_clicked) triggers=self.on_about_item_clicked)
# Give QT Extra Hint that this is an About Menu Item # Give QT Extra Hint that this is an About Menu Item
self.about_item.setMenuRole(QtGui.QAction.AboutRole) self.about_item.setMenuRole(QtGui.QAction.AboutRole)
if os.name == 'nt': if is_win():
self.local_help_file = os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm') self.local_help_file = os.path.join(AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
self.offline_help_item = create_action(main_window, 'offlineHelpItem', self.offline_help_item = create_action(main_window, 'offlineHelpItem',
icon=':/system/system_help_contents.png', icon=':/system/system_help_contents.png',
@ -323,7 +324,7 @@ class Ui_MainWindow(object):
# Qt on OS X looks for keywords in the menu items title to determine which menu items get added to the main # Qt on OS X looks for keywords in the menu items title to determine which menu items get added to the main
# menu. If we are running on Mac OS X the menu items whose title contains those keywords but don't belong in the # menu. If we are running on Mac OS X the menu items whose title contains those keywords but don't belong in the
# main menu need to be marked as such with QAction.NoRole. # main menu need to be marked as such with QAction.NoRole.
if sys.platform == 'darwin': if is_macosx():
self.settings_shortcuts_item.setMenuRole(QtGui.QAction.NoRole) self.settings_shortcuts_item.setMenuRole(QtGui.QAction.NoRole)
self.formatting_tag_item.setMenuRole(QtGui.QAction.NoRole) self.formatting_tag_item.setMenuRole(QtGui.QAction.NoRole)
add_actions(self.settings_menu, (self.settings_plugin_list_item, self.settings_language_menu.menuAction(), add_actions(self.settings_menu, (self.settings_plugin_list_item, self.settings_language_menu.menuAction(),
@ -332,7 +333,7 @@ class Ui_MainWindow(object):
add_actions(self.tools_menu, (self.tools_open_data_folder, None)) add_actions(self.tools_menu, (self.tools_open_data_folder, None))
add_actions(self.tools_menu, (self.tools_first_time_wizard, None)) add_actions(self.tools_menu, (self.tools_first_time_wizard, None))
add_actions(self.tools_menu, [self.update_theme_images]) add_actions(self.tools_menu, [self.update_theme_images])
if os.name == 'nt': if is_win():
add_actions(self.help_menu, (self.offline_help_item, self.on_line_help_item, None, self.web_site_item, add_actions(self.help_menu, (self.offline_help_item, self.on_line_help_item, None, self.web_site_item,
self.about_item)) self.about_item))
else: else:
@ -426,7 +427,7 @@ class Ui_MainWindow(object):
self.settings_plugin_list_item.setStatusTip(translate('OpenLP.MainWindow', 'List the Plugins')) self.settings_plugin_list_item.setStatusTip(translate('OpenLP.MainWindow', 'List the Plugins'))
self.about_item.setText(translate('OpenLP.MainWindow', '&About')) self.about_item.setText(translate('OpenLP.MainWindow', '&About'))
self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP')) self.about_item.setStatusTip(translate('OpenLP.MainWindow', 'More information about OpenLP'))
if os.name == 'nt': if is_win():
self.offline_help_item.setText(translate('OpenLP.MainWindow', '&User Guide')) self.offline_help_item.setText(translate('OpenLP.MainWindow', '&User Guide'))
self.on_line_help_item.setText(translate('OpenLP.MainWindow', '&Online Help')) self.on_line_help_item.setText(translate('OpenLP.MainWindow', '&Online Help'))
self.search_shortcut_action.setText(UiStrings().Search) self.search_shortcut_action.setText(UiStrings().Search)
@ -1073,7 +1074,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
if self.live_controller.display: if self.live_controller.display:
self.live_controller.display.close() self.live_controller.display.close()
self.live_controller.display = None self.live_controller.display = None
if os.name == 'nt': if is_win():
# Needed for Windows to stop crashes on exit # Needed for Windows to stop crashes on exit
Registry().remove('application') Registry().remove('application')

View File

@ -175,7 +175,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
# On some platforms importing vlc.py might cause # On some platforms importing vlc.py might cause
# also OSError exceptions. (e.g. Mac OS X) # also OSError exceptions. (e.g. Mac OS X)
except (ImportError, OSError): except (ImportError, OSError):
log.warn('Failed to import %s on path %s', module_name, path) log.warning('Failed to import %s on path %s', module_name, path)
player_classes = MediaPlayer.__subclasses__() player_classes = MediaPlayer.__subclasses__()
for player_class in player_classes: for player_class in player_classes:
player = player_class(self) player = player_class(self)

View File

@ -38,7 +38,7 @@ import threading
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.common import Settings from openlp.core.common import Settings, is_win, is_macosx
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.ui.media import MediaState from openlp.core.ui.media import MediaState
from openlp.core.ui.media.mediaplayer import MediaPlayer from openlp.core.ui.media.mediaplayer import MediaPlayer
@ -52,7 +52,7 @@ try:
except (ImportError, NameError, NotImplementedError): except (ImportError, NameError, NotImplementedError):
pass pass
except OSError as e: except OSError as e:
if sys.platform.startswith('win'): if is_win():
if not isinstance(e, WindowsError) and e.winerror != 126: if not isinstance(e, WindowsError) and e.winerror != 126:
raise raise
else: else:
@ -139,9 +139,9 @@ class VlcPlayer(MediaPlayer):
# You have to give the id of the QFrame (or similar object) # You have to give the id of the QFrame (or similar object)
# to vlc, different platforms have different functions for this. # to vlc, different platforms have different functions for this.
win_id = int(display.vlc_widget.winId()) win_id = int(display.vlc_widget.winId())
if sys.platform == "win32": if is_win():
display.vlc_media_player.set_hwnd(win_id) display.vlc_media_player.set_hwnd(win_id)
elif sys.platform == "darwin": elif is_macosx():
# We have to use 'set_nsobject' since Qt4 on OSX uses Cocoa # We have to use 'set_nsobject' since Qt4 on OSX uses Cocoa
# framework and not the old Carbon. # framework and not the old Carbon.
display.vlc_media_player.set_nsobject(win_id) display.vlc_media_player.set_nsobject(win_id)

View File

@ -993,7 +993,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
service_item.auto_play_slides_once = False service_item.auto_play_slides_once = False
self.set_modified() self.set_modified()
def on_auto_start(self): def on_auto_start(self, field=None):
""" """
Toggles to Auto Start Setting. Toggles to Auto Start Setting.
""" """

View File

@ -44,10 +44,10 @@ from random import randint
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from openlp.core.common import Registry, AppLocation, Settings from openlp.core.common import Registry, AppLocation, Settings, is_win, is_macosx
if sys.platform != 'win32' and sys.platform != 'darwin': if not is_win() and not is_macosx():
try: try:
from xdg import BaseDirectory from xdg import BaseDirectory
XDG_BASE_AVAILABLE = True XDG_BASE_AVAILABLE = True
@ -109,6 +109,22 @@ class VersionThread(QtCore.QThread):
Registry().execute('openlp_version_check', '%s' % version) Registry().execute('openlp_version_check', '%s' % version)
class HTTPRedirectHandlerFixed(urllib.request.HTTPRedirectHandler):
"""
Special HTTPRedirectHandler used to work around http://bugs.python.org/issue22248
(Redirecting to urls with special chars)
"""
def redirect_request(self, req, fp, code, msg, headers, newurl):
# Test if the newurl can be decoded to ascii
try:
test_url = newurl.encode('latin1').decode('ascii')
fixed_url = newurl
except Exception:
# The url could not be decoded to ascii, so we do some url encoding
fixed_url = urllib.parse.quote(newurl.encode('latin1').decode('utf-8', 'replace'), safe='/:')
return super(HTTPRedirectHandlerFixed, self).redirect_request(req, fp, code, msg, headers, fixed_url)
def get_application_version(): def get_application_version():
""" """
Returns the application version of the running instance of OpenLP:: Returns the application version of the running instance of OpenLP::
@ -341,6 +357,9 @@ def get_web_page(url, header=None, update_openlp=False):
# http://docs.python.org/library/urllib2.html # http://docs.python.org/library/urllib2.html
if not url: if not url:
return None return None
# This is needed to work around http://bugs.python.org/issue22248 and https://bugs.launchpad.net/openlp/+bug/1251437
opener = urllib.request.build_opener(HTTPRedirectHandlerFixed())
urllib.request.install_opener(opener)
req = urllib.request.Request(url) req = urllib.request.Request(url)
if not header or header[0].lower() != 'user-agent': if not header or header[0].lower() != 'user-agent':
user_agent = _get_user_agent() user_agent = _get_user_agent()

View File

@ -279,8 +279,8 @@ class ActionList(object):
actions.append(action) actions.append(action)
ActionList.shortcut_map[shortcuts[1]] = actions ActionList.shortcut_map[shortcuts[1]] = actions
else: else:
log.warn('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' %
(shortcuts[1], action.objectName())) (shortcuts[1], action.objectName()))
shortcuts.remove(shortcuts[1]) shortcuts.remove(shortcuts[1])
# Check the primary shortcut. # Check the primary shortcut.
existing_actions = ActionList.shortcut_map.get(shortcuts[0], []) existing_actions = ActionList.shortcut_map.get(shortcuts[0], [])
@ -290,8 +290,8 @@ class ActionList(object):
actions.append(action) actions.append(action)
ActionList.shortcut_map[shortcuts[0]] = actions ActionList.shortcut_map[shortcuts[0]] = actions
else: else:
log.warn('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' %
(shortcuts[0], action.objectName())) (shortcuts[0], action.objectName()))
shortcuts.remove(shortcuts[0]) shortcuts.remove(shortcuts[0])
action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts])

View File

@ -35,7 +35,7 @@ import sys
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.common import AppLocation, Settings, translate from openlp.core.common import AppLocation, Settings, translate, is_win, is_macosx
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -60,7 +60,7 @@ class LanguageManager(object):
app_translator = QtCore.QTranslator() app_translator = QtCore.QTranslator()
app_translator.load(language, lang_path) app_translator.load(language, lang_path)
# A translator for buttons and other default strings provided by Qt. # A translator for buttons and other default strings provided by Qt.
if sys.platform != 'win32' and sys.platform != 'darwin': if not is_win() and not is_macosx():
lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath) lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)
default_translator = QtCore.QTranslator() default_translator = QtCore.QTranslator()
default_translator.load('qt_%s' % language, lang_path) default_translator.load('qt_%s' % language, lang_path)

View File

@ -423,7 +423,7 @@ class BibleUpgradeForm(OpenLPWizard):
else: else:
language_id = self.new_bibles[number].get_language(name) language_id = self.new_bibles[number].get_language(name)
if not language_id: if not language_id:
log.warn('Upgrading from "%s" failed' % filename[0]) log.warning('Upgrading from "%s" failed' % filename[0])
self.new_bibles[number].session.close() self.new_bibles[number].session.close()
del self.new_bibles[number] del self.new_bibles[number]
self.increment_progress_bar( self.increment_progress_bar(
@ -444,7 +444,7 @@ class BibleUpgradeForm(OpenLPWizard):
book_ref_id = self.new_bibles[number].\ book_ref_id = self.new_bibles[number].\
get_book_ref_id_by_name(book, len(books), language_id) get_book_ref_id_by_name(book, len(books), language_id)
if not book_ref_id: if not book_ref_id:
log.warn('Upgrading books from %s - download name: "%s" aborted by user' % ( log.warning('Upgrading books from %s - download name: "%s" aborted by user' % (
meta_data['download_source'], meta_data['download_name'])) meta_data['download_source'], meta_data['download_name']))
self.new_bibles[number].session.close() self.new_bibles[number].session.close()
del self.new_bibles[number] del self.new_bibles[number]
@ -457,7 +457,7 @@ class BibleUpgradeForm(OpenLPWizard):
if oldbook: if oldbook:
verses = old_bible.get_verses(oldbook['id']) verses = old_bible.get_verses(oldbook['id'])
if not verses: if not verses:
log.warn('No verses found to import for book "%s"', book) log.warning('No verses found to import for book "%s"', book)
continue continue
for verse in verses: for verse in verses:
if self.stop_import_flag: if self.stop_import_flag:
@ -472,7 +472,7 @@ class BibleUpgradeForm(OpenLPWizard):
if not language_id: if not language_id:
language_id = self.new_bibles[number].get_language(name) language_id = self.new_bibles[number].get_language(name)
if not language_id: if not language_id:
log.warn('Upgrading books from "%s" failed' % name) log.warning('Upgrading books from "%s" failed' % name)
self.new_bibles[number].session.close() self.new_bibles[number].session.close()
del self.new_bibles[number] del self.new_bibles[number]
self.increment_progress_bar( self.increment_progress_bar(
@ -493,7 +493,7 @@ class BibleUpgradeForm(OpenLPWizard):
(number + 1, max_bibles, name, book['name'])) (number + 1, max_bibles, name, book['name']))
book_ref_id = self.new_bibles[number].get_book_ref_id_by_name(book['name'], len(books), language_id) book_ref_id = self.new_bibles[number].get_book_ref_id_by_name(book['name'], len(books), language_id)
if not book_ref_id: if not book_ref_id:
log.warn('Upgrading books from %s " failed - aborted by user' % name) log.warning('Upgrading books from %s " failed - aborted by user' % name)
self.new_bibles[number].session.close() self.new_bibles[number].session.close()
del self.new_bibles[number] del self.new_bibles[number]
self.success[number] = False self.success[number] = False
@ -503,7 +503,7 @@ class BibleUpgradeForm(OpenLPWizard):
book_details['testament_id']) book_details['testament_id'])
verses = old_bible.get_verses(book['id']) verses = old_bible.get_verses(book['id'])
if not verses: if not verses:
log.warn('No verses found to import for book "%s"', book['name']) log.warning('No verses found to import for book "%s"', book['name'])
self.new_bibles[number].delete_book(db_book) self.new_bibles[number].delete_book(db_book)
continue continue
for verse in verses: for verse in verses:

View File

@ -32,7 +32,6 @@ The :mod:`http` module enables OpenLP to retrieve scripture from bible websites.
import logging import logging
import re import re
import socket import socket
import urllib.request
import urllib.parse import urllib.parse
import urllib.error import urllib.error
from html.parser import HTMLParseError from html.parser import HTMLParseError
@ -165,7 +164,7 @@ class BGExtract(RegistryProperties):
if len(verse_parts) > 1: if len(verse_parts) > 1:
verse = int(verse_parts[0]) verse = int(verse_parts[0])
except TypeError: except TypeError:
log.warn('Illegal verse number: %s', str(verse)) log.warning('Illegal verse number: %s', str(verse))
verses.append((verse, text)) verses.append((verse, text))
verse_list = {} verse_list = {}
for verse, text in verses[::-1]: for verse, text in verses[::-1]:
@ -198,7 +197,7 @@ class BGExtract(RegistryProperties):
if len(verse_parts) > 1: if len(verse_parts) > 1:
clean_verse_num = int(verse_parts[0]) clean_verse_num = int(verse_parts[0])
except TypeError: except TypeError:
log.warn('Illegal verse number: %s', str(raw_verse_num)) log.warning('Illegal verse number: %s', str(raw_verse_num))
if clean_verse_num: if clean_verse_num:
verse_text = raw_verse_num.next_element verse_text = raw_verse_num.next_element
part = raw_verse_num.next_element.next_element part = raw_verse_num.next_element.next_element

View File

@ -123,7 +123,7 @@ class OpenSongBible(BibleDB):
if len(verse_parts) > 1: if len(verse_parts) > 1:
number = int(verse_parts[0]) number = int(verse_parts[0])
except TypeError: except TypeError:
log.warn('Illegal verse number: %s', str(verse.attrib['n'])) log.warning('Illegal verse number: %s', str(verse.attrib['n']))
verse_number = number verse_number = number
else: else:
verse_number += 1 verse_number += 1

View File

@ -42,7 +42,9 @@ import logging
import os import os
import time import time
if os.name == 'nt': from openlp.core.common import is_win
if is_win():
from win32com.client import Dispatch from win32com.client import Dispatch
import pywintypes import pywintypes
# Declare an empty exception to match the exception imported from UNO # Declare an empty exception to match the exception imported from UNO
@ -93,7 +95,7 @@ class ImpressController(PresentationController):
Impress is able to run on this machine. Impress is able to run on this machine.
""" """
log.debug('check_available') log.debug('check_available')
if os.name == 'nt': if is_win():
return self.get_com_servicemanager() is not None return self.get_com_servicemanager() is not None
else: else:
return uno_available return uno_available
@ -104,7 +106,7 @@ class ImpressController(PresentationController):
UNO interface when required. UNO interface when required.
""" """
log.debug('start process Openoffice') log.debug('start process Openoffice')
if os.name == 'nt': if is_win():
self.manager = self.get_com_servicemanager() self.manager = self.get_com_servicemanager()
self.manager._FlagAsMethod('Bridge_GetStruct') self.manager._FlagAsMethod('Bridge_GetStruct')
self.manager._FlagAsMethod('Bridge_GetValueObject') self.manager._FlagAsMethod('Bridge_GetValueObject')
@ -129,7 +131,7 @@ class ImpressController(PresentationController):
try: try:
uno_instance = get_uno_instance(resolver) uno_instance = get_uno_instance(resolver)
except: except:
log.warn('Unable to find running instance ') log.warning('Unable to find running instance ')
self.start_process() self.start_process()
loop += 1 loop += 1
try: try:
@ -138,7 +140,7 @@ class ImpressController(PresentationController):
desktop = self.manager.createInstanceWithContext("com.sun.star.frame.Desktop", uno_instance) desktop = self.manager.createInstanceWithContext("com.sun.star.frame.Desktop", uno_instance)
return desktop return desktop
except: except:
log.warn('Failed to get UNO desktop') log.warning('Failed to get UNO desktop')
return None return None
def get_com_desktop(self): def get_com_desktop(self):
@ -152,7 +154,7 @@ class ImpressController(PresentationController):
try: try:
desktop = self.manager.createInstance('com.sun.star.frame.Desktop') desktop = self.manager.createInstance('com.sun.star.frame.Desktop')
except (AttributeError, pywintypes.com_error): except (AttributeError, pywintypes.com_error):
log.warn('Failure to find desktop - Impress may have closed') log.warning('Failure to find desktop - Impress may have closed')
return desktop if desktop else None return desktop if desktop else None
def get_com_servicemanager(self): def get_com_servicemanager(self):
@ -163,7 +165,7 @@ class ImpressController(PresentationController):
try: try:
return Dispatch('com.sun.star.ServiceManager') return Dispatch('com.sun.star.ServiceManager')
except pywintypes.com_error: except pywintypes.com_error:
log.warn('Failed to get COM service manager. Impress Controller has been disabled') log.warning('Failed to get COM service manager. Impress Controller has been disabled')
return None return None
def kill(self): def kill(self):
@ -175,12 +177,12 @@ class ImpressController(PresentationController):
self.docs[0].close_presentation() self.docs[0].close_presentation()
desktop = None desktop = None
try: try:
if os.name != 'nt': if not is_win():
desktop = self.get_uno_desktop() desktop = self.get_uno_desktop()
else: else:
desktop = self.get_com_desktop() desktop = self.get_com_desktop()
except: except:
log.warn('Failed to find an OpenOffice desktop to terminate') log.warning('Failed to find an OpenOffice desktop to terminate')
if not desktop: if not desktop:
return return
docs = desktop.getComponents() docs = desktop.getComponents()
@ -198,7 +200,7 @@ class ImpressController(PresentationController):
desktop.terminate() desktop.terminate()
log.debug('OpenOffice killed') log.debug('OpenOffice killed')
except: except:
log.warn('Failed to terminate OpenOffice') log.warning('Failed to terminate OpenOffice')
class ImpressDocument(PresentationDocument): class ImpressDocument(PresentationDocument):
@ -223,7 +225,7 @@ class ImpressDocument(PresentationDocument):
is available the presentation is loaded and started. is available the presentation is loaded and started.
""" """
log.debug('Load Presentation OpenOffice') log.debug('Load Presentation OpenOffice')
if os.name == 'nt': if is_win():
desktop = self.controller.get_com_desktop() desktop = self.controller.get_com_desktop()
if desktop is None: if desktop is None:
self.controller.start_process() self.controller.start_process()
@ -236,7 +238,7 @@ class ImpressDocument(PresentationDocument):
return False return False
self.desktop = desktop self.desktop = desktop
properties = [] properties = []
if os.name != 'nt': if not is_win():
# Recent versions of Impress on Windows won't start the presentation if it starts as minimized. It seems OK # Recent versions of Impress on Windows won't start the presentation if it starts as minimized. It seems OK
# on Linux though. # on Linux though.
properties.append(self.create_property('Minimized', True)) properties.append(self.create_property('Minimized', True))
@ -244,9 +246,9 @@ class ImpressDocument(PresentationDocument):
try: try:
self.document = desktop.loadComponentFromURL(url, '_blank', 0, properties) self.document = desktop.loadComponentFromURL(url, '_blank', 0, properties)
except: except:
log.warn('Failed to load presentation %s' % url) log.warning('Failed to load presentation %s' % url)
return False return False
if os.name == 'nt': if is_win():
# As we can't start minimized the Impress window gets in the way. # As we can't start minimized the Impress window gets in the way.
# Either window.setPosSize(0, 0, 200, 400, 12) or .setVisible(False) # Either window.setPosSize(0, 0, 200, 400, 12) or .setVisible(False)
window = self.document.getCurrentController().getFrame().getContainerWindow() window = self.document.getCurrentController().getFrame().getContainerWindow()
@ -264,7 +266,7 @@ class ImpressDocument(PresentationDocument):
log.debug('create thumbnails OpenOffice') log.debug('create thumbnails OpenOffice')
if self.check_thumbnails(): if self.check_thumbnails():
return return
if os.name == 'nt': if is_win():
thumb_dir_url = 'file:///' + self.get_temp_folder().replace('\\', '/') \ thumb_dir_url = 'file:///' + self.get_temp_folder().replace('\\', '/') \
.replace(':', '|').replace(' ', '%20') .replace(':', '|').replace(' ', '%20')
else: else:
@ -297,7 +299,7 @@ class ImpressDocument(PresentationDocument):
Create an OOo style property object which are passed into some Uno methods. Create an OOo style property object which are passed into some Uno methods.
""" """
log.debug('create property OpenOffice') log.debug('create property OpenOffice')
if os.name == 'nt': if is_win():
property_object = self.controller.manager.Bridge_GetStruct('com.sun.star.beans.PropertyValue') property_object = self.controller.manager.Bridge_GetStruct('com.sun.star.beans.PropertyValue')
else: else:
property_object = PropertyValue() property_object = PropertyValue()
@ -318,7 +320,7 @@ class ImpressDocument(PresentationDocument):
self.presentation = None self.presentation = None
self.document.dispose() self.document.dispose()
except: except:
log.warn("Closing presentation failed") log.warning("Closing presentation failed")
self.document = None self.document = None
self.controller.remove_doc(self) self.controller.remove_doc(self)
@ -335,7 +337,7 @@ class ImpressDocument(PresentationDocument):
log.debug("getPresentation failed to find a presentation") log.debug("getPresentation failed to find a presentation")
return False return False
except: except:
log.warn("getPresentation failed to find a presentation") log.warning("getPresentation failed to find a presentation")
return False return False
return True return True

View File

@ -98,7 +98,7 @@ class Controller(object):
return True return True
if not self.doc.is_loaded(): if not self.doc.is_loaded():
if not self.doc.load_presentation(): if not self.doc.load_presentation():
log.warn('Failed to activate %s' % self.doc.filepath) log.warning('Failed to activate %s' % self.doc.filepath)
return False return False
if self.is_live: if self.is_live:
self.doc.start_presentation() self.doc.start_presentation()
@ -109,7 +109,7 @@ class Controller(object):
if self.doc.is_active(): if self.doc.is_active():
return True return True
else: else:
log.warn('Failed to activate %s' % self.doc.filepath) log.warning('Failed to activate %s' % self.doc.filepath)
return False return False
def slide(self, slide): def slide(self, slide):

View File

@ -34,7 +34,7 @@ import re
from subprocess import check_output, CalledProcessError, STDOUT from subprocess import check_output, CalledProcessError, STDOUT
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from openlp.core.common import Settings from openlp.core.common import Settings, is_win
from openlp.core.lib import ScreenList from openlp.core.lib import ScreenList
from .presentationcontroller import PresentationController, PresentationDocument from .presentationcontroller import PresentationController, PresentationDocument
@ -123,7 +123,7 @@ class PdfController(PresentationController):
else: else:
# Fallback to autodetection # Fallback to autodetection
application_path = AppLocation.get_directory(AppLocation.AppDir) application_path = AppLocation.get_directory(AppLocation.AppDir)
if os.name == 'nt': if is_win():
# for windows we only accept mudraw.exe in the base folder # for windows we only accept mudraw.exe in the base folder
application_path = AppLocation.get_directory(AppLocation.AppDir) application_path = AppLocation.get_directory(AppLocation.AppDir)
if os.path.isfile(os.path.join(application_path, 'mudraw.exe')): if os.path.isfile(os.path.join(application_path, 'mudraw.exe')):

View File

@ -33,7 +33,9 @@ This modul is for controlling powerpiont. PPT API documentation:
import os import os
import logging import logging
if os.name == 'nt': from openlp.core.common import is_win
if is_win():
from win32com.client import Dispatch from win32com.client import Dispatch
import winreg import winreg
import win32ui import win32ui
@ -69,7 +71,7 @@ class PowerpointController(PresentationController):
PowerPoint is able to run on this machine. PowerPoint is able to run on this machine.
""" """
log.debug('check_available') log.debug('check_available')
if os.name == 'nt': if is_win():
try: try:
winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, 'PowerPoint.Application').Close() winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, 'PowerPoint.Application').Close()
return True return True
@ -77,7 +79,7 @@ class PowerpointController(PresentationController):
pass pass
return False return False
if os.name == 'nt': if is_win():
def start_process(self): def start_process(self):
""" """
Loads PowerPoint process. Loads PowerPoint process.
@ -271,7 +273,7 @@ class PowerpointDocument(PresentationDocument):
trace_error_handler(log) trace_error_handler(log)
self.show_error_msg() self.show_error_msg()
if os.name == 'nt': if is_win():
def start_presentation(self): def start_presentation(self):
""" """
Starts a presentation from the beginning. Starts a presentation from the beginning.

View File

@ -30,7 +30,9 @@
import logging import logging
import os import os
if os.name == 'nt': from openlp.core.common import is_win
if is_win():
from ctypes import cdll from ctypes import cdll
from ctypes.wintypes import RECT from ctypes.wintypes import RECT
@ -63,11 +65,11 @@ class PptviewController(PresentationController):
PPT Viewer is able to run on this machine. PPT Viewer is able to run on this machine.
""" """
log.debug('check_available') log.debug('check_available')
if os.name != 'nt': if not is_win():
return False return False
return self.check_installed() return self.check_installed()
if os.name == 'nt': if is_win():
def check_installed(self): def check_installed(self):
""" """
Check the viewer is installed. Check the viewer is installed.

View File

@ -90,7 +90,7 @@ class PresentationPlugin(Plugin):
try: try:
self.controllers[controller].start_process() self.controllers[controller].start_process()
except Exception: except Exception:
log.warn('Failed to start controller process') log.warning('Failed to start controller process')
self.controllers[controller].available = False self.controllers[controller].available = False
self.media_item.build_file_mask_string() self.media_item.build_file_mask_string()
@ -134,7 +134,7 @@ class PresentationPlugin(Plugin):
try: try:
__import__(module_name, globals(), locals(), []) __import__(module_name, globals(), locals(), [])
except ImportError: except ImportError:
log.warn('Failed to import %s on path %s', module_name, path) log.warning('Failed to import %s on path %s', module_name, path)
controller_classes = PresentationController.__subclasses__() controller_classes = PresentationController.__subclasses__()
for controller_class in controller_classes: for controller_class in controller_classes:
controller = controller_class(self) controller = controller_class(self)

View File

@ -37,7 +37,7 @@ from time import sleep
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core import Settings from openlp.core import Settings
from openlp.core.common import Registry from openlp.core.common import Registry, is_win
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.songs.forms.songselectdialog import Ui_SongSelectDialog from openlp.plugins.songs.forms.songselectdialog import Ui_SongSelectDialog
from openlp.plugins.songs.lib.songselect import SongSelectImport from openlp.plugins.songs.lib.songselect import SongSelectImport
@ -377,7 +377,7 @@ class SongSelectForm(QtGui.QDialog, Ui_SongSelectDialog):
Adds the openlp to the class dynamically. Adds the openlp to the class dynamically.
Windows needs to access the application in a dynamic manner. Windows needs to access the application in a dynamic manner.
""" """
if os.name == 'nt': if is_win():
return Registry().get('application') return Registry().get('application')
else: else:
if not hasattr(self, '_application'): if not hasattr(self, '_application'):

View File

@ -32,7 +32,7 @@ The :mod:`importer` modules provides the general song import functionality.
import os import os
import logging import logging
from openlp.core.common import translate, UiStrings from openlp.core.common import translate, UiStrings, is_win
from openlp.core.ui.wizard import WizardStrings from openlp.core.ui.wizard import WizardStrings
from .importers.opensong import OpenSongImport from .importers.opensong import OpenSongImport
from .importers.easyslides import EasySlidesImport from .importers.easyslides import EasySlidesImport
@ -70,14 +70,14 @@ except ImportError:
log.exception('Error importing %s', 'OooImport') log.exception('Error importing %s', 'OooImport')
HAS_OOO = False HAS_OOO = False
HAS_MEDIASHOUT = False HAS_MEDIASHOUT = False
if os.name == 'nt': if is_win():
try: try:
from .importers.mediashout import MediaShoutImport from .importers.mediashout import MediaShoutImport
HAS_MEDIASHOUT = True HAS_MEDIASHOUT = True
except ImportError: except ImportError:
log.exception('Error importing %s', 'MediaShoutImport') log.exception('Error importing %s', 'MediaShoutImport')
HAS_WORSHIPCENTERPRO = False HAS_WORSHIPCENTERPRO = False
if os.name == 'nt': if is_win():
try: try:
from .importers.worshipcenterpro import WorshipCenterProImport from .importers.worshipcenterpro import WorshipCenterProImport
HAS_WORSHIPCENTERPRO = True HAS_WORSHIPCENTERPRO = True
@ -290,9 +290,9 @@ class SongFormat(object):
}, },
ProPresenter: { ProPresenter: {
'class': ProPresenterImport, 'class': ProPresenterImport,
'name': 'ProPresenter', 'name': 'ProPresenter 4',
'prefix': 'proPresenter', 'prefix': 'proPresenter',
'filter': '%s (*.pro4)' % translate('SongsPlugin.ImportWizardForm', 'ProPresenter Song Files') 'filter': '%s (*.pro4)' % translate('SongsPlugin.ImportWizardForm', 'ProPresenter 4 Song Files')
}, },
SongBeamer: { SongBeamer: {
'class': SongBeamerImport, 'class': SongBeamerImport,

View File

@ -27,5 +27,5 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
""" """
The :mod:`~openlp.plugins.songs.lib.import` module contains importers for the Songs plugin. The :mod:`~openlp.plugins.songs.lib.importers` module contains importers for the Songs plugin.
""" """

View File

@ -32,13 +32,14 @@ import time
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.common import is_win
from openlp.core.utils import get_uno_command, get_uno_instance from openlp.core.utils import get_uno_command, get_uno_instance
from openlp.core.lib import translate from openlp.core.lib import translate
from .songimport import SongImport from .songimport import SongImport
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
if os.name == 'nt': if is_win():
from win32com.client import Dispatch from win32com.client import Dispatch
NoConnectException = Exception NoConnectException = Exception
else: else:
@ -106,7 +107,7 @@ class OpenOfficeImport(SongImport):
Start OpenOffice.org process Start OpenOffice.org process
TODO: The presentation/Impress plugin may already have it running TODO: The presentation/Impress plugin may already have it running
""" """
if os.name == 'nt': if is_win():
self.start_ooo_process() self.start_ooo_process()
self.desktop = self.ooo_manager.createInstance('com.sun.star.frame.Desktop') self.desktop = self.ooo_manager.createInstance('com.sun.star.frame.Desktop')
else: else:
@ -133,7 +134,7 @@ class OpenOfficeImport(SongImport):
Start the OO Process Start the OO Process
""" """
try: try:
if os.name == 'nt': if is_win():
self.ooo_manager = Dispatch('com.sun.star.ServiceManager') self.ooo_manager = Dispatch('com.sun.star.ServiceManager')
self.ooo_manager._FlagAsMethod('Bridge_GetStruct') self.ooo_manager._FlagAsMethod('Bridge_GetStruct')
self.ooo_manager._FlagAsMethod('Bridge_GetValueObject') self.ooo_manager._FlagAsMethod('Bridge_GetValueObject')
@ -150,7 +151,7 @@ class OpenOfficeImport(SongImport):
Open the passed file in OpenOffice.org Impress Open the passed file in OpenOffice.org Impress
""" """
self.file_path = file_path self.file_path = file_path
if os.name == 'nt': if is_win():
url = file_path.replace('\\', '/') url = file_path.replace('\\', '/')
url = url.replace(':', '|').replace(' ', '%20') url = url.replace(':', '|').replace(' ', '%20')
url = 'file:///' + url url = 'file:///' + url

View File

@ -33,17 +33,20 @@ ProPresenter song files into the current installation database.
import os import os
import base64 import base64
import logging
from lxml import objectify from lxml import objectify
from openlp.core.ui.wizard import WizardStrings from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.songs.lib import strip_rtf from openlp.plugins.songs.lib import strip_rtf
from .songimport import SongImport from .songimport import SongImport
log = logging.getLogger(__name__)
class ProPresenterImport(SongImport): class ProPresenterImport(SongImport):
""" """
The :class:`ProPresenterImport` class provides OpenLP with the The :class:`ProPresenterImport` class provides OpenLP with the
ability to import ProPresenter song files. ability to import ProPresenter 4 song files.
""" """
def do_import(self): def do_import(self):
self.import_wizard.progress_bar.setMaximum(len(self.import_source)) self.import_wizard.progress_bar.setMaximum(len(self.import_source))
@ -52,11 +55,11 @@ class ProPresenterImport(SongImport):
return return
self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % os.path.basename(file_path)) self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % os.path.basename(file_path))
root = objectify.parse(open(file_path, 'rb')).getroot() root = objectify.parse(open(file_path, 'rb')).getroot()
self.process_song(root) self.process_song(root, file_path)
def process_song(self, root): def process_song(self, root, filename):
self.set_defaults() self.set_defaults()
self.title = root.get('CCLISongTitle') self.title = os.path.basename(filename).rstrip('.pro4')
self.copyright = root.get('CCLICopyrightInfo') self.copyright = root.get('CCLICopyrightInfo')
self.comments = root.get('notes') self.comments = root.get('notes')
self.ccli_number = root.get('CCLILicenseNumber') self.ccli_number = root.get('CCLILicenseNumber')
@ -67,6 +70,9 @@ class ProPresenterImport(SongImport):
count = 0 count = 0
for slide in root.slides.RVDisplaySlide: for slide in root.slides.RVDisplaySlide:
count += 1 count += 1
if not hasattr(slide.displayElements, 'RVTextElement'):
log.debug('No text found, may be an image slide')
continue
RTFData = slide.displayElements.RVTextElement.get('RTFData') RTFData = slide.displayElements.RVTextElement.get('RTFData')
rtf = base64.standard_b64decode(RTFData) rtf = base64.standard_b64decode(RTFData)
words, encoding = strip_rtf(rtf.decode()) words, encoding = strip_rtf(rtf.decode())

View File

@ -152,7 +152,7 @@ class SongShowPlusImport(SongImport):
if match: if match:
self.ccli_number = int(match.group()) self.ccli_number = int(match.group())
else: else:
log.warn("Can't parse CCLI Number from string: %s" % self.decode(data)) log.warning("Can't parse CCLI Number from string: %s" % self.decode(data))
elif block_key == VERSE: elif block_key == VERSE:
self.add_verse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no)) self.add_verse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no))
elif block_key == CHORUS: elif block_key == CHORUS:

View File

@ -37,12 +37,13 @@ import logging
import os import os
import re import re
from openlp.core.common import is_win
from .openoffice import OpenOfficeImport from .openoffice import OpenOfficeImport
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
if os.name == 'nt': if is_win():
from .openoffice import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH from .openoffice import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
RuntimeException = Exception RuntimeException = Exception
else: else:

View File

@ -58,7 +58,7 @@ class WorshipCenterProImport(SongImport):
try: try:
conn = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb)};DBQ=%s' % self.import_source) conn = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb)};DBQ=%s' % self.import_source)
except (pyodbc.DatabaseError, pyodbc.IntegrityError, pyodbc.InternalError, pyodbc.OperationalError) as e: except (pyodbc.DatabaseError, pyodbc.IntegrityError, pyodbc.InternalError, pyodbc.OperationalError) as e:
log.warn('Unable to connect the WorshipCenter Pro database %s. %s', self.import_source, str(e)) log.warning('Unable to connect the WorshipCenter Pro database %s. %s', self.import_source, str(e))
# Unfortunately no specific exception type # Unfortunately no specific exception type
self.log_error(self.import_source, translate('SongsPlugin.WorshipCenterProImport', self.log_error(self.import_source, translate('SongsPlugin.WorshipCenterProImport',
'Unable to connect the WorshipCenter Pro database.')) 'Unable to connect the WorshipCenter Pro database.'))

View File

@ -32,7 +32,8 @@ Functional tests to test the AppLocation class and related methods.
from unittest import TestCase from unittest import TestCase
from openlp.core.common import check_directory_exists, de_hump, trace_error_handler, translate from openlp.core.common import check_directory_exists, de_hump, trace_error_handler, translate, is_win, is_macosx, \
is_linux
from tests.functional import MagicMock, patch from tests.functional import MagicMock, patch
@ -139,3 +140,51 @@ class TestCommonFunctions(TestCase):
# THEN: the translated string should be returned, and the mocked function should have been called # THEN: the translated string should be returned, and the mocked function should have been called
mocked_translate.assert_called_with(context, text, comment, encoding, n) mocked_translate.assert_called_with(context, text, comment, encoding, n)
self.assertEqual('Translated string', result, 'The translated string should have been returned') self.assertEqual('Translated string', result, 'The translated string should have been returned')
def is_win_test(self):
"""
Test the is_win() function
"""
# GIVEN: Mocked out objects
with patch('openlp.core.common.os') as mocked_os, patch('openlp.core.common.sys') as mocked_sys:
# WHEN: The mocked os.name and sys.platform are set to 'nt' and 'win32' repectivly
mocked_os.name = 'nt'
mocked_sys.platform = 'win32'
# THEN: The three platform functions should perform properly
self.assertTrue(is_win(), 'is_win() should return True')
self.assertFalse(is_macosx(), 'is_macosx() should return False')
self.assertFalse(is_linux(), 'is_linux() should return False')
def is_macosx_test(self):
"""
Test the is_macosx() function
"""
# GIVEN: Mocked out objects
with patch('openlp.core.common.os') as mocked_os, patch('openlp.core.common.sys') as mocked_sys:
# WHEN: The mocked os.name and sys.platform are set to 'posix' and 'darwin' repectivly
mocked_os.name = 'posix'
mocked_sys.platform = 'darwin'
# THEN: The three platform functions should perform properly
self.assertTrue(is_macosx(), 'is_macosx() should return True')
self.assertFalse(is_win(), 'is_win() should return False')
self.assertFalse(is_linux(), 'is_linux() should return False')
def is_linux_test(self):
"""
Test the is_linux() function
"""
# GIVEN: Mocked out objects
with patch('openlp.core.common.os') as mocked_os, patch('openlp.core.common.sys') as mocked_sys:
# WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectivly
mocked_os.name = 'posix'
mocked_sys.platform = 'linux3'
# THEN: The three platform functions should perform properly
self.assertTrue(is_linux(), 'is_linux() should return True')
self.assertFalse(is_win(), 'is_win() should return False')
self.assertFalse(is_macosx(), 'is_macosx() should return False')

View File

@ -5,7 +5,7 @@ from unittest import TestCase
from openlp.core.common import UiStrings from openlp.core.common import UiStrings
from openlp.core.lib.filedialog import FileDialog from openlp.core.lib.filedialog import FileDialog
from tests.functional import MagicMock, patch from tests.functional import MagicMock, call, patch
class TestFileDialog(TestCase): class TestFileDialog(TestCase):
@ -65,11 +65,9 @@ class TestFileDialog(TestCase):
# THEN: os.path.exists should have been called with known args. QmessageBox.information should have been # THEN: os.path.exists should have been called with known args. QmessageBox.information should have been
# called. The returned result should correlate with the input. # called. The returned result should correlate with the input.
self.mocked_os.path.exists.assert_callde_with('/Valid File') call_list = [call('/Valid File'), call('/url%20encoded%20file%20%231'), call('/url encoded file #1'),
self.mocked_os.path.exists.assert_callde_with('/url%20encoded%20file%20%231') call('/non-existing'), call('/non-existing')]
self.mocked_os.path.exists.assert_callde_with('/url encoded file #1') self.mocked_os.path.exists.assert_has_calls(call_list)
self.mocked_os.path.exists.assert_callde_with('/non-existing')
self.mocked_os.path.exists.assert_callde_with('/non-existing')
self.mocked_qt_gui.QmessageBox.information.called_with(self.mocked_parent, UiStrings().FileNotFound, self.mocked_qt_gui.QmessageBox.information.called_with(self.mocked_parent, UiStrings().FileNotFound,
UiStrings().FileNotFoundMessage % '/non-existing') UiStrings().FileNotFoundMessage % '/non-existing')
self.assertEqual(result, ['/Valid File', '/url encoded file #1'], 'The returned file list is incorrect') self.assertEqual(result, ['/Valid File', '/url encoded file #1'], 'The returned file list is incorrect')

View File

@ -31,7 +31,8 @@ Package to test the openlp.core.ui.slidecontroller package.
""" """
from unittest import TestCase from unittest import TestCase
from openlp.core.common import Registry from openlp.core.common import Registry, ThemeLevel
from openlp.core.lib import ServiceItem, ServiceItemType, ItemCapabilities
from openlp.core.ui import ServiceManager from openlp.core.ui import ServiceManager
from tests.interfaces import MagicMock, patch from tests.interfaces import MagicMock, patch
@ -89,3 +90,466 @@ class TestServiceManager(TestCase):
self.assertEqual('txt' in service_manager.suffixes, True, 'The suffix txt should be in the list') self.assertEqual('txt' in service_manager.suffixes, True, 'The suffix txt should be in the list')
self.assertEqual('ppt' in service_manager.suffixes, True, 'The suffix ppt should be in the list') self.assertEqual('ppt' in service_manager.suffixes, True, 'The suffix ppt should be in the list')
self.assertEqual('pptx' in service_manager.suffixes, True, 'The suffix pptx should be in the list') self.assertEqual('pptx' in service_manager.suffixes, True, 'The suffix pptx should be in the list')
def build_context_menu_test(self):
"""
Test the creation of a context menu from a null service item.
"""
# GIVEN: A new service manager instance and a default service item.
service_manager = ServiceManager(None)
item = MagicMock()
item.parent.return_value = False
item.data.return_value = 0
service_manager.service_manager_list = MagicMock()
service_manager.service_manager_list.itemAt.return_value = item
service_item = ServiceItem(None)
service_manager.service_items.insert(1, {'service_item': service_item})
service_manager.edit_action = MagicMock()
service_manager.rename_action = MagicMock()
service_manager.create_custom_action = MagicMock()
service_manager.maintain_action = MagicMock()
service_manager.notes_action = MagicMock()
service_manager.time_action = MagicMock()
service_manager.auto_start_action = MagicMock()
service_manager.auto_play_slides_menu = MagicMock()
service_manager.auto_play_slides_once = MagicMock()
service_manager.auto_play_slides_loop = MagicMock()
service_manager.timed_slide_interval = MagicMock()
service_manager.theme_menu = MagicMock()
service_manager.menu = MagicMock()
# WHEN I define a context menu
service_manager.context_menu(1)
# THEN the following calls should have occurred.
self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have been called once')
self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have been called once')
self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have been called once')
self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have been called once')
self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have been called once')
self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have been called once')
self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have been called once')
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1,
'Should have been called once')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1,
'Should have been called once')
def build_song_context_menu_test(self):
"""
Test the creation of a context menu from service item of type text from Songs.
"""
# GIVEN: A new service manager instance and a default service item.
mocked_renderer = MagicMock()
mocked_renderer.theme_level = ThemeLevel.Song
Registry().register('plugin_manager', MagicMock())
Registry().register('renderer', mocked_renderer)
service_manager = ServiceManager(None)
item = MagicMock()
item.parent.return_value = False
item.data.return_value = 0
service_manager.service_manager_list = MagicMock()
service_manager.service_manager_list.itemAt.return_value = item
service_item = ServiceItem(None)
service_item.add_capability(ItemCapabilities.CanEdit)
service_item.add_capability(ItemCapabilities.CanPreview)
service_item.add_capability(ItemCapabilities.CanLoop)
service_item.add_capability(ItemCapabilities.OnLoadUpdate)
service_item.add_capability(ItemCapabilities.AddIfNewItem)
service_item.add_capability(ItemCapabilities.CanSoftBreak)
service_item.service_item_type = ServiceItemType.Text
service_item.edit_id = 1
service_item._display_frames.append(MagicMock())
service_manager.service_items.insert(1, {'service_item': service_item})
service_manager.edit_action = MagicMock()
service_manager.rename_action = MagicMock()
service_manager.create_custom_action = MagicMock()
service_manager.maintain_action = MagicMock()
service_manager.notes_action = MagicMock()
service_manager.time_action = MagicMock()
service_manager.auto_start_action = MagicMock()
service_manager.auto_play_slides_menu = MagicMock()
service_manager.auto_play_slides_once = MagicMock()
service_manager.auto_play_slides_loop = MagicMock()
service_manager.timed_slide_interval = MagicMock()
service_manager.theme_menu = MagicMock()
service_manager.menu = MagicMock()
# WHEN I define a context menu
service_manager.context_menu(1)
# THEN the following calls should have occurred.
self.assertEquals(service_manager.edit_action.setVisible.call_count, 2, 'Should have be called twice')
self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 2,
'Should have be called twice')
# THEN we add a 2nd display frame
service_item._display_frames.append(MagicMock())
service_manager.context_menu(1)
# THEN the following additional calls should have occurred.
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 2,
'Should have be called twice')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once')
def build_bible_context_menu_test(self):
"""
Test the creation of a context menu from service item of type text from Bibles.
"""
# GIVEN: A new service manager instance and a default service item.
mocked_renderer = MagicMock()
mocked_renderer.theme_level = ThemeLevel.Song
Registry().register('plugin_manager', MagicMock())
Registry().register('renderer', mocked_renderer)
service_manager = ServiceManager(None)
item = MagicMock()
item.parent.return_value = False
item.data.return_value = 0
service_manager.service_manager_list = MagicMock()
service_manager.service_manager_list.itemAt.return_value = item
service_item = ServiceItem(None)
service_item.add_capability(ItemCapabilities.NoLineBreaks)
service_item.add_capability(ItemCapabilities.CanPreview)
service_item.add_capability(ItemCapabilities.CanLoop)
service_item.add_capability(ItemCapabilities.CanWordSplit)
service_item.add_capability(ItemCapabilities.CanEditTitle)
service_item.service_item_type = ServiceItemType.Text
service_item.edit_id = 1
service_item._display_frames.append(MagicMock())
service_manager.service_items.insert(1, {'service_item': service_item})
service_manager.edit_action = MagicMock()
service_manager.rename_action = MagicMock()
service_manager.create_custom_action = MagicMock()
service_manager.maintain_action = MagicMock()
service_manager.notes_action = MagicMock()
service_manager.time_action = MagicMock()
service_manager.auto_start_action = MagicMock()
service_manager.auto_play_slides_menu = MagicMock()
service_manager.auto_play_slides_once = MagicMock()
service_manager.auto_play_slides_loop = MagicMock()
service_manager.timed_slide_interval = MagicMock()
service_manager.theme_menu = MagicMock()
service_manager.menu = MagicMock()
# WHEN I define a context menu
service_manager.context_menu(1)
# THEN the following calls should have occurred.
self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.rename_action.setVisible.call_count, 2, 'Should have be called twice')
self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 2,
'Should have be called twice')
# THEN we add a 2nd display frame
service_item._display_frames.append(MagicMock())
service_manager.context_menu(1)
# THEN the following additional calls should have occurred.
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 2,
'Should have be called twice')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once')
def build_custom_context_menu_test(self):
"""
Test the creation of a context menu from service item of type text from Custom.
"""
# GIVEN: A new service manager instance and a default service item.
mocked_renderer = MagicMock()
mocked_renderer.theme_level = ThemeLevel.Song
Registry().register('plugin_manager', MagicMock())
Registry().register('renderer', mocked_renderer)
service_manager = ServiceManager(None)
item = MagicMock()
item.parent.return_value = False
item.data.return_value = 0
service_manager.service_manager_list = MagicMock()
service_manager.service_manager_list.itemAt.return_value = item
service_item = ServiceItem(None)
service_item.add_capability(ItemCapabilities.CanEdit)
service_item.add_capability(ItemCapabilities.CanPreview)
service_item.add_capability(ItemCapabilities.CanLoop)
service_item.add_capability(ItemCapabilities.CanSoftBreak)
service_item.add_capability(ItemCapabilities.OnLoadUpdate)
service_item.service_item_type = ServiceItemType.Text
service_item.edit_id = 1
service_item._display_frames.append(MagicMock())
service_manager.service_items.insert(1, {'service_item': service_item})
service_manager.edit_action = MagicMock()
service_manager.rename_action = MagicMock()
service_manager.create_custom_action = MagicMock()
service_manager.maintain_action = MagicMock()
service_manager.notes_action = MagicMock()
service_manager.time_action = MagicMock()
service_manager.auto_start_action = MagicMock()
service_manager.auto_play_slides_menu = MagicMock()
service_manager.auto_play_slides_once = MagicMock()
service_manager.auto_play_slides_loop = MagicMock()
service_manager.timed_slide_interval = MagicMock()
service_manager.theme_menu = MagicMock()
service_manager.menu = MagicMock()
# WHEN I define a context menu
service_manager.context_menu(1)
# THEN the following calls should have occurred.
self.assertEquals(service_manager.edit_action.setVisible.call_count, 2, 'Should have be called twice')
self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 2,
'Should have be called twice')
# THEN we add a 2nd display frame
service_item._display_frames.append(MagicMock())
service_manager.context_menu(1)
# THEN the following additional calls should have occurred.
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 2,
'Should have be called twice')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once')
def build_image_context_menu_test(self):
"""
Test the creation of a context menu from service item of type Image from Image.
"""
# GIVEN: A new service manager instance and a default service item.
Registry().register('plugin_manager', MagicMock())
Registry().register('renderer', MagicMock())
service_manager = ServiceManager(None)
item = MagicMock()
item.parent.return_value = False
item.data.return_value = 0
service_manager.service_manager_list = MagicMock()
service_manager.service_manager_list.itemAt.return_value = item
service_item = ServiceItem(None)
service_item.add_capability(ItemCapabilities.CanMaintain)
service_item.add_capability(ItemCapabilities.CanPreview)
service_item.add_capability(ItemCapabilities.CanLoop)
service_item.add_capability(ItemCapabilities.CanAppend)
service_item.add_capability(ItemCapabilities.CanEditTitle)
service_item.service_item_type = ServiceItemType.Image
service_item.edit_id = 1
service_item._raw_frames.append(MagicMock())
service_manager.service_items.insert(1, {'service_item': service_item})
service_manager.edit_action = MagicMock()
service_manager.rename_action = MagicMock()
service_manager.create_custom_action = MagicMock()
service_manager.maintain_action = MagicMock()
service_manager.notes_action = MagicMock()
service_manager.time_action = MagicMock()
service_manager.auto_start_action = MagicMock()
service_manager.auto_play_slides_menu = MagicMock()
service_manager.auto_play_slides_once = MagicMock()
service_manager.auto_play_slides_loop = MagicMock()
service_manager.timed_slide_interval = MagicMock()
service_manager.theme_menu = MagicMock()
service_manager.menu = MagicMock()
# WHEN I define a context menu
service_manager.context_menu(1)
# THEN the following calls should have occurred.
self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.rename_action.setVisible.call_count, 2, 'Should have be called twice')
self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.maintain_action.setVisible.call_count, 2, 'Should have be called twice')
self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
# THEN we add a 2nd display frame and regenerate the menu.
service_item._raw_frames.append(MagicMock())
service_manager.context_menu(1)
# THEN the following additional calls should have occurred.
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 2,
'Should have be called twice')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once')
def build_media_context_menu_test(self):
"""
Test the creation of a context menu from service item of type Command from Media.
"""
# GIVEN: A new service manager instance and a default service item.
Registry().register('plugin_manager', MagicMock())
Registry().register('renderer', MagicMock())
service_manager = ServiceManager(None)
item = MagicMock()
item.parent.return_value = False
item.data.return_value = 0
service_manager.service_manager_list = MagicMock()
service_manager.service_manager_list.itemAt.return_value = item
service_item = ServiceItem(None)
service_item.add_capability(ItemCapabilities.CanAutoStartForLive)
service_item.add_capability(ItemCapabilities.CanEditTitle)
service_item.add_capability(ItemCapabilities.RequiresMedia)
service_item.service_item_type = ServiceItemType.Command
service_item.edit_id = 1
service_item._raw_frames.append(MagicMock())
service_manager.service_items.insert(1, {'service_item': service_item})
service_manager.edit_action = MagicMock()
service_manager.rename_action = MagicMock()
service_manager.create_custom_action = MagicMock()
service_manager.maintain_action = MagicMock()
service_manager.notes_action = MagicMock()
service_manager.time_action = MagicMock()
service_manager.auto_start_action = MagicMock()
service_manager.auto_play_slides_menu = MagicMock()
service_manager.auto_play_slides_once = MagicMock()
service_manager.auto_play_slides_loop = MagicMock()
service_manager.timed_slide_interval = MagicMock()
service_manager.theme_menu = MagicMock()
service_manager.menu = MagicMock()
# WHEN I define a context menu
service_manager.context_menu(1)
# THEN the following calls should have occurred.
self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.rename_action.setVisible.call_count, 2, 'Should have be called twice')
self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 2, 'Should have be called twice')
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
# THEN I change the length of the media and regenerate the menu.
service_item.set_media_length(5)
service_manager.context_menu(1)
# THEN the following additional calls should have occurred.
self.assertEquals(service_manager.time_action.setVisible.call_count, 3, 'Should have be called three times')
def build_presentation_pdf_context_menu_test(self):
"""
Test the creation of a context menu from service item of type Command with PDF from Presentation.
"""
# GIVEN: A new service manager instance and a default service item.
Registry().register('plugin_manager', MagicMock())
Registry().register('renderer', MagicMock())
service_manager = ServiceManager(None)
item = MagicMock()
item.parent.return_value = False
item.data.return_value = 0
service_manager.service_manager_list = MagicMock()
service_manager.service_manager_list.itemAt.return_value = item
service_item = ServiceItem(None)
service_item.add_capability(ItemCapabilities.CanMaintain)
service_item.add_capability(ItemCapabilities.CanPreview)
service_item.add_capability(ItemCapabilities.CanLoop)
service_item.add_capability(ItemCapabilities.CanAppend)
service_item.service_item_type = ServiceItemType.Command
service_item.edit_id = 1
service_item._raw_frames.append(MagicMock())
service_manager.service_items.insert(1, {'service_item': service_item})
service_manager.edit_action = MagicMock()
service_manager.rename_action = MagicMock()
service_manager.create_custom_action = MagicMock()
service_manager.maintain_action = MagicMock()
service_manager.notes_action = MagicMock()
service_manager.time_action = MagicMock()
service_manager.auto_start_action = MagicMock()
service_manager.auto_play_slides_menu = MagicMock()
service_manager.auto_play_slides_once = MagicMock()
service_manager.auto_play_slides_loop = MagicMock()
service_manager.timed_slide_interval = MagicMock()
service_manager.theme_menu = MagicMock()
service_manager.menu = MagicMock()
# WHEN I define a context menu
service_manager.context_menu(1)
# THEN the following calls should have occurred.
self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.maintain_action.setVisible.call_count, 2, 'Should have be called twice')
self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
def build_presentation_non_pdf_context_menu_test(self):
"""
Test the creation of a context menu from service item of type Command with Impress from Presentation.
"""
# GIVEN: A new service manager instance and a default service item.
Registry().register('plugin_manager', MagicMock())
Registry().register('renderer', MagicMock())
service_manager = ServiceManager(None)
item = MagicMock()
item.parent.return_value = False
item.data.return_value = 0
service_manager.service_manager_list = MagicMock()
service_manager.service_manager_list.itemAt.return_value = item
service_item = ServiceItem(None)
service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay)
service_item.service_item_type = ServiceItemType.Command
service_item.edit_id = 1
service_item._raw_frames.append(MagicMock())
service_manager.service_items.insert(1, {'service_item': service_item})
service_manager.edit_action = MagicMock()
service_manager.rename_action = MagicMock()
service_manager.create_custom_action = MagicMock()
service_manager.maintain_action = MagicMock()
service_manager.notes_action = MagicMock()
service_manager.time_action = MagicMock()
service_manager.auto_start_action = MagicMock()
service_manager.auto_play_slides_menu = MagicMock()
service_manager.auto_play_slides_once = MagicMock()
service_manager.auto_play_slides_loop = MagicMock()
service_manager.timed_slide_interval = MagicMock()
service_manager.theme_menu = MagicMock()
service_manager.menu = MagicMock()
# WHEN I define a context menu
service_manager.context_menu(1)
# THEN the following calls should have occurred.
self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')
self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called')
self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1,
'Should have be called once')

View File

@ -52,3 +52,5 @@ class TestProPresenterFileImport(SongImportTestHelper):
""" """
self.file_import([os.path.join(TEST_PATH, 'Amazing Grace.pro4')], self.file_import([os.path.join(TEST_PATH, 'Amazing Grace.pro4')],
self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json'))) self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json')))
self.file_import([os.path.join(TEST_PATH, 'Vaste Grond.pro4')],
self.load_external_result_data(os.path.join(TEST_PATH, 'Vaste Grond.json')))

View File

@ -59,6 +59,19 @@ class TestBibleHTTP(TestCase):
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
assert len(books) == 66, 'The bible should not have had any books added or removed' assert len(books) == 66, 'The bible should not have had any books added or removed'
def bible_gateway_extract_books_support_redirect_test(self):
"""
Test the Bible Gateway retrieval of book list for DN1933 bible with redirect (bug 1251437)
"""
# GIVEN: A new Bible Gateway extraction class
handler = BGExtract()
# WHEN: The Books list is called
books = handler.get_books_from_http('DN1933')
# THEN: We should get back a valid service item
assert len(books) == 66, 'This bible should have 66 books'
def bible_gateway_extract_verse_test(self): def bible_gateway_extract_verse_test(self):
""" """
Test the Bible Gateway retrieval of verse list for NIV bible John 3 Test the Bible Gateway retrieval of verse list for NIV bible John 3

View File

@ -0,0 +1,34 @@
{
"title": "Vaste Grond",
"verse_order_list": [],
"verses": [
[
"God voor U is niets onmogelijk\nHoe ongelofelijk\nU heeft alles in de hand",
"v1"
],
[
"U bent God en trekt Uw eigen plan\nU bent voor niemand bang\nVoor niets en niemand bang",
"v2"
],
[
"U houd me vast en geeft me moed\nOm door te gaan als ik niet durf\nIk wil van U zijn",
"v3"
],
[
"U geeft me kracht, en bent de vaste grond\nwaarop ik stevig sta\nik wil van U zijn, voor altijd van U zijn\nO God.",
"v4"
],
[
"Grote God, U bent uitzonderlijk\nen ondoorgrondelijk\nU biedt Uw liefde aan",
"v5"
],
[
"Wie ben ik, dat U mij ziet staan\nen met mij om wilt gaan?\nIk kan U niet weerstaan",
"v6"
],
[
"Onweerstaanbaar,\nonweerstaanbare God",
"v7"
]
]
}

File diff suppressed because one or more lines are too long