This commit is contained in:
Samuel Mehrbrodt 2014-04-14 21:46:02 +02:00
commit e7af43af4a
62 changed files with 589 additions and 263 deletions

View File

@ -30,7 +30,6 @@
The :mod:`openlp` module contains all the project produced OpenLP functionality The :mod:`openlp` module contains all the project produced OpenLP functionality
""" """
import openlp.core from openlp import core, plugins
import openlp.plugins
__all__ = ['core', 'plugins'] __all__ = ['core', 'plugins']

View File

@ -38,7 +38,7 @@ import traceback
from PyQt4 import QtCore from PyQt4 import QtCore
log = logging.getLogger(__name__+'.__init__') log = logging.getLogger(__name__ + '.__init__')
FIRST_CAMEL_REGEX = re.compile('(.)([A-Z][a-z]+)') FIRST_CAMEL_REGEX = re.compile('(.)([A-Z][a-z]+)')
@ -76,6 +76,9 @@ def check_directory_exists(directory, do_not_log=False):
def get_frozen_path(frozen_option, non_frozen_option): def get_frozen_path(frozen_option, non_frozen_option):
""" """
Return a path based on the system status. Return a path based on the system status.
:param frozen_option:
:param non_frozen_option:
""" """
if hasattr(sys, 'frozen') and sys.frozen == 1: if hasattr(sys, 'frozen') and sys.frozen == 1:
return frozen_option return frozen_option

View File

@ -39,7 +39,7 @@ from PyQt4 import QtCore, QtGui, Qt
from openlp.core.common import translate from openlp.core.common import translate
log = logging.getLogger(__name__+'.__init__') log = logging.getLogger(__name__ + '.__init__')
class ServiceItemContext(object): class ServiceItemContext(object):

View File

@ -168,29 +168,29 @@ class MediaManagerItem(QtGui.QWidget, RegistryProperties):
Create buttons for the media item toolbar Create buttons for the media item toolbar
""" """
toolbar_actions = [] toolbar_actions = []
## Import Button ## # Import Button
if self.has_import_icon: if self.has_import_icon:
toolbar_actions.append(['Import', StringContent.Import, toolbar_actions.append(['Import', StringContent.Import,
':/general/general_import.png', self.on_import_click]) ':/general/general_import.png', self.on_import_click])
## Load Button ## # Load Button
if self.has_file_icon: if self.has_file_icon:
toolbar_actions.append(['Load', StringContent.Load, ':/general/general_open.png', self.on_file_click]) toolbar_actions.append(['Load', StringContent.Load, ':/general/general_open.png', self.on_file_click])
## New Button ## # New Button
if self.has_new_icon: if self.has_new_icon:
toolbar_actions.append(['New', StringContent.New, ':/general/general_new.png', self.on_new_click]) toolbar_actions.append(['New', StringContent.New, ':/general/general_new.png', self.on_new_click])
## Edit Button ## # Edit Button
if self.has_edit_icon: if self.has_edit_icon:
toolbar_actions.append(['Edit', StringContent.Edit, ':/general/general_edit.png', self.on_edit_click]) toolbar_actions.append(['Edit', StringContent.Edit, ':/general/general_edit.png', self.on_edit_click])
## Delete Button ## # Delete Button
if self.has_delete_icon: if self.has_delete_icon:
toolbar_actions.append(['Delete', StringContent.Delete, toolbar_actions.append(['Delete', StringContent.Delete,
':/general/general_delete.png', self.on_delete_click]) ':/general/general_delete.png', self.on_delete_click])
## Preview ## # Preview
toolbar_actions.append(['Preview', StringContent.Preview, toolbar_actions.append(['Preview', StringContent.Preview,
':/general/general_preview.png', self.on_preview_click]) ':/general/general_preview.png', self.on_preview_click])
## Live Button ## # Live Button
toolbar_actions.append(['Live', StringContent.Live, ':/general/general_live.png', self.on_live_click]) toolbar_actions.append(['Live', StringContent.Live, ':/general/general_live.png', self.on_live_click])
## Add to service Button ## # Add to service Button
toolbar_actions.append(['Service', StringContent.Service, ':/general/general_add.png', self.on_add_click]) toolbar_actions.append(['Service', StringContent.Service, ':/general/general_add.png', self.on_add_click])
for action in toolbar_actions: for action in toolbar_actions:
if action[0] == StringContent.Preview: if action[0] == StringContent.Preview:

View File

@ -101,7 +101,7 @@ class Plugin(QtCore.QObject, RegistryProperties):
``add_import_menu_item(import_menu)`` ``add_import_menu_item(import_menu)``
Add an item to the Import menu. Add an item to the Import menu.
``add_export_menu_Item(export_menu)`` ``add_export_menu_item(export_menu)``
Add an item to the Export menu. Add an item to the Export menu.
``create_settings_tab()`` ``create_settings_tab()``
@ -226,7 +226,7 @@ class Plugin(QtCore.QObject, RegistryProperties):
""" """
pass pass
def add_export_menu_Item(self, export_menu): def add_export_menu_item(self, export_menu):
""" """
Create a menu item and add it to the "Export" menu. Create a menu item and add it to the "Export" menu.
@ -329,22 +329,24 @@ class Plugin(QtCore.QObject, RegistryProperties):
def set_plugin_ui_text_strings(self, tooltips): def set_plugin_ui_text_strings(self, tooltips):
""" """
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
:param tooltips:
""" """
## Load Action ## # Load Action
self.__set_name_text_string(StringContent.Load, UiStrings().Load, tooltips['load']) self.__set_name_text_string(StringContent.Load, UiStrings().Load, tooltips['load'])
## Import Action ## # Import Action
self.__set_name_text_string(StringContent.Import, UiStrings().Import, tooltips['import']) self.__set_name_text_string(StringContent.Import, UiStrings().Import, tooltips['import'])
## New Action ## # New Action
self.__set_name_text_string(StringContent.New, UiStrings().Add, tooltips['new']) self.__set_name_text_string(StringContent.New, UiStrings().Add, tooltips['new'])
## Edit Action ## # Edit Action
self.__set_name_text_string(StringContent.Edit, UiStrings().Edit, tooltips['edit']) self.__set_name_text_string(StringContent.Edit, UiStrings().Edit, tooltips['edit'])
## Delete Action ## # Delete Action
self.__set_name_text_string(StringContent.Delete, UiStrings().Delete, tooltips['delete']) self.__set_name_text_string(StringContent.Delete, UiStrings().Delete, tooltips['delete'])
## Preview Action ## # Preview Action
self.__set_name_text_string(StringContent.Preview, UiStrings().Preview, tooltips['preview']) self.__set_name_text_string(StringContent.Preview, UiStrings().Preview, tooltips['preview'])
## Send Live Action ## # Send Live Action
self.__set_name_text_string(StringContent.Live, UiStrings().Live, tooltips['live']) self.__set_name_text_string(StringContent.Live, UiStrings().Live, tooltips['live'])
## Add to Service Action ## # Add to Service Action
self.__set_name_text_string(StringContent.Service, UiStrings().Service, tooltips['service']) self.__set_name_text_string(StringContent.Service, UiStrings().Service, tooltips['service'])
def __set_name_text_string(self, name, title, tooltip): def __set_name_text_string(self, name, title, tooltip):

View File

@ -161,7 +161,7 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties):
""" """
for plugin in self.plugins: for plugin in self.plugins:
if plugin.status is not PluginStatus.Disabled: if plugin.status is not PluginStatus.Disabled:
plugin.add_export_menu_Item(self.main_window.file_export_menu) plugin.add_export_menu_item(self.main_window.file_export_menu)
def hook_tools_menu(self): def hook_tools_menu(self):
""" """

View File

@ -108,6 +108,9 @@ class ItemCapabilities(object):
``CanAutoStartForLive`` ``CanAutoStartForLive``
The capability to ignore the do not play if display blank flag. The capability to ignore the do not play if display blank flag.
``CanEditTitle``
The capability to edit the title of the item
""" """
CanPreview = 1 CanPreview = 1
CanEdit = 2 CanEdit = 2
@ -125,6 +128,7 @@ class ItemCapabilities(object):
CanWordSplit = 14 CanWordSplit = 14
HasBackgroundAudio = 15 HasBackgroundAudio = 15
CanAutoStartForLive = 16 CanAutoStartForLive = 16
CanEditTitle = 17
class ServiceItem(RegistryProperties): class ServiceItem(RegistryProperties):
@ -383,7 +387,7 @@ class ServiceItem(RegistryProperties):
self.will_auto_start = header.get('will_auto_start', False) self.will_auto_start = header.get('will_auto_start', False)
self.processor = header.get('processor', None) self.processor = header.get('processor', None)
self.has_original_files = True self.has_original_files = True
#TODO Remove me in 2,3 build phase # TODO: Remove me in 2,3 build phase
if self.is_capable(ItemCapabilities.HasDetailedTitleDisplay): if self.is_capable(ItemCapabilities.HasDetailedTitleDisplay):
self.capabilities.remove(ItemCapabilities.HasDetailedTitleDisplay) self.capabilities.remove(ItemCapabilities.HasDetailedTitleDisplay)
self.processor = self.title self.processor = self.title
@ -423,7 +427,7 @@ class ServiceItem(RegistryProperties):
""" """
Returns the title of the service item. Returns the title of the service item.
""" """
if self.is_text(): if self.is_text() or ItemCapabilities.CanEditTitle in self.capabilities:
return self.title return self.title
else: else:
if len(self._raw_frames) > 1: if len(self._raw_frames) > 1:

View File

@ -95,15 +95,15 @@ class Ui_ExceptionDialog(object):
Translate the widgets on the fly. Translate the widgets on the fly.
""" """
exception_dialog.setWindowTitle(translate('OpenLP.ExceptionDialog', 'Error Occurred')) exception_dialog.setWindowTitle(translate('OpenLP.ExceptionDialog', 'Error Occurred'))
self.description_explanation.setText(translate('OpenLP.ExceptionDialog', self.description_explanation.setText(
'Please enter a description of what you were doing to cause this error ' translate('OpenLP.ExceptionDialog', 'Please enter a description of what you were doing to cause this error '
'\n(Minimum 20 characters)')) '\n(Minimum 20 characters)'))
self.message_label.setText(translate('OpenLP.ExceptionDialog', 'Oops! ' self.message_label.setText(
'OpenLP hit a problem, and couldn\'t recover. The text in the box ' translate('OpenLP.ExceptionDialog', 'Oops! OpenLP hit a problem, and couldn\'t recover. The text in the '
'below contains information that might be helpful to the OpenLP ' 'box below contains information that might be helpful to the OpenLP '
'developers, so please e-mail it to bugs@openlp.org, along with a ' 'developers, so please e-mail it to bugs@openlp.org, along with a '
'detailed description of what you were doing when the problem ' 'detailed description of what you were doing when the problem '
'occurred.')) 'occurred.'))
self.send_report_button.setText(translate('OpenLP.ExceptionDialog', 'Send E-Mail')) self.send_report_button.setText(translate('OpenLP.ExceptionDialog', 'Send E-Mail'))
self.save_report_button.setText(translate('OpenLP.ExceptionDialog', 'Save to File')) self.save_report_button.setText(translate('OpenLP.ExceptionDialog', 'Save to File'))
self.attach_tile_button.setText(translate('OpenLP.ExceptionDialog', 'Attach File')) self.attach_tile_button.setText(translate('OpenLP.ExceptionDialog', 'Attach File'))

View File

@ -211,9 +211,9 @@ class Ui_FirstTimeWizard(object):
first_time_wizard.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'First Time Wizard')) first_time_wizard.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'First Time Wizard'))
self.title_label.setText('<span style="font-size:14pt; font-weight:600;">%s</span>' % self.title_label.setText('<span style="font-size:14pt; font-weight:600;">%s</span>' %
translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard')) translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard'))
self.information_label.setText(translate('OpenLP.FirstTimeWizard', self.information_label.setText(
'This wizard will help you to configure OpenLP for initial use. ' translate('OpenLP.FirstTimeWizard', 'This wizard will help you to configure OpenLP for initial use. '
'Click the next button below to start.')) 'Click the next button below to start.'))
self.plugin_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Activate required Plugins')) self.plugin_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Activate required Plugins'))
self.plugin_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select the Plugins you wish to use. ')) self.plugin_page.setSubTitle(translate('OpenLP.FirstTimeWizard', 'Select the Plugins you wish to use. '))
self.songs_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Songs')) self.songs_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Songs'))

View File

@ -63,7 +63,6 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont
self.services = FormattingTagController() self.services = FormattingTagController()
self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected) self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected)
self.new_button.clicked.connect(self.on_new_clicked) self.new_button.clicked.connect(self.on_new_clicked)
#self.save_button.clicked.connect(self.on_saved_clicked)
self.delete_button.clicked.connect(self.on_delete_clicked) self.delete_button.clicked.connect(self.on_delete_clicked)
self.tag_table_widget.currentCellChanged.connect(self.on_current_cell_changed) self.tag_table_widget.currentCellChanged.connect(self.on_current_cell_changed)
self.button_box.rejected.connect(self.close) self.button_box.rejected.connect(self.close)
@ -202,5 +201,4 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont
if errors: if errors:
QtGui.QMessageBox.warning(self, translate('OpenLP.FormattingTagForm', 'Validation Error'), errors, QtGui.QMessageBox.warning(self, translate('OpenLP.FormattingTagForm', 'Validation Error'), errors,
QtGui.QMessageBox.Ok) QtGui.QMessageBox.Ok)
#self.tag_table_widget.selectRow(pre_row - 1)
self.tag_table_widget.resizeRowsToContents() self.tag_table_widget.resizeRowsToContents()

View File

@ -56,29 +56,27 @@ from openlp.core.ui.firsttimeform import FirstTimeForm
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
MEDIA_MANAGER_STYLE = """ MEDIA_MANAGER_STYLE = """
QToolBox { QToolBox {
padding-bottom: 2px; padding-bottom: 2px;
} }
QToolBox::tab { QToolBox::tab {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 palette(button), stop: 0.5 palette(button), stop: 0 palette(button), stop: 1.0 palette(mid));
stop: 1.0 palette(mid)); border: 1px solid palette(mid);
border: 1px groove palette(mid); border-radius: 3px;
border-radius: 5px; }
} QToolBox::tab:selected {
QToolBox::tab:selected {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 palette(light), stop: 0.5 palette(midlight), stop: 0 palette(light), stop: 1.0 palette(button));
stop: 1.0 palette(dark)); border: 1px solid palette(mid);
border: 1px groove palette(dark);
font-weight: bold; font-weight: bold;
} }
""" """
PROGRESSBAR_STYLE = """ PROGRESSBAR_STYLE = """
QProgressBar{ QProgressBar{
height: 10px; height: 10px;
} }
""" """
@ -369,7 +367,7 @@ class Ui_MainWindow(object):
self.settings_menu.setTitle(translate('OpenLP.MainWindow', '&Settings')) self.settings_menu.setTitle(translate('OpenLP.MainWindow', '&Settings'))
self.settings_language_menu.setTitle(translate('OpenLP.MainWindow', '&Language')) self.settings_language_menu.setTitle(translate('OpenLP.MainWindow', '&Language'))
self.help_menu.setTitle(translate('OpenLP.MainWindow', '&Help')) self.help_menu.setTitle(translate('OpenLP.MainWindow', '&Help'))
self.media_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Media Manager')) self.media_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Library'))
self.service_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Service Manager')) self.service_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Service Manager'))
self.theme_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Theme Manager')) self.theme_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Theme Manager'))
self.file_new_item.setText(translate('OpenLP.MainWindow', '&New')) self.file_new_item.setText(translate('OpenLP.MainWindow', '&New'))
@ -396,12 +394,12 @@ class Ui_MainWindow(object):
self.settings_shortcuts_item.setText(translate('OpenLP.MainWindow', 'Configure &Shortcuts...')) self.settings_shortcuts_item.setText(translate('OpenLP.MainWindow', 'Configure &Shortcuts...'))
self.formatting_tag_item.setText(translate('OpenLP.MainWindow', 'Configure &Formatting Tags...')) self.formatting_tag_item.setText(translate('OpenLP.MainWindow', 'Configure &Formatting Tags...'))
self.settings_configure_item.setText(translate('OpenLP.MainWindow', '&Configure OpenLP...')) self.settings_configure_item.setText(translate('OpenLP.MainWindow', '&Configure OpenLP...'))
self.settings_export_item.setStatusTip(translate('OpenLP.MainWindow', self.settings_export_item.setStatusTip(
'Export OpenLP settings to a specified *.config file')) translate('OpenLP.MainWindow', 'Export OpenLP settings to a specified *.config file'))
self.settings_export_item.setText(translate('OpenLP.MainWindow', 'Settings')) self.settings_export_item.setText(translate('OpenLP.MainWindow', 'Settings'))
self.settings_import_item.setStatusTip(translate('OpenLP.MainWindow', self.settings_import_item.setStatusTip(
'Import OpenLP settings from a specified *.config file previously ' translate('OpenLP.MainWindow', 'Import OpenLP settings from a specified *.config file previously '
'exported on this or another machine')) 'exported on this or another machine'))
self.settings_import_item.setText(translate('OpenLP.MainWindow', 'Settings')) self.settings_import_item.setText(translate('OpenLP.MainWindow', 'Settings'))
self.view_media_manager_item.setText(translate('OpenLP.MainWindow', '&Media Manager')) self.view_media_manager_item.setText(translate('OpenLP.MainWindow', '&Media Manager'))
self.view_media_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Toggle Media Manager')) self.view_media_manager_item.setToolTip(translate('OpenLP.MainWindow', 'Toggle Media Manager'))
@ -598,13 +596,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
self.live_controller.display.setFocus() self.live_controller.display.setFocus()
self.activateWindow() self.activateWindow()
if self.arguments: if self.arguments:
args = [] self.open_cmd_line_files()
for a in self.arguments:
args.extend([a])
filename = args[0]
if not isinstance(filename, str):
filename = str(filename, sys.getfilesystemencoding())
self.service_manager_contents.load_file(filename)
elif Settings().value(self.general_settings_section + '/auto open'): elif Settings().value(self.general_settings_section + '/auto open'):
self.service_manager_contents.load_Last_file() self.service_manager_contents.load_Last_file()
self.timer_version_id = self.startTimer(1000) self.timer_version_id = self.startTimer(1000)
@ -868,7 +860,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
section = 'general' section = 'general'
section_key = section + "/" + key section_key = section + "/" + key
# Make sure it's a valid section for us. # Make sure it's a valid section for us.
if not section in setting_sections: if section not in setting_sections:
continue continue
# We have a good file, import it. # We have a good file, import it.
for section_key in import_keys: for section_key in import_keys:
@ -1364,3 +1356,17 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
if self.new_data_path == AppLocation.get_directory(AppLocation.DataDir): if self.new_data_path == AppLocation.get_directory(AppLocation.DataDir):
settings.remove('advanced/data path') settings.remove('advanced/data path')
self.application.set_normal_cursor() self.application.set_normal_cursor()
def open_cmd_line_files(self):
"""
Open files passed in through command line arguments
"""
args = []
for a in self.arguments:
args.extend([a])
for arg in args:
filename = arg
if not isinstance(filename, str):
filename = str(filename, sys.getfilesystemencoding())
if filename.endswith(('.osz', '.oszl')):
self.service_manager_contents.load_file(filename)

View File

@ -35,7 +35,7 @@ from openlp.core.common import Settings
from PyQt4 import QtCore from PyQt4 import QtCore
log = logging.getLogger(__name__+'.__init__') log = logging.getLogger(__name__ + '.__init__')
class MediaState(object): class MediaState(object):

View File

@ -137,7 +137,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
for player in list(self.media_players.values()): for player in list(self.media_players.values()):
if player.is_active: if player.is_active:
for item in player.audio_extensions_list: for item in player.audio_extensions_list:
if not item in self.audio_extensions_list: if item not in self.audio_extensions_list:
self.audio_extensions_list.append(item) self.audio_extensions_list.append(item)
suffix_list.append(item[2:]) suffix_list.append(item[2:])
self.video_extensions_list = [] self.video_extensions_list = []
@ -184,8 +184,8 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
return False return False
saved_players, overridden_player = get_media_players() saved_players, overridden_player = get_media_players()
invalid_media_players = \ invalid_media_players = \
[mediaPlayer for mediaPlayer in saved_players if not mediaPlayer in self.media_players or [media_player for media_player in saved_players if media_player not in self.media_players or
not self.media_players[mediaPlayer].check_available()] not self.media_players[media_player].check_available()]
if invalid_media_players: if invalid_media_players:
for invalidPlayer in invalid_media_players: for invalidPlayer in invalid_media_players:
saved_players.remove(invalidPlayer) saved_players.remove(invalidPlayer)

View File

@ -48,13 +48,13 @@ import sys
from inspect import getargspec from inspect import getargspec
__version__ = "N/A" __version__ = "N/A"
build_date = "Mon Apr 1 23:47:38 2013" build_date = "Tue Jul 2 10:35:53 2013"
if sys.version_info[0] > 2: if sys.version_info[0] > 2:
str = str str = str
str = str unicode = str
bytes = bytes bytes = bytes
str = (str, bytes) basestring = (str, bytes)
PYTHON3 = True PYTHON3 = True
def str_to_bytes(s): def str_to_bytes(s):
"""Translate string or bytes to bytes. """Translate string or bytes to bytes.
@ -73,14 +73,14 @@ if sys.version_info[0] > 2:
return b return b
else: else:
str = str str = str
str = str unicode = unicode
bytes = str bytes = str
str = str basestring = basestring
PYTHON3 = False PYTHON3 = False
def str_to_bytes(s): def str_to_bytes(s):
"""Translate string or bytes to bytes. """Translate string or bytes to bytes.
""" """
if isinstance(s, str): if isinstance(s, unicode):
return s.encode(sys.getfilesystemencoding()) return s.encode(sys.getfilesystemencoding())
else: else:
return s return s
@ -89,7 +89,7 @@ else:
"""Translate bytes to unicode string. """Translate bytes to unicode string.
""" """
if isinstance(b, str): if isinstance(b, str):
return str(b, sys.getfilesystemencoding()) return unicode(b, sys.getfilesystemencoding())
else: else:
return b return b
@ -110,7 +110,7 @@ def find_lib():
p = find_library('libvlc.dll') p = find_library('libvlc.dll')
if p is None: if p is None:
try: # some registry settings try: # some registry settings
import winreg as w # leaner than win32api, win32con import _winreg as w # leaner than win32api, win32con
for r in w.HKEY_LOCAL_MACHINE, w.HKEY_CURRENT_USER: for r in w.HKEY_LOCAL_MACHINE, w.HKEY_CURRENT_USER:
try: try:
r = w.OpenKey(r, 'Software\\VideoLAN\\VLC') r = w.OpenKey(r, 'Software\\VideoLAN\\VLC')
@ -168,7 +168,7 @@ class VLCException(Exception):
pass pass
try: try:
_Ints = (int, int) _Ints = (int, long)
except NameError: # no long in Python 3+ except NameError: # no long in Python 3+
_Ints = int _Ints = int
_Seqs = (list, tuple) _Seqs = (list, tuple)
@ -327,6 +327,9 @@ class _Enum(ctypes.c_uint):
n = self._enum_names_.get(self.value, '') or ('FIXME_(%r)' % (self.value,)) n = self._enum_names_.get(self.value, '') or ('FIXME_(%r)' % (self.value,))
return '.'.join((self.__class__.__name__, n)) return '.'.join((self.__class__.__name__, n))
def __hash__(self):
return self.value
def __repr__(self): def __repr__(self):
return '.'.join((self.__class__.__module__, self.__str__())) return '.'.join((self.__class__.__module__, self.__str__()))
@ -1294,7 +1297,7 @@ class Instance(_Ctype):
i = args[0] i = args[0]
if isinstance(i, _Ints): if isinstance(i, _Ints):
return _Constructor(cls, i) return _Constructor(cls, i)
elif isinstance(i, str): elif isinstance(i, basestring):
args = i.strip().split() args = i.strip().split()
elif isinstance(i, _Seqs): elif isinstance(i, _Seqs):
args = i args = i
@ -2078,7 +2081,7 @@ class MediaList(_Ctype):
@param mrl: a media instance or a MRL. @param mrl: a media instance or a MRL.
@return: 0 on success, -1 if the media list is read-only. @return: 0 on success, -1 if the media list is read-only.
""" """
if isinstance(mrl, str): if isinstance(mrl, basestring):
mrl = (self.get_instance() or get_default_instance()).media_new(mrl) mrl = (self.get_instance() or get_default_instance()).media_new(mrl)
return libvlc_media_list_add_media(self, mrl) return libvlc_media_list_add_media(self, mrl)
@ -3351,6 +3354,39 @@ def libvlc_event_type_name(event_type):
ctypes.c_char_p, ctypes.c_uint) ctypes.c_char_p, ctypes.c_uint)
return f(event_type) return f(event_type)
def libvlc_log_get_context(ctx):
'''Gets debugging informations about a log message: the name of the VLC module
emitting the message and the message location within the source code.
The returned module name and file name will be NULL if unknown.
The returned line number will similarly be zero if unknown.
@param ctx: message context (as passed to the @ref libvlc_log_cb callback).
@return: module module name storage (or NULL), file source code file name storage (or NULL), line source code file line number storage (or NULL).
@version: LibVLC 2.1.0 or later.
'''
f = _Cfunctions.get('libvlc_log_get_context', None) or \
_Cfunction('libvlc_log_get_context', ((1,), (2,), (2,), (2,),), None,
None, Log_ptr, ListPOINTER(ctypes.c_char_p), ListPOINTER(ctypes.c_char_p), ctypes.POINTER(ctypes.c_uint))
return f(ctx)
def libvlc_log_get_object(ctx, id):
'''Gets VLC object informations about a log message: the type name of the VLC
object emitting the message, the object header if any and a temporaly-unique
object identifier. These informations are mainly meant for B{manual}
troubleshooting.
The returned type name may be "generic" if unknown, but it cannot be NULL.
The returned header will be NULL if unset; in current versions, the header
is used to distinguish for VLM inputs.
The returned object ID will be zero if the message is not associated with
any VLC object.
@param ctx: message context (as passed to the @ref libvlc_log_cb callback).
@return: name object name storage (or NULL), header object header (or NULL), line source code file line number storage (or NULL).
@version: LibVLC 2.1.0 or later.
'''
f = _Cfunctions.get('libvlc_log_get_object', None) or \
_Cfunction('libvlc_log_get_object', ((1,), (2,), (2,), (1,),), None,
None, Log_ptr, ListPOINTER(ctypes.c_char_p), ListPOINTER(ctypes.c_char_p), ctypes.POINTER(ctypes.c_uint))
return f(ctx, id)
def libvlc_log_unset(p_instance): def libvlc_log_unset(p_instance):
'''Unsets the logging callback for a LibVLC instance. This is rarely needed: '''Unsets the logging callback for a LibVLC instance. This is rarely needed:
the callback is implicitly unset when the instance is destroyed. the callback is implicitly unset when the instance is destroyed.
@ -5827,7 +5863,7 @@ def libvlc_vlm_get_event_manager(p_instance):
# libvlc_printerr # libvlc_printerr
# libvlc_set_exit_handler # libvlc_set_exit_handler
# 15 function(s) not wrapped as methods: # 17 function(s) not wrapped as methods:
# libvlc_audio_output_device_list_release # libvlc_audio_output_device_list_release
# libvlc_audio_output_list_release # libvlc_audio_output_list_release
# libvlc_clearerr # libvlc_clearerr
@ -5838,6 +5874,8 @@ def libvlc_vlm_get_event_manager(p_instance):
# libvlc_get_changeset # libvlc_get_changeset
# libvlc_get_compiler # libvlc_get_compiler
# libvlc_get_version # libvlc_get_version
# libvlc_log_get_context
# libvlc_log_get_object
# libvlc_media_tracks_release # libvlc_media_tracks_release
# libvlc_module_description_list_release # libvlc_module_description_list_release
# libvlc_new # libvlc_new
@ -5910,9 +5948,9 @@ def debug_callback(event, *args, **kwds):
''' '''
l = ['event %s' % (event.type,)] l = ['event %s' % (event.type,)]
if args: if args:
l.extend(list(map(str, args))) l.extend(map(str, args))
if kwds: if kwds:
l.extend(sorted('%s=%s' % t for t in list(kwds.items()))) l.extend(sorted('%s=%s' % t for t in kwds.items()))
print('Debug callback (%s)' % ', '.join(l)) print('Debug callback (%s)' % ', '.join(l))
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -174,34 +174,11 @@ FLASH_HTML = """
<div id="flash" class="size" style="visibility:hidden"></div> <div id="flash" class="size" style="visibility:hidden"></div>
""" """
VIDEO_EXT = [ VIDEO_EXT = ['*.3gp', '*.3gpp', '*.3g2', '*.3gpp2', '*.aac', '*.flv', '*.f4a', '*.f4b', '*.f4p', '*.f4v', '*.mov',
'*.3gp', '*.m4a', '*.m4b', '*.m4p', '*.m4v', '*.mkv', '*.mp4', '*.ogv', '*.webm', '*.mpg', '*.wmv', '*.mpeg',
'*.3gpp', '*.avi', '*.swf']
'*.3g2',
'*.3gpp2',
'*.aac',
'*.flv',
'*.f4a',
'*.f4b',
'*.f4p',
'*.f4v',
'*.mov',
'*.m4a',
'*.m4b',
'*.m4p',
'*.m4v',
'*.mkv',
'*.mp4',
'*.ogv',
'*.webm',
'*.mpg', '*.wmv', '*.mpeg', '*.avi',
'*.swf'
]
AUDIO_EXT = [ AUDIO_EXT = ['*.mp3', '*.ogg']
'*.mp3',
'*.ogg'
]
class WebkitPlayer(MediaPlayer): class WebkitPlayer(MediaPlayer):
@ -411,10 +388,9 @@ class WebkitPlayer(MediaPlayer):
""" """
Return some information about this player Return some information about this player
""" """
return(translate('Media.player', 'Webkit is a media player which runs ' part1 = translate('Media.player', 'Webkit is a media player which runs inside a web browser. This player '
'inside a web browser. This player allows text over video to be ' 'allows text over video to be rendered.')
'rendered.') + part2 = translate('Media.player', 'Audio')
'<br/> <strong>' + translate('Media.player', 'Audio') + part3 = translate('Media.player', 'Video')
'</strong><br/>' + str(AUDIO_EXT) + '<br/><strong>' + return part1 + '<br/> <strong>' + part2 + '</strong><br/>' + str(AUDIO_EXT) + '<br/><strong>' + part3 + \
translate('Media.player', 'Video') + '</strong><br/>' + '</strong><br/>' + str(VIDEO_EXT) + '<br/>'
str(VIDEO_EXT) + '<br/>')

View File

@ -234,6 +234,8 @@ class Ui_ServiceManager(object):
self.menu = QtGui.QMenu() self.menu = QtGui.QMenu()
self.edit_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Edit Item'), self.edit_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Edit Item'),
icon=':/general/general_edit.png', triggers=self.remote_edit) icon=':/general/general_edit.png', triggers=self.remote_edit)
self.rename_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Rename...'),
icon=':/general/general_edit.png', triggers=self.on_service_item_rename)
self.maintain_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Reorder Item'), self.maintain_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Reorder Item'),
icon=':/general/general_edit.png', icon=':/general/general_edit.png',
triggers=self.on_service_item_edit_form) triggers=self.on_service_item_edit_form)
@ -399,7 +401,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
:param suffix_list: New Suffix's to be supported :param suffix_list: New Suffix's to be supported
""" """
for suffix in suffix_list: for suffix in suffix_list:
if not suffix in self.suffixes: if suffix not in self.suffixes:
self.suffixes.append(suffix) self.suffixes.append(suffix)
def on_new_service_clicked(self, field=None): def on_new_service_clicked(self, field=None):
@ -629,7 +631,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
for item in self.service_items: for item in self.service_items:
self.main_window.increment_progress_bar() self.main_window.increment_progress_bar()
service_item = item['service_item'].get_service_repr(self._save_lite) service_item = item['service_item'].get_service_repr(self._save_lite)
#TODO: check for file item on save. # TODO: check for file item on save.
service.append({'serviceitem': service_item}) service.append({'serviceitem': service_item})
self.main_window.increment_progress_bar() self.main_window.increment_progress_bar()
service_content = json.dumps(service) service_content = json.dumps(service)
@ -754,8 +756,9 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
items = json.load(file_to) items = json.load(file_to)
else: else:
critical_error_message_box(message=translate('OpenLP.ServiceManager', critical_error_message_box(message=translate('OpenLP.ServiceManager',
'The service file you are trying to open is in an old format.\n ' 'The service file you are trying to open is in an old '
'Please save it using OpenLP 2.0.2 or greater.')) 'format.\n Please save it using OpenLP 2.0.2 or '
'greater.'))
return return
file_to.close() file_to.close()
self.new_file() self.new_file()
@ -848,6 +851,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
pos = item.data(0, QtCore.Qt.UserRole) pos = item.data(0, QtCore.Qt.UserRole)
service_item = self.service_items[pos - 1] service_item = self.service_items[pos - 1]
self.edit_action.setVisible(False) self.edit_action.setVisible(False)
self.rename_action.setVisible(False)
self.create_custom_action.setVisible(False) self.create_custom_action.setVisible(False)
self.maintain_action.setVisible(False) self.maintain_action.setVisible(False)
self.notes_action.setVisible(False) self.notes_action.setVisible(False)
@ -855,6 +859,8 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
self.auto_start_action.setVisible(False) self.auto_start_action.setVisible(False)
if service_item['service_item'].is_capable(ItemCapabilities.CanEdit) and service_item['service_item'].edit_id: if service_item['service_item'].is_capable(ItemCapabilities.CanEdit) and service_item['service_item'].edit_id:
self.edit_action.setVisible(True) self.edit_action.setVisible(True)
if service_item['service_item'].is_capable(ItemCapabilities.CanEditTitle):
self.rename_action.setVisible(True)
if service_item['service_item'].is_capable(ItemCapabilities.CanMaintain): if service_item['service_item'].is_capable(ItemCapabilities.CanMaintain):
self.maintain_action.setVisible(True) self.maintain_action.setVisible(True)
if item.parent() is None: if item.parent() is None:
@ -1482,6 +1488,22 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
if new_item: if new_item:
self.add_service_item(new_item, replace=True) self.add_service_item(new_item, replace=True)
def on_service_item_rename(self):
"""
Opens a dialog to rename the service item.
"""
item = self.find_service_item()[0]
if not self.service_items[item]['service_item'].is_capable(ItemCapabilities.CanEditTitle):
return
title = self.service_items[item]['service_item'].title
title, ok = QtGui.QInputDialog.getText(self, translate('OpenLP.ServiceManager', 'Rename item title'),
translate('OpenLP.ServiceManager', 'Title:'),
QtGui.QLineEdit.Normal, self.trUtf8(title))
if ok:
self.service_items[item]['service_item'].title = title
self.repaint_service_list(item, -1)
self.set_modified()
def create_custom(self, field=None): def create_custom(self, field=None):
""" """
Saves the current text item as a custom slide Saves the current text item as a custom slide

View File

@ -150,5 +150,5 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog, RegistryProperties):
:param function: The function to be called :param function: The function to be called
""" """
if not function in self.processes: if function not in self.processes:
self.processes.append(function) self.processes.append(function)

View File

@ -1039,7 +1039,6 @@ class SlideController(DisplayController, RegistryProperties):
""" """
self.preview_widget.change_slide(row) self.preview_widget.change_slide(row)
self.update_preview() self.update_preview()
Registry().execute('slidecontroller_%s_changed' % self.type_prefix, row)
def update_preview(self): def update_preview(self):
""" """

View File

@ -44,7 +44,6 @@ class Ui_ThemeLayoutDialog(object):
Set up the UI Set up the UI
""" """
themeLayoutDialog.setObjectName('themeLayoutDialogDialog') themeLayoutDialog.setObjectName('themeLayoutDialogDialog')
#themeLayoutDialog.resize(300, 200)
self.preview_layout = QtGui.QVBoxLayout(themeLayoutDialog) self.preview_layout = QtGui.QVBoxLayout(themeLayoutDialog)
self.preview_layout.setObjectName('preview_layout') self.preview_layout.setObjectName('preview_layout')
self.preview_area = QtGui.QWidget(themeLayoutDialog) self.preview_area = QtGui.QWidget(themeLayoutDialog)

View File

@ -114,17 +114,19 @@ class ThemesTab(SettingsTab):
self.global_group_box.setTitle(translate('OpenLP.ThemesTab', 'Global Theme')) self.global_group_box.setTitle(translate('OpenLP.ThemesTab', 'Global Theme'))
self.level_group_box.setTitle(translate('OpenLP.ThemesTab', 'Theme Level')) self.level_group_box.setTitle(translate('OpenLP.ThemesTab', 'Theme Level'))
self.song_level_radio_button.setText(translate('OpenLP.ThemesTab', 'S&ong Level')) self.song_level_radio_button.setText(translate('OpenLP.ThemesTab', 'S&ong Level'))
self.song_level_label.setText(translate('OpenLP.ThemesTab', 'Use the theme from each song ' self.song_level_label.setText(
'in the database. If a song doesn\'t have a theme associated with ' translate('OpenLP.ThemesTab', 'Use the theme from each song in the database. If a song doesn\'t have a '
'it, then use the service\'s theme. If the service doesn\'t have ' 'theme associated with it, then use the service\'s theme. If the service '
'a theme, then use the global theme.')) 'doesn\'t have a theme, then use the global theme.'))
self.service_level_radio_button.setText(translate('OpenLP.ThemesTab', '&Service Level')) self.service_level_radio_button.setText(translate('OpenLP.ThemesTab', '&Service Level'))
self.service_level_label.setText(translate('OpenLP.ThemesTab', 'Use the theme from the service, ' self.service_level_label.setText(
'overriding any of the individual songs\' themes. If the ' translate('OpenLP.ThemesTab', 'Use the theme from the service, overriding any of the individual '
'service doesn\'t have a theme, then use the global theme.')) 'songs\' themes. If the service doesn\'t have a theme, then use the global '
'theme.'))
self.global_level_radio_button.setText(translate('OpenLP.ThemesTab', '&Global Level')) self.global_level_radio_button.setText(translate('OpenLP.ThemesTab', '&Global Level'))
self.global_level_label.setText(translate('OpenLP.ThemesTab', 'Use the global theme, overriding ' self.global_level_label.setText(translate('OpenLP.ThemesTab', 'Use the global theme, overriding any themes '
'any themes associated with either the service or the songs.')) 'associated with either the service or the '
'songs.'))
def load(self): def load(self):
""" """

View File

@ -56,7 +56,7 @@ if sys.platform != 'win32' and sys.platform != 'darwin':
from openlp.core.common import translate from openlp.core.common import translate
log = logging.getLogger(__name__+'.__init__') log = logging.getLogger(__name__ + '.__init__')
APPLICATION_VERSION = {} APPLICATION_VERSION = {}
IMAGES_FILTER = None IMAGES_FILTER = None

View File

@ -74,7 +74,7 @@ class LanguageManager(object):
log.debug('Translation files: %s', AppLocation.get_directory( log.debug('Translation files: %s', AppLocation.get_directory(
AppLocation.LanguageDir)) AppLocation.LanguageDir))
trans_dir = QtCore.QDir(AppLocation.get_directory(AppLocation.LanguageDir)) trans_dir = QtCore.QDir(AppLocation.get_directory(AppLocation.LanguageDir))
file_names = trans_dir.entryList('*.qm', QtCore.QDir.Files, QtCore.QDir.Name) file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Files, QtCore.QDir.Name)
# Remove qm files from the list which start with "qt_". # Remove qm files from the list which start with "qt_".
file_names = [file_ for file_ in file_names if not file_.startswith('qt_')] file_names = [file_ for file_ in file_names if not file_.startswith('qt_')]
return list(map(trans_dir.filePath, file_names)) return list(map(trans_dir.filePath, file_names))

View File

@ -207,12 +207,12 @@ class AlertsPlugin(Plugin):
""" """
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
""" """
## Name PluginList ## # Name PluginList
self.text_strings[StringContent.Name] = { self.text_strings[StringContent.Name] = {
'singular': translate('AlertsPlugin', 'Alert', 'name singular'), 'singular': translate('AlertsPlugin', 'Alert', 'name singular'),
'plural': translate('AlertsPlugin', 'Alerts', 'name plural') 'plural': translate('AlertsPlugin', 'Alerts', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## # Name for MediaDockManager, SettingsManager
self.text_strings[StringContent.VisibleName] = { self.text_strings[StringContent.VisibleName] = {
'title': translate('AlertsPlugin', 'Alerts', 'container title') 'title': translate('AlertsPlugin', 'Alerts', 'container title')
} }

View File

@ -88,8 +88,6 @@ class BiblePlugin(Plugin):
self.import_bible_item.setVisible(True) self.import_bible_item.setVisible(True)
action_list = ActionList.get_instance() action_list = ActionList.get_instance()
action_list.add_action(self.import_bible_item, UiStrings().Import) action_list.add_action(self.import_bible_item, UiStrings().Import)
# Do not add the action to the list yet.
#action_list.add_action(self.export_bible_item, UiStrings().Export)
# Set to invisible until we can export bibles # Set to invisible until we can export bibles
self.export_bible_item.setVisible(False) self.export_bible_item.setVisible(False)
self.tools_upgrade_item.setVisible(bool(self.manager.old_bible_databases)) self.tools_upgrade_item.setVisible(bool(self.manager.old_bible_databases))
@ -104,7 +102,6 @@ class BiblePlugin(Plugin):
action_list = ActionList.get_instance() action_list = ActionList.get_instance()
action_list.remove_action(self.import_bible_item, UiStrings().Import) action_list.remove_action(self.import_bible_item, UiStrings().Import)
self.import_bible_item.setVisible(False) self.import_bible_item.setVisible(False)
#action_list.remove_action(self.export_bible_item, UiStrings().Export)
self.export_bible_item.setVisible(False) self.export_bible_item.setVisible(False)
def app_startup(self): def app_startup(self):
@ -115,19 +112,27 @@ class BiblePlugin(Plugin):
if self.manager.old_bible_databases: if self.manager.old_bible_databases:
if QtGui.QMessageBox.information( if QtGui.QMessageBox.information(
self.main_window, translate('OpenLP', 'Information'), self.main_window, translate('OpenLP', 'Information'),
translate('OpenLP', 'Bible format has changed.\nYou have to upgrade your existing Bibles.\n' translate('OpenLP', 'Bible format has changed.\nYou have to upgrade your '
'Should OpenLP upgrade now?'), 'existing Bibles.\nShould OpenLP upgrade now?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) == \ QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) == \
QtGui.QMessageBox.Yes: QtGui.QMessageBox.Yes:
self.on_tools_upgrade_Item_triggered() self.on_tools_upgrade_Item_triggered()
def add_import_menu_item(self, import_menu): def add_import_menu_item(self, import_menu):
"""
:param import_menu:
"""
self.import_bible_item = create_action(import_menu, 'importBibleItem', self.import_bible_item = create_action(import_menu, 'importBibleItem',
text=translate('BiblesPlugin', '&Bible'), visible=False, text=translate('BiblesPlugin', '&Bible'), visible=False,
triggers=self.on_bible_import_click) triggers=self.on_bible_import_click)
import_menu.addAction(self.import_bible_item) import_menu.addAction(self.import_bible_item)
def add_export_menu_Item(self, export_menu): def add_export_menu_item(self, export_menu):
"""
:param export_menu:
"""
self.export_bible_item = create_action(export_menu, 'exportBibleItem', self.export_bible_item = create_action(export_menu, 'exportBibleItem',
text=translate('BiblesPlugin', '&Bible'), visible=False) text=translate('BiblesPlugin', '&Bible'), visible=False)
export_menu.addAction(self.export_bible_item) export_menu.addAction(self.export_bible_item)
@ -190,12 +195,12 @@ class BiblePlugin(Plugin):
""" """
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
""" """
## Name PluginList ## # Name PluginList
self.text_strings[StringContent.Name] = { self.text_strings[StringContent.Name] = {
'singular': translate('BiblesPlugin', 'Bible', 'name singular'), 'singular': translate('BiblesPlugin', 'Bible', 'name singular'),
'plural': translate('BiblesPlugin', 'Bibles', 'name plural') 'plural': translate('BiblesPlugin', 'Bibles', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## # Name for MediaDockManager, SettingsManager
self.text_strings[StringContent.VisibleName] = { self.text_strings[StringContent.VisibleName] = {
'title': translate('BiblesPlugin', 'Bibles', 'container title') 'title': translate('BiblesPlugin', 'Bibles', 'container title')
} }

View File

@ -78,7 +78,7 @@ class BibleUpgradeForm(OpenLPWizard):
Set up the UI for the bible wizard. Set up the UI for the bible wizard.
""" """
super(BibleUpgradeForm, self).setupUi(image) super(BibleUpgradeForm, self).setupUi(image)
Registry().execute('openlp_stop_wizard', self.stop_import) Registry().register_function('openlp_stop_wizard', self.stop_import)
def stop_import(self): def stop_import(self):
""" """

View File

@ -154,7 +154,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
if 'path' in kwargs: if 'path' in kwargs:
self.path = kwargs['path'] self.path = kwargs['path']
self.wizard = None self.wizard = None
Registry().execute('openlp_stop_wizard', self.stop_import) Registry().register_function('openlp_stop_wizard', self.stop_import)
def stop_import(self): def stop_import(self):
""" """
@ -191,7 +191,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
:param testament: *Defaults to 1.* The testament_reference_id from :param testament: *Defaults to 1.* The testament_reference_id from
bibles_resources.sqlite of the testament this book belongs to. bibles_resources.sqlite of the testament this book belongs to.
""" """
log.debug('BibleDB.create_book("%s", "%s")', name, bk_ref_id) log.debug('BibleDB.create_book("%s", "%s")' % (name, bk_ref_id))
book = Book.populate(name=name, book_reference_id=bk_ref_id, testament_reference_id=testament) book = Book.populate(name=name, book_reference_id=bk_ref_id, testament_reference_id=testament)
self.save_object(book) self.save_object(book)
return book return book
@ -202,7 +202,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
:param book: The book object :param book: The book object
""" """
log.debug('BibleDB.update_book("%s")', book.name) log.debug('BibleDB.update_book("%s")' % book.name)
return self.save_object(book) return self.save_object(book)
def delete_book(self, db_book): def delete_book(self, db_book):
@ -211,7 +211,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
:param db_book: The book object. :param db_book: The book object.
""" """
log.debug('BibleDB.delete_book("%s")', db_book.name) log.debug('BibleDB.delete_book("%s")' % db_book.name)
if self.delete_object(Book, db_book.id): if self.delete_object(Book, db_book.id):
return True return True
return False return False
@ -225,7 +225,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
:param text_list: A dict of the verses to be inserted. The key is the verse number, and the value is the :param text_list: A dict of the verses to be inserted. The key is the verse number, and the value is the
verse text. verse text.
""" """
log.debug('BibleDBcreate_chapter("%s", "%s")', book_id, chapter) log.debug('BibleDBcreate_chapter("%s", "%s")' % (book_id, chapter))
# Text list has book and chapter as first two elements of the array. # Text list has book and chapter as first two elements of the array.
for verse_number, verse_text in text_list.items(): for verse_number, verse_text in text_list.items():
verse = Verse.populate( verse = Verse.populate(
@ -267,7 +267,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
""" """
if not isinstance(value, str): if not isinstance(value, str):
value = str(value) value = str(value)
log.debug('BibleDB.save_meta("%s/%s")', key, value) log.debug('BibleDB.save_meta("%s/%s")' % (key, value))
meta = self.get_object(BibleMeta, key) meta = self.get_object(BibleMeta, key)
if meta: if meta:
meta.value = value meta.value = value
@ -281,7 +281,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
:param book: The name of the book to return. :param book: The name of the book to return.
""" """
log.debug('BibleDB.get_book("%s")', book) log.debug('BibleDB.get_book("%s")' % book)
return self.get_object_filtered(Book, Book.name.like(book + '%')) return self.get_object_filtered(Book, Book.name.like(book + '%'))
def get_books(self): def get_books(self):
@ -292,17 +292,17 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
log.debug('BibleDB.get_books()') log.debug('BibleDB.get_books()')
return self.get_all_objects(Book, order_by_ref=Book.id) return self.get_all_objects(Book, order_by_ref=Book.id)
def get_book_by_book_ref_id(self, id): def get_book_by_book_ref_id(self, ref_id):
""" """
Return a book object from the database. Return a book object from the database.
:param id: The reference id of the book to return. :param ref_id: The reference id of the book to return.
""" """
log.debug('BibleDB.get_book_by_book_ref_id("%s")', id) log.debug('BibleDB.get_book_by_book_ref_id("%s")' % ref_id)
return self.get_object_filtered(Book, Book.book_reference_id.like(id)) return self.get_object_filtered(Book, Book.book_reference_id.like(ref_id))
def get_book_ref_id_by_name(self, book, maxbooks, language_id=None): def get_book_ref_id_by_name(self, book, maxbooks, language_id=None):
log.debug('BibleDB.get_book_ref_id_by_name:("%s", "%s")', book, language_id) log.debug('BibleDB.get_book_ref_id_by_name:("%s", "%s")' % (book, language_id))
book_id = None book_id = None
if BiblesResourcesDB.get_book(book, True): if BiblesResourcesDB.get_book(book, True):
book_temp = BiblesResourcesDB.get_book(book, True) book_temp = BiblesResourcesDB.get_book(book, True)
@ -328,7 +328,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
:param book: The name of the book, according to the selected language. :param book: The name of the book, according to the selected language.
:param language_selection: The language selection the user has chosen in the settings section of the Bible. :param language_selection: The language selection the user has chosen in the settings section of the Bible.
""" """
log.debug('get_book_ref_id_by_localised_name("%s", "%s")', book, language_selection) log.debug('get_book_ref_id_by_localised_name("%s", "%s")' % (book, language_selection))
from openlp.plugins.bibles.lib import LanguageSelection, BibleStrings from openlp.plugins.bibles.lib import LanguageSelection, BibleStrings
book_names = BibleStrings().BookNames book_names = BibleStrings().BookNames
# escape reserved characters # escape reserved characters
@ -376,14 +376,14 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
[(u'35', 1, 1, 1), (u'35', 2, 2, 3)] [(u'35', 1, 1, 1), (u'35', 2, 2, 3)]
:param show_error: :param show_error:
""" """
log.debug('BibleDB.get_verses("%s")', reference_list) log.debug('BibleDB.get_verses("%s")' % reference_list)
verse_list = [] verse_list = []
book_error = False book_error = False
for book_id, chapter, start_verse, end_verse in reference_list: for book_id, chapter, start_verse, end_verse in reference_list:
db_book = self.get_book_by_book_ref_id(book_id) db_book = self.get_book_by_book_ref_id(book_id)
if db_book: if db_book:
book_id = db_book.book_reference_id book_id = db_book.book_reference_id
log.debug('Book name corrected to "%s"', db_book.name) log.debug('Book name corrected to "%s"' % db_book.name)
if end_verse == -1: if end_verse == -1:
end_verse = self.get_verse_count(book_id, chapter) end_verse = self.get_verse_count(book_id, chapter)
verses = self.session.query(Verse) \ verses = self.session.query(Verse) \
@ -395,7 +395,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
.all() .all()
verse_list.extend(verses) verse_list.extend(verses)
else: else:
log.debug('OpenLP failed to find book with id "%s"', book_id) log.debug('OpenLP failed to find book with id "%s"' % book_id)
book_error = True book_error = True
if book_error and show_error: if book_error and show_error:
critical_error_message_box( critical_error_message_box(
@ -414,7 +414,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
contains spaces, it will split apart and AND'd on the list of contains spaces, it will split apart and AND'd on the list of
values. values.
""" """
log.debug('BibleDB.verse_search("%s")', text) log.debug('BibleDB.verse_search("%s")' % text)
verses = self.session.query(Verse) verses = self.session.query(Verse)
if text.find(',') > -1: if text.find(',') > -1:
keywords = ['%%%s%%' % keyword.strip() for keyword in text.split(',')] keywords = ['%%%s%%' % keyword.strip() for keyword in text.split(',')]
@ -433,7 +433,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
:param book: The book object to get the chapter count for. :param book: The book object to get the chapter count for.
""" """
log.debug('BibleDB.get_chapter_count("%s")', book.name) log.debug('BibleDB.get_chapter_count("%s")' % book.name)
count = self.session.query(func.max(Verse.chapter)).join(Book).filter( count = self.session.query(func.max(Verse.chapter)).join(Book).filter(
Book.book_reference_id == book.book_reference_id).scalar() Book.book_reference_id == book.book_reference_id).scalar()
if not count: if not count:
@ -447,7 +447,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties):
:param book_ref_id: The book reference id. :param book_ref_id: The book reference id.
:param chapter: The chapter to get the verse count for. :param chapter: The chapter to get the verse count for.
""" """
log.debug('BibleDB.get_verse_count("%s", "%s")', book_ref_id, chapter) log.debug('BibleDB.get_verse_count("%s", "%s")' % (book_ref_id, chapter))
count = self.session.query(func.max(Verse.verse)).join(Book) \ count = self.session.query(func.max(Verse.verse)).join(Book) \
.filter(Book.book_reference_id == book_ref_id) \ .filter(Book.book_reference_id == book_ref_id) \
.filter(Verse.chapter == chapter) \ .filter(Verse.chapter == chapter) \
@ -563,7 +563,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param name: The name or abbreviation of the book. :param name: The name or abbreviation of the book.
:param lower: True if the comparison should be only lowercase :param lower: True if the comparison should be only lowercase
""" """
log.debug('BiblesResourcesDB.get_book("%s")', name) log.debug('BiblesResourcesDB.get_book("%s")' % name)
if not isinstance(name, str): if not isinstance(name, str):
name = str(name) name = str(name)
if lower: if lower:
@ -592,7 +592,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param string: The string to search for in the book names or abbreviations. :param string: The string to search for in the book names or abbreviations.
""" """
log.debug('BiblesResourcesDB.get_book_like("%s")', string) log.debug('BiblesResourcesDB.get_book_like("%s")' % string)
if not isinstance(string, str): if not isinstance(string, str):
name = str(string) name = str(string)
books = BiblesResourcesDB.run_sql( books = BiblesResourcesDB.run_sql(
@ -611,17 +611,17 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
return None return None
@staticmethod @staticmethod
def get_book_by_id(id): def get_book_by_id(book_id):
""" """
Return a book by id. Return a book by id.
:param id: The id of the book. :param book_id: The id of the book.
""" """
log.debug('BiblesResourcesDB.get_book_by_id("%s")', id) log.debug('BiblesResourcesDB.get_book_by_id("%s")' % book_id)
if not isinstance(id, int): if not isinstance(book_id, int):
id = int(id) book_id = int(book_id)
books = BiblesResourcesDB.run_sql( books = BiblesResourcesDB.run_sql(
'SELECT id, testament_id, name, abbreviation, chapters FROM book_reference WHERE id = ?', (id, )) 'SELECT id, testament_id, name, abbreviation, chapters FROM book_reference WHERE id = ?', (book_id, ))
if books: if books:
return { return {
'id': books[0][0], 'id': books[0][0],
@ -641,7 +641,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param book_ref_id: The id of a book. :param book_ref_id: The id of a book.
:param chapter: The chapter number. :param chapter: The chapter number.
""" """
log.debug('BiblesResourcesDB.get_chapter("%s", "%s")', book_ref_id, chapter) log.debug('BiblesResourcesDB.get_chapter("%s", "%s")' % (book_ref_id, chapter))
if not isinstance(chapter, int): if not isinstance(chapter, int):
chapter = int(chapter) chapter = int(chapter)
chapters = BiblesResourcesDB.run_sql( chapters = BiblesResourcesDB.run_sql(
@ -649,10 +649,10 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
'chapter, verse_count FROM chapters WHERE book_reference_id = ?', (book_ref_id,)) 'chapter, verse_count FROM chapters WHERE book_reference_id = ?', (book_ref_id,))
try: try:
return { return {
'id': chapters[chapter-1][0], 'id': chapters[chapter - 1][0],
'book_reference_id': chapters[chapter-1][1], 'book_reference_id': chapters[chapter - 1][1],
'chapter': chapters[chapter-1][2], 'chapter': chapters[chapter - 1][2],
'verse_count': chapters[chapter-1][3] 'verse_count': chapters[chapter - 1][3]
} }
except (IndexError, TypeError): except (IndexError, TypeError):
return None return None
@ -664,7 +664,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param book_ref_id: The id of the book. :param book_ref_id: The id of the book.
""" """
log.debug('BiblesResourcesDB.get_chapter_count("%s")', book_ref_id) log.debug('BiblesResourcesDB.get_chapter_count("%s")' % book_ref_id)
details = BiblesResourcesDB.get_book_by_id(book_ref_id) details = BiblesResourcesDB.get_book_by_id(book_ref_id)
if details: if details:
return details['chapters'] return details['chapters']
@ -678,7 +678,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param book_ref_id: The id of the book. :param book_ref_id: The id of the book.
:param chapter: The number of the chapter. :param chapter: The number of the chapter.
""" """
log.debug('BiblesResourcesDB.get_verse_count("%s", "%s")', book_ref_id, chapter) log.debug('BiblesResourcesDB.get_verse_count("%s", "%s")' % (book_ref_id, chapter))
details = BiblesResourcesDB.get_chapter(book_ref_id, chapter) details = BiblesResourcesDB.get_chapter(book_ref_id, chapter)
if details: if details:
return details['verse_count'] return details['verse_count']
@ -691,7 +691,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param source: The name or abbreviation of the book. :param source: The name or abbreviation of the book.
""" """
log.debug('BiblesResourcesDB.get_download_source("%s")', source) log.debug('BiblesResourcesDB.get_download_source("%s")' % source)
if not isinstance(source, str): if not isinstance(source, str):
source = str(source) source = str(source)
source = source.title() source = source.title()
@ -712,7 +712,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param source: The source of the web_bible. :param source: The source of the web_bible.
""" """
log.debug('BiblesResourcesDB.get_webbibles("%s")', source) log.debug('BiblesResourcesDB.get_webbibles("%s")' % source)
if not isinstance(source, str): if not isinstance(source, str):
source = str(source) source = str(source)
source = BiblesResourcesDB.get_download_source(source) source = BiblesResourcesDB.get_download_source(source)
@ -737,7 +737,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param abbreviation: The abbreviation of the web_bible. :param abbreviation: The abbreviation of the web_bible.
:param source: The source of the web_bible. :param source: The source of the web_bible.
""" """
log.debug('BiblesResourcesDB.get_webbibles("%s", "%s")', abbreviation, source) log.debug('BiblesResourcesDB.get_webbibles("%s", "%s")' % (abbreviation, source))
if not isinstance(abbreviation, str): if not isinstance(abbreviation, str):
abbreviation = str(abbreviation) abbreviation = str(abbreviation)
if not isinstance(source, str): if not isinstance(source, str):
@ -765,7 +765,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param name: The name to search the id. :param name: The name to search the id.
:param language_id: The language_id for which language should be searched :param language_id: The language_id for which language should be searched
""" """
log.debug('BiblesResourcesDB.get_alternative_book_name("%s", "%s")', name, language_id) log.debug('BiblesResourcesDB.get_alternative_book_name("%s", "%s")' % (name, language_id))
if language_id: if language_id:
books = BiblesResourcesDB.run_sql( books = BiblesResourcesDB.run_sql(
'SELECT book_reference_id, name FROM alternative_book_names WHERE language_id = ? ORDER BY id', 'SELECT book_reference_id, name FROM alternative_book_names WHERE language_id = ? ORDER BY id',
@ -784,7 +784,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager):
:param name: The name or abbreviation of the language. :param name: The name or abbreviation of the language.
""" """
log.debug('BiblesResourcesDB.get_language("%s")', name) log.debug('BiblesResourcesDB.get_language("%s")' % name)
if not isinstance(name, str): if not isinstance(name, str):
name = str(name) name = str(name)
language = BiblesResourcesDB.run_sql( language = BiblesResourcesDB.run_sql(
@ -846,13 +846,13 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager):
file_path = os.path.join( file_path = os.path.join(
AppLocation.get_directory(AppLocation.DataDir), 'bibles', 'alternative_book_names.sqlite') AppLocation.get_directory(AppLocation.DataDir), 'bibles', 'alternative_book_names.sqlite')
if not os.path.exists(file_path): if not os.path.exists(file_path):
#create new DB, create table alternative_book_names # create new DB, create table alternative_book_names
AlternativeBookNamesDB.conn = sqlite3.connect(file_path) AlternativeBookNamesDB.conn = sqlite3.connect(file_path)
AlternativeBookNamesDB.conn.execute( AlternativeBookNamesDB.conn.execute(
'CREATE TABLE alternative_book_names(id INTEGER NOT NULL, ' 'CREATE TABLE alternative_book_names(id INTEGER NOT NULL, '
'book_reference_id INTEGER, language_id INTEGER, name VARCHAR(50), PRIMARY KEY (id))') 'book_reference_id INTEGER, language_id INTEGER, name VARCHAR(50), PRIMARY KEY (id))')
else: else:
#use existing DB # use existing DB
AlternativeBookNamesDB.conn = sqlite3.connect(file_path) AlternativeBookNamesDB.conn = sqlite3.connect(file_path)
AlternativeBookNamesDB.cursor = AlternativeBookNamesDB.conn.cursor() AlternativeBookNamesDB.cursor = AlternativeBookNamesDB.conn.cursor()
return AlternativeBookNamesDB.cursor return AlternativeBookNamesDB.cursor
@ -880,7 +880,7 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager):
:param name: The name to search the id. :param name: The name to search the id.
:param language_id: The language_id for which language should be searched :param language_id: The language_id for which language should be searched
""" """
log.debug('AlternativeBookNamesDB.get_book_reference_id("%s", "%s")', name, language_id) log.debug('AlternativeBookNamesDB.get_book_reference_id("%s", "%s")' % (name, language_id))
if language_id: if language_id:
books = AlternativeBookNamesDB.run_sql( books = AlternativeBookNamesDB.run_sql(
'SELECT book_reference_id, name FROM alternative_book_names WHERE language_id = ?', (language_id, )) 'SELECT book_reference_id, name FROM alternative_book_names WHERE language_id = ?', (language_id, ))
@ -901,8 +901,8 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager):
:param book_reference_id: The book_reference_id of the book. :param book_reference_id: The book_reference_id of the book.
:param language_id: The language to which the alternative book name belong. :param language_id: The language to which the alternative book name belong.
""" """
log.debug('AlternativeBookNamesDB.create_alternative_book_name("%s", "%s", "%s")', log.debug('AlternativeBookNamesDB.create_alternative_book_name("%s", "%s", "%s")' %
name, book_reference_id, language_id) (name, book_reference_id, language_id))
return AlternativeBookNamesDB.run_sql( return AlternativeBookNamesDB.run_sql(
'INSERT INTO alternative_book_names(book_reference_id, language_id, name) ' 'INSERT INTO alternative_book_names(book_reference_id, language_id, name) '
'VALUES (?, ?, ?)', (book_reference_id, language_id, name), True) 'VALUES (?, ?, ?)', (book_reference_id, language_id, name), True)

View File

@ -552,10 +552,10 @@ class HTTPBible(BibleDB, RegistryProperties):
self.application.set_busy_cursor() self.application.set_busy_cursor()
search_results = self.get_chapter(book, reference[1]) search_results = self.get_chapter(book, reference[1])
if search_results and search_results.has_verse_list(): if search_results and search_results.has_verse_list():
## We have found a book of the bible lets check to see # We have found a book of the bible lets check to see
## if it was there. By reusing the returned book name # if it was there. By reusing the returned book name
## we get a correct book. For example it is possible # we get a correct book. For example it is possible
## to request ac and get Acts back. # to request ac and get Acts back.
book_name = search_results.book book_name = search_results.book
self.application.process_events() self.application.process_events()
# Check to see if book/chapter exists. # Check to see if book/chapter exists.

View File

@ -480,6 +480,10 @@ class BibleMediaItem(MediaManagerItem):
self.reload_bibles() self.reload_bibles()
def on_delete_click(self): def on_delete_click(self):
"""
When the delete button is pressed
"""
bible = None
if self.quickTab.isVisible(): if self.quickTab.isVisible():
bible = self.quickVersionComboBox.currentText() bible = self.quickVersionComboBox.currentText()
elif self.advancedTab.isVisible(): elif self.advancedTab.isVisible():
@ -488,8 +492,9 @@ class BibleMediaItem(MediaManagerItem):
if QtGui.QMessageBox.question( if QtGui.QMessageBox.question(
self, UiStrings().ConfirmDelete, self, UiStrings().ConfirmDelete,
translate('BiblesPlugin.MediaItem', 'Are you sure you want to completely delete "%s" Bible from ' translate('BiblesPlugin.MediaItem', 'Are you sure you want to completely delete "%s" Bible from '
'OpenLP?\n\nYou will need to re-import this Bible to use it again.') % bible, 'OpenLP?\n\nYou will need to re-import this Bible to use it '
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), 'again.') % bible,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
return return
self.plugin.manager.delete_bible(bible) self.plugin.manager.delete_bible(bible)
@ -752,7 +757,7 @@ class BibleMediaItem(MediaManagerItem):
log.exception('The second_search_results does not have as many verses as the search_results.') log.exception('The second_search_results does not have as many verses as the search_results.')
break break
bible_text = '%s %d%s%d (%s, %s)' % (book, verse.chapter, verse_separator, verse.verse, version, bible_text = '%s %d%s%d (%s, %s)' % (book, verse.chapter, verse_separator, verse.verse, version,
second_version) second_version)
else: else:
bible_text = '%s %d%s%d (%s)' % (book, verse.chapter, verse_separator, verse.verse, version) bible_text = '%s %d%s%d (%s)' % (book, verse.chapter, verse_separator, verse.verse, version)
bible_verse = QtGui.QListWidgetItem(bible_text) bible_verse = QtGui.QListWidgetItem(bible_text)
@ -840,6 +845,7 @@ class BibleMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.CanPreview) service_item.add_capability(ItemCapabilities.CanPreview)
service_item.add_capability(ItemCapabilities.CanLoop) service_item.add_capability(ItemCapabilities.CanLoop)
service_item.add_capability(ItemCapabilities.CanWordSplit) service_item.add_capability(ItemCapabilities.CanWordSplit)
service_item.add_capability(ItemCapabilities.CanEditTitle)
# Service Item: Title # Service Item: Title
service_item.title = create_separated_list(raw_title) service_item.title = create_separated_list(raw_title)
# Service Item: Theme # Service Item: Theme

View File

@ -94,5 +94,5 @@ class VerseReferenceList(object):
result = result + ', ' + version['permission'] result = result + ', ' + version['permission']
result = result.rstrip() result = result.rstrip()
if result.endswith(','): if result.endswith(','):
return result[:len(result)-1] return result[:len(result) - 1]
return result return result

View File

@ -43,7 +43,7 @@ log = logging.getLogger(__name__)
__default_settings__ = { __default_settings__ = {
'custom/db type': 'sqlite', 'custom/db type': 'sqlite',
'custom/last search type': CustomSearch.Titles, 'custom/last search type': CustomSearch.Titles,
'custom/display footer': True, 'custom/display footer': True,
'custom/add custom from service': True 'custom/add custom from service': True
} }
@ -97,12 +97,12 @@ class CustomPlugin(Plugin):
""" """
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
""" """
## Name PluginList ## # Name PluginList
self.text_strings[StringContent.Name] = { self.text_strings[StringContent.Name] = {
'singular': translate('CustomPlugin', 'Custom Slide', 'name singular'), 'singular': translate('CustomPlugin', 'Custom Slide', 'name singular'),
'plural': translate('CustomPlugin', 'Custom Slides', 'name plural') 'plural': translate('CustomPlugin', 'Custom Slides', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## # Name for MediaDockManager, SettingsManager
self.text_strings[StringContent.VisibleName] = { self.text_strings[StringContent.VisibleName] = {
'title': translate('CustomPlugin', 'Custom Slides', 'container title') 'title': translate('CustomPlugin', 'Custom Slides', 'container title')
} }

View File

@ -1,4 +1,3 @@
#lint:disable
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4

View File

@ -51,7 +51,7 @@ from lxml import etree, objectify
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
#TODO: These classes need to be refactored into a single class. # TODO: These classes need to be refactored into a single class.
class CustomXMLBuilder(object): class CustomXMLBuilder(object):
""" """
This class builds the XML used to describe songs. This class builds the XML used to describe songs.

View File

@ -95,12 +95,12 @@ class ImagePlugin(Plugin):
""" """
Called to define all translatable texts of the plugin. Called to define all translatable texts of the plugin.
""" """
## Name PluginList ## # Name PluginList
self.text_strings[StringContent.Name] = { self.text_strings[StringContent.Name] = {
'singular': translate('ImagePlugin', 'Image', 'name singular'), 'singular': translate('ImagePlugin', 'Image', 'name singular'),
'plural': translate('ImagePlugin', 'Images', 'name plural') 'plural': translate('ImagePlugin', 'Images', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## # Name for MediaDockManager, SettingsManager
self.text_strings[StringContent.VisibleName] = {'title': translate('ImagePlugin', 'Images', 'container title')} self.text_strings[StringContent.VisibleName] = {'title': translate('ImagePlugin', 'Images', 'container title')}
# Middle Header Bar # Middle Header Bar
tooltips = { tooltips = {

View File

@ -550,6 +550,7 @@ class ImageMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.CanPreview) service_item.add_capability(ItemCapabilities.CanPreview)
service_item.add_capability(ItemCapabilities.CanLoop) service_item.add_capability(ItemCapabilities.CanLoop)
service_item.add_capability(ItemCapabilities.CanAppend) service_item.add_capability(ItemCapabilities.CanAppend)
service_item.add_capability(ItemCapabilities.CanEditTitle)
# force a nonexistent theme # force a nonexistent theme
service_item.theme = -1 service_item.theme = -1
missing_items_file_names = [] missing_items_file_names = []

View File

@ -95,7 +95,6 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
self.reset_action.setToolTip(UiStrings().ResetLiveBG) self.reset_action.setToolTip(UiStrings().ResetLiveBG)
self.automatic = UiStrings().Automatic self.automatic = UiStrings().Automatic
self.display_type_label.setText(translate('MediaPlugin.MediaItem', 'Use Player:')) self.display_type_label.setText(translate('MediaPlugin.MediaItem', 'Use Player:'))
#self.rebuild_players()
def required_icons(self): def required_icons(self):
""" """
@ -141,7 +140,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
if index == 0: if index == 0:
set_media_players(player) set_media_players(player)
else: else:
set_media_players(player, player[index-1]) set_media_players(player, player[index - 1])
def on_reset_click(self): def on_reset_click(self):
""" """
@ -216,6 +215,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
if not self.media_controller.media_length(service_item): if not self.media_controller.media_length(service_item):
return False return False
service_item.add_capability(ItemCapabilities.CanAutoStartForLive) service_item.add_capability(ItemCapabilities.CanAutoStartForLive)
service_item.add_capability(ItemCapabilities.CanEditTitle)
service_item.add_capability(ItemCapabilities.RequiresMedia) service_item.add_capability(ItemCapabilities.RequiresMedia)
if Settings().value(self.settings_section + '/media auto start') == QtCore.Qt.Checked: if Settings().value(self.settings_section + '/media auto start') == QtCore.Qt.Checked:
service_item.will_auto_start = True service_item.will_auto_start = True

View File

@ -73,12 +73,12 @@ class MediaPlugin(Plugin):
""" """
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
""" """
## Name PluginList ## # Name PluginList
self.text_strings[StringContent.Name] = { self.text_strings[StringContent.Name] = {
'singular': translate('MediaPlugin', 'Media', 'name singular'), 'singular': translate('MediaPlugin', 'Media', 'name singular'),
'plural': translate('MediaPlugin', 'Media', 'name plural') 'plural': translate('MediaPlugin', 'Media', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## # Name for MediaDockManager, SettingsManager
self.text_strings[StringContent.VisibleName] = { self.text_strings[StringContent.VisibleName] = {
'title': translate('MediaPlugin', 'Media', 'container title') 'title': translate('MediaPlugin', 'Media', 'container title')
} }

View File

@ -377,8 +377,6 @@ class ImpressDocument(PresentationDocument):
Stop the presentation, remove from screen. Stop the presentation, remove from screen.
""" """
log.debug('stop presentation OpenOffice') log.debug('stop presentation OpenOffice')
# deactivate should hide the screen according to docs, but doesn't
#self.control.deactivate()
self.presentation.end() self.presentation.end()
self.control = None self.control = None

View File

@ -263,6 +263,7 @@ class PresentationMediaItem(MediaManagerItem):
file_type = os.path.splitext(filename)[1][1:] file_type = os.path.splitext(filename)[1][1:]
if not self.display_type_combo_box.currentText(): if not self.display_type_combo_box.currentText():
return False return False
service_item.add_capability(ItemCapabilities.CanEditTitle)
if (file_type == 'pdf' or file_type == 'xps') and context != ServiceItemContext.Service: if (file_type == 'pdf' or file_type == 'xps') and context != ServiceItemContext.Service:
service_item.add_capability(ItemCapabilities.CanMaintain) service_item.add_capability(ItemCapabilities.CanMaintain)
service_item.add_capability(ItemCapabilities.CanPreview) service_item.add_capability(ItemCapabilities.CanPreview)

View File

@ -74,7 +74,7 @@ class PdfController(PresentationController):
runlog = '' runlog = ''
log.debug('testing program_path: %s', program_path) log.debug('testing program_path: %s', program_path)
try: try:
runlog = check_output([program_path, '--help'], stderr=STDOUT) runlog = check_output([program_path, '--help'], stderr=STDOUT)
except CalledProcessError as e: except CalledProcessError as e:
runlog = e.output runlog = e.output
except Exception: except Exception:
@ -183,7 +183,7 @@ class PdfDocument(PresentationDocument):
self.image_files = [] self.image_files = []
self.num_pages = -1 self.num_pages = -1
def gs_get_resolution(self, size): def gs_get_resolution(self, size):
""" """
Only used when using ghostscript Only used when using ghostscript
Ghostscript can't scale automatically while keeping aspect like mupdf, so we need Ghostscript can't scale automatically while keeping aspect like mupdf, so we need
@ -236,7 +236,7 @@ class PdfDocument(PresentationDocument):
if os.path.isfile(os.path.join(self.get_temp_folder(), 'mainslide001.png')): if os.path.isfile(os.path.join(self.get_temp_folder(), 'mainslide001.png')):
created_files = sorted(os.listdir(self.get_temp_folder())) created_files = sorted(os.listdir(self.get_temp_folder()))
for fn in created_files: for fn in created_files:
if os.path.isfile(os.path.join(self.get_temp_folder(), fn)): if os.path.isfile(os.path.join(self.get_temp_folder(), fn)):
self.image_files.append(os.path.join(self.get_temp_folder(), fn)) self.image_files.append(os.path.join(self.get_temp_folder(), fn))
self.num_pages = len(self.image_files) self.num_pages = len(self.image_files)
return True return True

View File

@ -247,7 +247,7 @@ class PowerpointDocument(PresentationDocument):
Starts a presentation from the beginning. Starts a presentation from the beginning.
""" """
log.debug('start_presentation') log.debug('start_presentation')
#SlideShowWindow measures its size/position by points, not pixels # SlideShowWindow measures its size/position by points, not pixels
try: try:
dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88) dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88)
except win32ui.error: except win32ui.error:

View File

@ -175,10 +175,10 @@ class PresentationTab(SettingsTab):
if pdf_program == '': if pdf_program == '':
enable_pdf_program = 0 enable_pdf_program = 0
if pdf_program != Settings().value(self.settings_section + '/pdf_program'): if pdf_program != Settings().value(self.settings_section + '/pdf_program'):
Settings().setValue(self.settings_section + '/pdf_program', pdf_program) Settings().setValue(self.settings_section + '/pdf_program', pdf_program)
changed = True changed = True
if enable_pdf_program != Settings().value(self.settings_section + '/enable_pdf_program'): if enable_pdf_program != Settings().value(self.settings_section + '/enable_pdf_program'):
Settings().setValue(self.settings_section + '/enable_pdf_program', enable_pdf_program) Settings().setValue(self.settings_section + '/enable_pdf_program', enable_pdf_program)
changed = True changed = True
if changed: if changed:
self.settings_form.register_post_process('mediaitem_suffix_reset') self.settings_form.register_post_process('mediaitem_suffix_reset')

View File

@ -156,12 +156,12 @@ class PresentationPlugin(Plugin):
""" """
Called to define all translatable texts of the plugin. Called to define all translatable texts of the plugin.
""" """
## Name PluginList ## # Name PluginList
self.text_strings[StringContent.Name] = { self.text_strings[StringContent.Name] = {
'singular': translate('PresentationPlugin', 'Presentation', 'name singular'), 'singular': translate('PresentationPlugin', 'Presentation', 'name singular'),
'plural': translate('PresentationPlugin', 'Presentations', 'name plural') 'plural': translate('PresentationPlugin', 'Presentations', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## # Name for MediaDockManager, SettingsManager
self.text_strings[StringContent.VisibleName] = { self.text_strings[StringContent.VisibleName] = {
'title': translate('PresentationPlugin', 'Presentations', 'container title') 'title': translate('PresentationPlugin', 'Presentations', 'container title')
} }

View File

@ -92,12 +92,12 @@ class RemotesPlugin(Plugin):
""" """
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
""" """
## Name PluginList ## # Name PluginList
self.text_strings[StringContent.Name] = { self.text_strings[StringContent.Name] = {
'singular': translate('RemotePlugin', 'Remote', 'name singular'), 'singular': translate('RemotePlugin', 'Remote', 'name singular'),
'plural': translate('RemotePlugin', 'Remotes', 'name plural') 'plural': translate('RemotePlugin', 'Remotes', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## # Name for MediaDockManager, SettingsManager
self.text_strings[StringContent.VisibleName] = { self.text_strings[StringContent.VisibleName] = {
'title': translate('RemotePlugin', 'Remote', 'container title') 'title': translate('RemotePlugin', 'Remote', 'container title')
} }

View File

@ -114,7 +114,7 @@ class DuplicateSongRemovalForm(OpenLPWizard, RegistryProperties):
self.review_layout.addWidget(self.review_scroll_area) self.review_layout.addWidget(self.review_scroll_area)
self.review_page_id = self.addPage(self.review_page) self.review_page_id = self.addPage(self.review_page)
# Add a dummy page to the end, to prevent the finish button to appear and the next button do disappear on the # Add a dummy page to the end, to prevent the finish button to appear and the next button do disappear on the
#review page. # review page.
self.dummy_page = QtGui.QWizardPage() self.dummy_page = QtGui.QWizardPage()
self.dummy_page_id = self.addPage(self.dummy_page) self.dummy_page_id = self.addPage(self.dummy_page)
@ -217,12 +217,12 @@ class DuplicateSongRemovalForm(OpenLPWizard, RegistryProperties):
duplicate_added = False duplicate_added = False
for duplicate_group in self.duplicate_song_list: for duplicate_group in self.duplicate_song_list:
# Skip the first song in the duplicate lists, since the first one has to be an earlier song. # Skip the first song in the duplicate lists, since the first one has to be an earlier song.
if search_song in duplicate_group and not duplicate_song in duplicate_group: if search_song in duplicate_group and duplicate_song not in duplicate_group:
duplicate_group.append(duplicate_song) duplicate_group.append(duplicate_song)
duplicate_group_found = True duplicate_group_found = True
duplicate_added = True duplicate_added = True
break break
elif not search_song in duplicate_group and duplicate_song in duplicate_group: elif search_song not in duplicate_group and duplicate_song in duplicate_group:
duplicate_group.append(search_song) duplicate_group.append(search_song)
duplicate_group_found = True duplicate_group_found = True
duplicate_added = True duplicate_added = True

View File

@ -675,14 +675,13 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog, RegistryProperties):
separator = parts.find(':') separator = parts.find(':')
if separator >= 0: if separator >= 0:
verse_name = parts[0:separator].strip() verse_name = parts[0:separator].strip()
verse_num = parts[separator+1:].strip() verse_num = parts[separator + 1:].strip()
else: else:
verse_name = parts verse_name = parts
verse_num = '1' verse_num = '1'
verse_index = VerseType.from_loose_input(verse_name) verse_index = VerseType.from_loose_input(verse_name)
verse_tag = VerseType.tags[verse_index] verse_tag = VerseType.tags[verse_index]
# Later we need to handle v1a as well. # Later we need to handle v1a as well.
#regex = re.compile(r'(\d+\w.)')
regex = re.compile(r'\D*(\d+)\D*') regex = re.compile(r'\D*(\d+)\D*')
match = regex.match(verse_num) match = regex.match(verse_num)
if match: if match:

View File

@ -75,7 +75,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
text = self.verse_text_edit.toPlainText() text = self.verse_text_edit.toPlainText()
position = self.verse_text_edit.textCursor().position() position = self.verse_text_edit.textCursor().position()
insert_string = '[---]' insert_string = '[---]'
if position and text[position-1] != '\n': if position and text[position - 1] != '\n':
insert_string = '\n' + insert_string insert_string = '\n' + insert_string
if position == len(text) or text[position] != '\n': if position == len(text) or text[position] != '\n':
insert_string += '\n' insert_string += '\n'

View File

@ -66,8 +66,10 @@ class Ui_MediaFilesDialog(object):
def retranslateUi(self, media_files_dialog): def retranslateUi(self, media_files_dialog):
""" """
Translate the UI on the fly. Translate the UI on the fly.
:param media_files_dialog:
""" """
media_files_dialog.setWindowTitle(translate('SongsPlugin.MediaFilesForm', 'Select Media File(s)')) media_files_dialog.setWindowTitle(translate('SongsPlugin.MediaFilesForm', 'Select Media File(s)'))
self.select_label.setText(translate('SongsPlugin.MediaFilesForm', self.select_label.setText(translate('SongsPlugin.MediaFilesForm', 'Select one or more audio files from the '
'Select one or more audio files from the list below, and click OK to import them ' 'list below, and click OK to import them '
'into this song.')) 'into this song.'))

View File

@ -152,9 +152,9 @@ class SongExportForm(OpenLPWizard):
self.setWindowTitle(translate('SongsPlugin.ExportWizardForm', 'Song Export Wizard')) self.setWindowTitle(translate('SongsPlugin.ExportWizardForm', 'Song Export Wizard'))
self.title_label.setText(WizardStrings.HeaderStyle % self.title_label.setText(WizardStrings.HeaderStyle %
translate('OpenLP.Ui', 'Welcome to the Song Export Wizard')) translate('OpenLP.Ui', 'Welcome to the Song Export Wizard'))
self.information_label.setText(translate('SongsPlugin.ExportWizardForm', 'This wizard will help to' self.information_label.setText(
' export your songs to the open and free <strong>OpenLyrics </strong> worship ' translate('SongsPlugin.ExportWizardForm', 'This wizard will help to export your songs to the open and free '
'song format.')) '<strong>OpenLyrics </strong> worship song format.'))
self.available_songs_page.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Songs')) self.available_songs_page.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
self.available_songs_page.setSubTitle(translate('SongsPlugin.ExportWizardForm', self.available_songs_page.setSubTitle(translate('SongsPlugin.ExportWizardForm',
'Check the songs you want to export.')) 'Check the songs you want to export.'))

View File

@ -270,13 +270,13 @@ class CCLIFileImport(SongImport):
verse_text = '' verse_text = ''
verse_start = False verse_start = False
else: else:
#line_number=0, song title # line_number=0, song title
if line_number == 0: if line_number == 0:
self.title = clean_line self.title = clean_line
line_number += 1 line_number += 1
#line_number=1, verses # line_number=1, verses
elif line_number == 1: elif line_number == 1:
#line_number=1, ccli number, first line after verses # line_number=1, ccli number, first line after verses
if clean_line.startswith('CCLI'): if clean_line.startswith('CCLI'):
line_number += 1 line_number += 1
ccli_parts = clean_line.split(' ') ccli_parts = clean_line.split(' ')
@ -319,21 +319,21 @@ class CCLIFileImport(SongImport):
# last part. Add l so as to keep the CRLF # last part. Add l so as to keep the CRLF
verse_text = verse_text + line verse_text = verse_text + line
else: else:
#line_number=2, copyright # line_number=2, copyright
if line_number == 2: if line_number == 2:
line_number += 1 line_number += 1
if clean_line.startswith('©'): if clean_line.startswith('©'):
self.copyright = clean_line self.copyright = clean_line
else: else:
song_author = clean_line song_author = clean_line
#n=3, authors # n=3, authors
elif line_number == 3: elif line_number == 3:
line_number += 1 line_number += 1
if song_author: if song_author:
self.copyright = clean_line self.copyright = clean_line
else: else:
song_author = clean_line song_author = clean_line
#line_number=4, comments lines before last line # line_number=4, comments lines before last line
elif line_number == 4 and not clean_line.startswith('CCL'): elif line_number == 4 and not clean_line.startswith('CCL'):
self.comments += clean_line self.comments += clean_line
# split on known separators # split on known separators

View File

@ -305,7 +305,7 @@ class EasyWorshipSongImport(SongImport):
elif field_desc.field_type == FieldType.Logical: elif field_desc.field_type == FieldType.Logical:
return field ^ 0x80 == 1 return field ^ 0x80 == 1
elif field_desc.field_type == FieldType.Memo or field_desc.field_type == FieldType.Blob: elif field_desc.field_type == FieldType.Memo or field_desc.field_type == FieldType.Blob:
block_start, blob_size = struct.unpack_from('<II', field, len(field)-10) block_start, blob_size = struct.unpack_from('<II', field, len(field) - 10)
sub_block = block_start & 0xff sub_block = block_start & 0xff
block_start &= ~0xff block_start &= ~0xff
self.memo_file.seek(block_start) self.memo_file.seek(block_start)

View File

@ -96,7 +96,7 @@ class SongMediaItem(MediaManagerItem):
def add_end_header_bar(self): def add_end_header_bar(self):
self.toolbar.addSeparator() self.toolbar.addSeparator()
## Song Maintenance Button ## # Song Maintenance Button
self.maintenance_action = self.toolbar.add_toolbar_action('maintenance_action', self.maintenance_action = self.toolbar.add_toolbar_action('maintenance_action',
icon=':/songs/song_maintenance.png', icon=':/songs/song_maintenance.png',
triggers=self.on_song_maintenance_click) triggers=self.on_song_maintenance_click)
@ -266,7 +266,7 @@ class SongMediaItem(MediaManagerItem):
# Do not display temporary songs # Do not display temporary songs
if song.temporary: if song.temporary:
continue continue
if song_number and not song_number in song.song_number: if song_number and song_number not in song.song_number:
continue continue
song_detail = '%s - %s (%s)' % (book.name, song.song_number, song.title) song_detail = '%s - %s (%s)' % (book.name, song.song_number, song.title)
song_name = QtGui.QListWidgetItem(song_detail) song_name = QtGui.QListWidgetItem(song_detail)

View File

@ -132,7 +132,7 @@ class SongsPlugin(Plugin):
) )
import_menu.addAction(self.import_songselect_item) import_menu.addAction(self.import_songselect_item)
def add_export_menu_Item(self, export_menu): def add_export_menu_item(self, export_menu):
""" """
Give the Songs plugin the opportunity to add items to the **Export** menu. Give the Songs plugin the opportunity to add items to the **Export** menu.
@ -261,12 +261,12 @@ class SongsPlugin(Plugin):
""" """
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
""" """
## Name PluginList ## # Name PluginList
self.text_strings[StringContent.Name] = { self.text_strings[StringContent.Name] = {
'singular': translate('SongsPlugin', 'Song', 'name singular'), 'singular': translate('SongsPlugin', 'Song', 'name singular'),
'plural': translate('SongsPlugin', 'Songs', 'name plural') 'plural': translate('SongsPlugin', 'Songs', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## # Name for MediaDockManager, SettingsManager
self.text_strings[StringContent.VisibleName] = { self.text_strings[StringContent.VisibleName] = {
'title': translate('SongsPlugin', 'Songs', 'container title') 'title': translate('SongsPlugin', 'Songs', 'container title')
} }

View File

@ -246,12 +246,12 @@ class SongUsagePlugin(Plugin):
""" """
Called to define all translatable texts of the plugin Called to define all translatable texts of the plugin
""" """
## Name PluginList ## # Name PluginList
self.text_strings[StringContent.Name] = { self.text_strings[StringContent.Name] = {
'singular': translate('SongUsagePlugin', 'SongUsage', 'name singular'), 'singular': translate('SongUsagePlugin', 'SongUsage', 'name singular'),
'plural': translate('SongUsagePlugin', 'SongUsage', 'name plural') 'plural': translate('SongUsagePlugin', 'SongUsage', 'name plural')
} }
## Name for MediaDockManager, SettingsManager ## # Name for MediaDockManager, SettingsManager
self.text_strings[StringContent.VisibleName] = { self.text_strings[StringContent.VisibleName] = {
'title': translate('SongUsagePlugin', 'SongUsage', 'container title') 'title': translate('SongUsagePlugin', 'SongUsage', 'container title')
} }

View File

@ -32,12 +32,13 @@ Functional tests to test the AppLocation class and related methods.
from unittest import TestCase from unittest import TestCase
from openlp.core.common import de_hump from openlp.core.common import de_hump, trace_error_handler
from tests.functional import MagicMock, patch
class TestInitFunctions(TestCase): class TestCommonFunctions(TestCase):
""" """
A test suite to test out various functions in the __init__ class. A test suite to test out various functions in the openlp.core.common module.
""" """
def de_hump_conversion_test(self): def de_hump_conversion_test(self):
""" """
@ -64,3 +65,19 @@ class TestInitFunctions(TestCase):
# THEN: the new string should be converted to python format # THEN: the new string should be converted to python format
self.assertTrue(new_string == "my_class", 'The class name should have been preserved') self.assertTrue(new_string == "my_class", 'The class name should have been preserved')
def trace_error_handler_test(self):
"""
Test the trace_error_handler() method
"""
# GIVEN: Mocked out objects
with patch('openlp.core.common.traceback') as mocked_traceback:
mocked_traceback.extract_stack.return_value = [('openlp.fake', 56, None, 'trace_error_handler_test')]
mocked_logger = MagicMock()
# WHEN: trace_error_handler() is called
trace_error_handler(mocked_logger)
# THEN: The mocked_logger.error() method should have been called with the correct parameters
mocked_logger.error.assert_called_with('OpenLP Error trace\n File openlp.fake at line 56 \n\t called trace_error_handler_test')

View File

@ -50,8 +50,8 @@ class TestDB(TestCase):
""" """
# GIVEN: Mocked out SQLAlchemy calls and return objects, and an in-memory SQLite database URL # GIVEN: Mocked out SQLAlchemy calls and return objects, and an in-memory SQLite database URL
with patch('openlp.core.lib.db.create_engine') as mocked_create_engine, \ with patch('openlp.core.lib.db.create_engine') as mocked_create_engine, \
patch('openlp.core.lib.db.MetaData') as MockedMetaData, \ patch('openlp.core.lib.db.MetaData') as MockedMetaData, \
patch('openlp.core.lib.db.sessionmaker') as mocked_sessionmaker, \ patch('openlp.core.lib.db.sessionmaker') as mocked_sessionmaker, \
patch('openlp.core.lib.db.scoped_session') as mocked_scoped_session: patch('openlp.core.lib.db.scoped_session') as mocked_scoped_session:
mocked_engine = MagicMock() mocked_engine = MagicMock()
mocked_metadata = MagicMock() mocked_metadata = MagicMock()

View File

@ -212,9 +212,9 @@ class TestPluginManager(TestCase):
# WHEN: We run hook_export_menu() # WHEN: We run hook_export_menu()
plugin_manager.hook_export_menu() plugin_manager.hook_export_menu()
# THEN: The add_export_menu_Item() method should not have been called # THEN: The add_export_menu_item() method should not have been called
self.assertEqual(0, mocked_plugin.add_export_menu_Item.call_count, self.assertEqual(0, mocked_plugin.add_export_menu_item.call_count,
'The add_export_menu_Item() method should not have been called.') 'The add_export_menu_item() method should not have been called.')
def hook_export_menu_with_active_plugin_test(self): def hook_export_menu_with_active_plugin_test(self):
""" """
@ -229,8 +229,8 @@ class TestPluginManager(TestCase):
# WHEN: We run hook_export_menu() # WHEN: We run hook_export_menu()
plugin_manager.hook_export_menu() plugin_manager.hook_export_menu()
# THEN: The add_export_menu_Item() method should have been called # THEN: The add_export_menu_item() method should have been called
mocked_plugin.add_export_menu_Item.assert_called_with(self.mocked_main_window.file_export_menu) mocked_plugin.add_export_menu_item.assert_called_with(self.mocked_main_window.file_export_menu)
def hook_upgrade_plugin_settings_with_disabled_plugin_test(self): def hook_upgrade_plugin_settings_with_disabled_plugin_test(self):
""" """
@ -264,7 +264,7 @@ class TestPluginManager(TestCase):
# WHEN: We run hook_upgrade_plugin_settings() # WHEN: We run hook_upgrade_plugin_settings()
plugin_manager.hook_upgrade_plugin_settings(settings) plugin_manager.hook_upgrade_plugin_settings(settings)
# THEN: The add_export_menu_Item() method should have been called # THEN: The add_export_menu_item() method should have been called
mocked_plugin.upgrade_settings.assert_called_with(settings) mocked_plugin.upgrade_settings.assert_called_with(settings)
def hook_tools_menu_with_disabled_plugin_test(self): def hook_tools_menu_with_disabled_plugin_test(self):

View File

@ -81,3 +81,20 @@ class TestUi(TestCase):
self.assertIsInstance(btnbox, QtGui.QDialogButtonBox) self.assertIsInstance(btnbox, QtGui.QDialogButtonBox)
self.assertEqual(1, len(btnbox.buttons())) self.assertEqual(1, len(btnbox.buttons()))
self.assertEqual(QtGui.QDialogButtonBox.HelpRole, btnbox.buttonRole(btnbox.buttons()[0])) self.assertEqual(QtGui.QDialogButtonBox.HelpRole, btnbox.buttonRole(btnbox.buttons()[0]))
def test_create_valign_selection_widgets(self):
"""
Test creating a combo box for valign selection
"""
# GIVEN: A dialog
dialog = QtGui.QDialog()
# WHEN: We create the widgets
label, combo = create_valign_selection_widgets(dialog)
# THEN: We should get a label and a combobox.
self.assertEqual(translate('OpenLP.Ui', '&Vertical Align:'), label.text())
self.assertIsInstance(combo, QtGui.QComboBox)
self.assertEqual(combo, label.buddy())
for text in [UiStrings().Top, UiStrings().Middle, UiStrings().Bottom]:
self.assertTrue(combo.findText(text) >= 0)

View File

@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
Package to test openlp.core.ui.mainwindow package.
"""
import os
from unittest import TestCase
from openlp.core.ui.mainwindow import MainWindow
from openlp.core.common.registry import Registry
from tests.utils.constants import TEST_RESOURCES_PATH
from tests.helpers.testmixin import TestMixin
from tests.functional import MagicMock, patch
class TestMainWindow(TestCase, TestMixin):
def setUp(self):
Registry.create()
self.registry = Registry()
self.get_application()
# Mock cursor busy/normal methods.
self.app.set_busy_cursor = MagicMock()
self.app.set_normal_cursor = MagicMock()
self.app.args = []
Registry().register('application', self.app)
# Mock classes and methods used by mainwindow.
with patch('openlp.core.ui.mainwindow.SettingsForm') as mocked_settings_form, \
patch('openlp.core.ui.mainwindow.ImageManager') as mocked_image_manager, \
patch('openlp.core.ui.mainwindow.LiveController') as mocked_live_controller, \
patch('openlp.core.ui.mainwindow.PreviewController') as mocked_preview_controller, \
patch('openlp.core.ui.mainwindow.OpenLPDockWidget') as mocked_dock_widget, \
patch('openlp.core.ui.mainwindow.QtGui.QToolBox') as mocked_q_tool_box_class, \
patch('openlp.core.ui.mainwindow.QtGui.QMainWindow.addDockWidget') as mocked_add_dock_method, \
patch('openlp.core.ui.mainwindow.ThemeManager') as mocked_theme_manager, \
patch('openlp.core.ui.mainwindow.Renderer') as mocked_renderer:
self.main_window = MainWindow()
def tearDown(self):
del self.main_window
def cmd_line_file_test(self):
"""
Test that passing a service file from the command line loads the service.
"""
# GIVEN a service as an argument to openlp
service = os.path.join(TEST_RESOURCES_PATH, 'service', 'test.osz')
self.main_window.arguments = [service]
with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:
# WHEN the argument is processed
self.main_window.open_cmd_line_files()
# THEN the service from the arguments is loaded
mocked_load_path.assert_called_with(service), 'load_path should have been called with the service\'s path'
def cmd_line_arg_test(self):
"""
Test that passing a non service file does nothing.
"""
# GIVEN a non service file as an argument to openlp
service = os.path.join('openlp.py')
self.main_window.arguments = [service]
with patch('openlp.core.ui.servicemanager.ServiceManager.load_file') as mocked_load_path:
# WHEN the argument is processed
self.main_window.open_cmd_line_files()
# THEN the file should not be opened
assert not mocked_load_path.called, 'load_path should not have been called'

View File

@ -313,6 +313,7 @@ class TestServiceManager(TestCase, TestMixin):
self.service_manager.notes_action.setVisible = MagicMock() self.service_manager.notes_action.setVisible = MagicMock()
self.service_manager.time_action.setVisible = MagicMock() self.service_manager.time_action.setVisible = MagicMock()
self.service_manager.auto_start_action.setVisible = MagicMock() self.service_manager.auto_start_action.setVisible = MagicMock()
self.service_manager.rename_action.setVisible = MagicMock()
# WHEN: Show the context menu. # WHEN: Show the context menu.
self.service_manager.context_menu(q_point) self.service_manager.context_menu(q_point)
@ -329,6 +330,8 @@ class TestServiceManager(TestCase, TestMixin):
'The action should be set invisible.' 'The action should be set invisible.'
self.service_manager.auto_start_action.setVisible.assert_called_with(True), \ self.service_manager.auto_start_action.setVisible.assert_called_with(True), \
'The action should be set visible.' 'The action should be set visible.'
self.service_manager.rename_action.setVisible.assert_called_once_with(False), \
'The action should be set invisible.'
def click_on_new_service_test(self): def click_on_new_service_test(self):
""" """

View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
Test the openlp.core.ui.splashscreen class.
"""
from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.ui import SplashScreen
from tests.helpers.testmixin import TestMixin
class TestSplashScreen(TestCase, TestMixin):
def setUp(self):
self.get_application()
self.main_window = QtGui.QMainWindow()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.app
del self.main_window
def setupUi_test(self):
"""
Test if the setupUi method....
"""
# GIVEN: A splash screen instance.
splash = SplashScreen()
# THEN: Check if the splash has a setupUi method.
assert hasattr(splash, 'setupUi'), 'The Splash Screen should have a setupUi() method.'

Binary file not shown.

View File

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
Package to test for proper bzr tags.
"""
from unittest import TestCase
from subprocess import Popen, PIPE
TAGS = [
['1.9.0', '1'],
['1.9.1', '775'],
['1.9.2', '890'],
['1.9.3', '1063'],
['1.9.4', '1196'],
['1.9.5', '1421'],
['1.9.6', '1657'],
['1.9.7', '1761'],
['1.9.8', '1856'],
['1.9.9', '1917'],
['1.9.10', '2003'],
['1.9.11', '2039'],
['1.9.12', '2063'],
['2.0', '2118'],
['2.0.1', '?'],
['2.0.2', '?'],
['2.0.3', '?'],
['2.1.0', '2119']
]
class TestBzrTags(TestCase):
def bzr_tags_test(self):
"""
Test for proper bzr tags
"""
# GIVEN: A bzr branch
# WHEN getting the branches tags
bzr = Popen(('bzr', 'tags'), stdout=PIPE)
stdout = bzr.communicate()[0]
tags = [line.decode('utf-8').split() for line in stdout.splitlines()]
# THEN the tags should match the accepted tags
self.assertEqual(TAGS, tags, 'List of tags should match')