diff --git a/openlp/__init__.py b/openlp/__init__.py index ac5f063d4..98e847979 100644 --- a/openlp/__init__.py +++ b/openlp/__init__.py @@ -30,7 +30,6 @@ The :mod:`openlp` module contains all the project produced OpenLP functionality """ -import openlp.core -import openlp.plugins +from openlp import core, plugins __all__ = ['core', 'plugins'] diff --git a/openlp/core/common/__init__.py b/openlp/core/common/__init__.py index 03bf964bc..22207dec4 100644 --- a/openlp/core/common/__init__.py +++ b/openlp/core/common/__init__.py @@ -38,7 +38,7 @@ import traceback from PyQt4 import QtCore -log = logging.getLogger(__name__+'.__init__') +log = logging.getLogger(__name__ + '.__init__') FIRST_CAMEL_REGEX = re.compile('(.)([A-Z][a-z]+)') @@ -51,8 +51,10 @@ def trace_error_handler(logger): :param logger: logger to use so traceback is logged to correct class """ + log_string = "OpenLP Error trace" for tb in traceback.extract_stack(): - logger.error('Called by ' + tb[3] + ' at line ' + str(tb[1]) + ' in ' + tb[0]) + log_string = '%s\n File %s at line %d \n\t called %s' % (log_string, tb[0], tb[1], tb[3]) + logger.error(log_string) def check_directory_exists(directory, do_not_log=False): @@ -74,6 +76,9 @@ def check_directory_exists(directory, do_not_log=False): def get_frozen_path(frozen_option, non_frozen_option): """ Return a path based on the system status. + + :param frozen_option: + :param non_frozen_option: """ if hasattr(sys, 'frozen') and sys.frozen == 1: return frozen_option diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index e6b7f4fe3..9561baff4 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -39,7 +39,7 @@ from PyQt4 import QtCore, QtGui, Qt from openlp.core.common import translate -log = logging.getLogger(__name__+'.__init__') +log = logging.getLogger(__name__ + '.__init__') class ServiceItemContext(object): diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 13d4b0bbb..4d7676ad6 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -168,29 +168,29 @@ class MediaManagerItem(QtGui.QWidget, RegistryProperties): Create buttons for the media item toolbar """ toolbar_actions = [] - ## Import Button ## + # Import Button if self.has_import_icon: toolbar_actions.append(['Import', StringContent.Import, ':/general/general_import.png', self.on_import_click]) - ## Load Button ## + # Load Button if self.has_file_icon: toolbar_actions.append(['Load', StringContent.Load, ':/general/general_open.png', self.on_file_click]) - ## New Button ## + # New Button if self.has_new_icon: toolbar_actions.append(['New', StringContent.New, ':/general/general_new.png', self.on_new_click]) - ## Edit Button ## + # Edit Button if self.has_edit_icon: toolbar_actions.append(['Edit', StringContent.Edit, ':/general/general_edit.png', self.on_edit_click]) - ## Delete Button ## + # Delete Button if self.has_delete_icon: toolbar_actions.append(['Delete', StringContent.Delete, ':/general/general_delete.png', self.on_delete_click]) - ## Preview ## + # Preview toolbar_actions.append(['Preview', StringContent.Preview, ':/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]) - ## Add to service Button ## + # Add to service Button toolbar_actions.append(['Service', StringContent.Service, ':/general/general_add.png', self.on_add_click]) for action in toolbar_actions: if action[0] == StringContent.Preview: diff --git a/openlp/core/lib/plugin.py b/openlp/core/lib/plugin.py index e14fe8bb0..1f459524c 100644 --- a/openlp/core/lib/plugin.py +++ b/openlp/core/lib/plugin.py @@ -101,7 +101,7 @@ class Plugin(QtCore.QObject, RegistryProperties): ``add_import_menu_item(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. ``create_settings_tab()`` @@ -226,7 +226,7 @@ class Plugin(QtCore.QObject, RegistryProperties): """ 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. @@ -329,22 +329,24 @@ class Plugin(QtCore.QObject, RegistryProperties): def set_plugin_ui_text_strings(self, tooltips): """ 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']) - ## Import Action ## + # Import Action 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']) - ## Edit Action ## + # Edit Action 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']) - ## Preview Action ## + # Preview Action 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']) - ## Add to Service Action ## + # Add to Service Action self.__set_name_text_string(StringContent.Service, UiStrings().Service, tooltips['service']) def __set_name_text_string(self, name, title, tooltip): diff --git a/openlp/core/lib/pluginmanager.py b/openlp/core/lib/pluginmanager.py index d24f07eac..474113c98 100644 --- a/openlp/core/lib/pluginmanager.py +++ b/openlp/core/lib/pluginmanager.py @@ -161,7 +161,7 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties): """ for plugin in self.plugins: 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): """ diff --git a/openlp/core/lib/searchedit.py b/openlp/core/lib/searchedit.py index bb510d046..de329236c 100644 --- a/openlp/core/lib/searchedit.py +++ b/openlp/core/lib/searchedit.py @@ -178,15 +178,7 @@ class SearchEdit(QtGui.QLineEdit): correct action on the button, and set the current search type (using the list of identifiers provided by the developer), the ``searchTypeChanged(int)`` signal is emitted with the identifier. """ - sender = self.sender() for action in self.menu_button.menu().actions(): + # Why is this needed? action.setChecked(False) - self.menu_button.setDefaultAction(sender) - self._current_search_type = sender.data() - # setplaceholder_text has been implemented in Qt 4.7 and in at least - # PyQt 4.9 (I am not sure, if it was implemented in PyQt 4.8). - try: - self.setPlaceholderText(self.menu_button.defaultAction().placeholder_text) - except AttributeError: - pass - self.emit(QtCore.SIGNAL('searchTypeChanged(int)'), self._current_search_type) + self.set_current_search_type(self.sender().data()) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 6d07e1c34..17d11ef63 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -108,6 +108,9 @@ class ItemCapabilities(object): ``CanAutoStartForLive`` The capability to ignore the do not play if display blank flag. + ``CanEditTitle`` + The capability to edit the title of the item + """ CanPreview = 1 CanEdit = 2 @@ -125,6 +128,7 @@ class ItemCapabilities(object): CanWordSplit = 14 HasBackgroundAudio = 15 CanAutoStartForLive = 16 + CanEditTitle = 17 class ServiceItem(RegistryProperties): @@ -383,7 +387,7 @@ class ServiceItem(RegistryProperties): self.will_auto_start = header.get('will_auto_start', False) self.processor = header.get('processor', None) 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): self.capabilities.remove(ItemCapabilities.HasDetailedTitleDisplay) self.processor = self.title @@ -423,7 +427,7 @@ class ServiceItem(RegistryProperties): """ Returns the title of the service item. """ - if self.is_text(): + if self.is_text() or ItemCapabilities.CanEditTitle in self.capabilities: return self.title else: if len(self._raw_frames) > 1: diff --git a/openlp/core/ui/exceptiondialog.py b/openlp/core/ui/exceptiondialog.py index 4d7abe708..212fee4cd 100644 --- a/openlp/core/ui/exceptiondialog.py +++ b/openlp/core/ui/exceptiondialog.py @@ -95,15 +95,15 @@ class Ui_ExceptionDialog(object): Translate the widgets on the fly. """ exception_dialog.setWindowTitle(translate('OpenLP.ExceptionDialog', 'Error Occurred')) - self.description_explanation.setText(translate('OpenLP.ExceptionDialog', - 'Please enter a description of what you were doing to cause this error ' - '\n(Minimum 20 characters)')) - self.message_label.setText(translate('OpenLP.ExceptionDialog', 'Oops! ' - 'OpenLP hit a problem, and couldn\'t recover. The text in the box ' - 'below contains information that might be helpful to the OpenLP ' - 'developers, so please e-mail it to bugs@openlp.org, along with a ' - 'detailed description of what you were doing when the problem ' - 'occurred.')) + self.description_explanation.setText( + translate('OpenLP.ExceptionDialog', 'Please enter a description of what you were doing to cause this error ' + '\n(Minimum 20 characters)')) + self.message_label.setText( + translate('OpenLP.ExceptionDialog', 'Oops! OpenLP hit a problem, and couldn\'t recover. The text in the ' + 'box below contains information that might be helpful to the OpenLP ' + 'developers, so please e-mail it to bugs@openlp.org, along with a ' + 'detailed description of what you were doing when the problem ' + 'occurred.')) self.send_report_button.setText(translate('OpenLP.ExceptionDialog', 'Send E-Mail')) self.save_report_button.setText(translate('OpenLP.ExceptionDialog', 'Save to File')) self.attach_tile_button.setText(translate('OpenLP.ExceptionDialog', 'Attach File')) diff --git a/openlp/core/ui/firsttimewizard.py b/openlp/core/ui/firsttimewizard.py index 407842c48..1a270f931 100644 --- a/openlp/core/ui/firsttimewizard.py +++ b/openlp/core/ui/firsttimewizard.py @@ -211,9 +211,9 @@ class Ui_FirstTimeWizard(object): first_time_wizard.setWindowTitle(translate('OpenLP.FirstTimeWizard', 'First Time Wizard')) self.title_label.setText('%s' % translate('OpenLP.FirstTimeWizard', 'Welcome to the First Time Wizard')) - self.information_label.setText(translate('OpenLP.FirstTimeWizard', - 'This wizard will help you to configure OpenLP for initial use. ' - 'Click the next button below to start.')) + self.information_label.setText( + translate('OpenLP.FirstTimeWizard', 'This wizard will help you to configure OpenLP for initial use. ' + 'Click the next button below to start.')) 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.songs_check_box.setText(translate('OpenLP.FirstTimeWizard', 'Songs')) diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index b7153429d..be4247bc1 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -63,7 +63,6 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont self.services = FormattingTagController() self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected) 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.tag_table_widget.currentCellChanged.connect(self.on_current_cell_changed) self.button_box.rejected.connect(self.close) @@ -202,5 +201,4 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont if errors: QtGui.QMessageBox.warning(self, translate('OpenLP.FormattingTagForm', 'Validation Error'), errors, QtGui.QMessageBox.Ok) - #self.tag_table_widget.selectRow(pre_row - 1) self.tag_table_widget.resizeRowsToContents() diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 703307e18..81e822c16 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -56,29 +56,27 @@ from openlp.core.ui.firsttimeform import FirstTimeForm log = logging.getLogger(__name__) MEDIA_MANAGER_STYLE = """ - QToolBox { +QToolBox { padding-bottom: 2px; - } - QToolBox::tab { +} +QToolBox::tab { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 palette(button), stop: 0.5 palette(button), - stop: 1.0 palette(mid)); - border: 1px groove palette(mid); - border-radius: 5px; - } - QToolBox::tab:selected { + stop: 0 palette(button), stop: 1.0 palette(mid)); + border: 1px solid palette(mid); + border-radius: 3px; +} +QToolBox::tab:selected { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 palette(light), stop: 0.5 palette(midlight), - stop: 1.0 palette(dark)); - border: 1px groove palette(dark); + stop: 0 palette(light), stop: 1.0 palette(button)); + border: 1px solid palette(mid); font-weight: bold; - } +} """ PROGRESSBAR_STYLE = """ - QProgressBar{ - height: 10px; - } +QProgressBar{ + height: 10px; +} """ @@ -369,7 +367,7 @@ class Ui_MainWindow(object): self.settings_menu.setTitle(translate('OpenLP.MainWindow', '&Settings')) self.settings_language_menu.setTitle(translate('OpenLP.MainWindow', '&Language')) 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.theme_manager_dock.setWindowTitle(translate('OpenLP.MainWindow', 'Theme Manager')) 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.formatting_tag_item.setText(translate('OpenLP.MainWindow', 'Configure &Formatting Tags...')) self.settings_configure_item.setText(translate('OpenLP.MainWindow', '&Configure OpenLP...')) - self.settings_export_item.setStatusTip(translate('OpenLP.MainWindow', - 'Export OpenLP settings to a specified *.config file')) + self.settings_export_item.setStatusTip( + translate('OpenLP.MainWindow', 'Export OpenLP settings to a specified *.config file')) self.settings_export_item.setText(translate('OpenLP.MainWindow', 'Settings')) - self.settings_import_item.setStatusTip(translate('OpenLP.MainWindow', - 'Import OpenLP settings from a specified *.config file previously ' - 'exported on this or another machine')) + self.settings_import_item.setStatusTip( + translate('OpenLP.MainWindow', 'Import OpenLP settings from a specified *.config file previously ' + 'exported on this or another machine')) 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.setToolTip(translate('OpenLP.MainWindow', 'Toggle Media Manager')) @@ -598,13 +596,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties): self.live_controller.display.setFocus() self.activateWindow() if self.arguments: - args = [] - 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) + self.open_cmd_line_files() elif Settings().value(self.general_settings_section + '/auto open'): self.service_manager_contents.load_Last_file() self.timer_version_id = self.startTimer(1000) @@ -652,7 +644,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties): translate('OpenLP.MainWindow', 'Are you sure you want to re-run the First ' 'Time Wizard?\n\nRe-running this wizard may make changes to your ' 'current OpenLP configuration and possibly add songs to your ' - '#existing songs list and change your default theme.'), + 'existing songs list and change your default theme.'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.No) @@ -868,7 +860,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties): section = 'general' section_key = section + "/" + key # Make sure it's a valid section for us. - if not section in setting_sections: + if section not in setting_sections: continue # We have a good file, import it. 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): settings.remove('advanced/data path') 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) diff --git a/openlp/core/ui/media/__init__.py b/openlp/core/ui/media/__init__.py index 1276c8662..8cc10b6a1 100644 --- a/openlp/core/ui/media/__init__.py +++ b/openlp/core/ui/media/__init__.py @@ -35,7 +35,7 @@ from openlp.core.common import Settings from PyQt4 import QtCore -log = logging.getLogger(__name__+'.__init__') +log = logging.getLogger(__name__ + '.__init__') class MediaState(object): diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index d846af0e4..0b065c131 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -137,7 +137,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties): for player in list(self.media_players.values()): if player.is_active: 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) suffix_list.append(item[2:]) self.video_extensions_list = [] @@ -184,8 +184,8 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties): return False saved_players, overridden_player = get_media_players() invalid_media_players = \ - [mediaPlayer for mediaPlayer in saved_players if not mediaPlayer in self.media_players or - not self.media_players[mediaPlayer].check_available()] + [media_player for media_player in saved_players if media_player not in self.media_players or + not self.media_players[media_player].check_available()] if invalid_media_players: for invalidPlayer in invalid_media_players: saved_players.remove(invalidPlayer) diff --git a/openlp/core/ui/media/vendor/vlc.py b/openlp/core/ui/media/vendor/vlc.py index 6e17c002f..0326e4104 100644 --- a/openlp/core/ui/media/vendor/vlc.py +++ b/openlp/core/ui/media/vendor/vlc.py @@ -48,13 +48,13 @@ import sys from inspect import getargspec __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: str = str - str = str + unicode = str bytes = bytes - str = (str, bytes) + basestring = (str, bytes) PYTHON3 = True def str_to_bytes(s): """Translate string or bytes to bytes. @@ -73,14 +73,14 @@ if sys.version_info[0] > 2: return b else: str = str - str = str + unicode = unicode bytes = str - str = str + basestring = basestring PYTHON3 = False def str_to_bytes(s): """Translate string or bytes to bytes. """ - if isinstance(s, str): + if isinstance(s, unicode): return s.encode(sys.getfilesystemencoding()) else: return s @@ -89,7 +89,7 @@ else: """Translate bytes to unicode string. """ if isinstance(b, str): - return str(b, sys.getfilesystemencoding()) + return unicode(b, sys.getfilesystemencoding()) else: return b @@ -110,7 +110,7 @@ def find_lib(): p = find_library('libvlc.dll') if p is None: 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: try: r = w.OpenKey(r, 'Software\\VideoLAN\\VLC') @@ -168,7 +168,7 @@ class VLCException(Exception): pass try: - _Ints = (int, int) + _Ints = (int, long) except NameError: # no long in Python 3+ _Ints = int _Seqs = (list, tuple) @@ -327,6 +327,9 @@ class _Enum(ctypes.c_uint): n = self._enum_names_.get(self.value, '') or ('FIXME_(%r)' % (self.value,)) return '.'.join((self.__class__.__name__, n)) + def __hash__(self): + return self.value + def __repr__(self): return '.'.join((self.__class__.__module__, self.__str__())) @@ -1294,7 +1297,7 @@ class Instance(_Ctype): i = args[0] if isinstance(i, _Ints): return _Constructor(cls, i) - elif isinstance(i, str): + elif isinstance(i, basestring): args = i.strip().split() elif isinstance(i, _Seqs): args = i @@ -2078,7 +2081,7 @@ class MediaList(_Ctype): @param mrl: a media instance or a MRL. @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) 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) 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): '''Unsets the logging callback for a LibVLC instance. This is rarely needed: 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_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_list_release # libvlc_clearerr @@ -5838,6 +5874,8 @@ def libvlc_vlm_get_event_manager(p_instance): # libvlc_get_changeset # libvlc_get_compiler # libvlc_get_version +# libvlc_log_get_context +# libvlc_log_get_object # libvlc_media_tracks_release # libvlc_module_description_list_release # libvlc_new @@ -5910,9 +5948,9 @@ def debug_callback(event, *args, **kwds): ''' l = ['event %s' % (event.type,)] if args: - l.extend(list(map(str, args))) + l.extend(map(str, args)) 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)) if __name__ == '__main__': diff --git a/openlp/core/ui/media/webkitplayer.py b/openlp/core/ui/media/webkitplayer.py index e3a522140..38e691494 100644 --- a/openlp/core/ui/media/webkitplayer.py +++ b/openlp/core/ui/media/webkitplayer.py @@ -174,34 +174,11 @@ FLASH_HTML = """ """ -VIDEO_EXT = [ - '*.3gp', - '*.3gpp', - '*.3g2', - '*.3gpp2', - '*.aac', - '*.flv', - '*.f4a', - '*.f4b', - '*.f4p', - '*.f4v', - '*.mov', - '*.m4a', - '*.m4b', - '*.m4p', - '*.m4v', - '*.mkv', - '*.mp4', - '*.ogv', - '*.webm', - '*.mpg', '*.wmv', '*.mpeg', '*.avi', - '*.swf' -] +VIDEO_EXT = ['*.3gp', '*.3gpp', '*.3g2', '*.3gpp2', '*.aac', '*.flv', '*.f4a', '*.f4b', '*.f4p', '*.f4v', '*.mov', + '*.m4a', '*.m4b', '*.m4p', '*.m4v', '*.mkv', '*.mp4', '*.ogv', '*.webm', '*.mpg', '*.wmv', '*.mpeg', + '*.avi', '*.swf'] -AUDIO_EXT = [ - '*.mp3', - '*.ogg' -] +AUDIO_EXT = ['*.mp3', '*.ogg'] class WebkitPlayer(MediaPlayer): @@ -411,10 +388,9 @@ class WebkitPlayer(MediaPlayer): """ Return some information about this player """ - return(translate('Media.player', 'Webkit is a media player which runs ' - 'inside a web browser. This player allows text over video to be ' - 'rendered.') + - '
' + translate('Media.player', 'Audio') + - '
' + str(AUDIO_EXT) + '
' + - translate('Media.player', 'Video') + '
' + - str(VIDEO_EXT) + '
') + part1 = translate('Media.player', 'Webkit is a media player which runs inside a web browser. This player ' + 'allows text over video to be rendered.') + part2 = translate('Media.player', 'Audio') + part3 = translate('Media.player', 'Video') + return part1 + '
' + part2 + '
' + str(AUDIO_EXT) + '
' + part3 + \ + '
' + str(VIDEO_EXT) + '
' diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index c2b36551a..9bc63eae6 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -234,6 +234,8 @@ class Ui_ServiceManager(object): self.menu = QtGui.QMenu() self.edit_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Edit Item'), 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'), icon=':/general/general_edit.png', 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 """ for suffix in suffix_list: - if not suffix in self.suffixes: + if suffix not in self.suffixes: self.suffixes.append(suffix) 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: self.main_window.increment_progress_bar() 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}) self.main_window.increment_progress_bar() service_content = json.dumps(service) @@ -754,8 +756,9 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage items = json.load(file_to) else: critical_error_message_box(message=translate('OpenLP.ServiceManager', - 'The service file you are trying to open is in an old format.\n ' - 'Please save it using OpenLP 2.0.2 or greater.')) + 'The service file you are trying to open is in an old ' + 'format.\n Please save it using OpenLP 2.0.2 or ' + 'greater.')) return file_to.close() self.new_file() @@ -848,6 +851,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage pos = item.data(0, QtCore.Qt.UserRole) service_item = self.service_items[pos - 1] self.edit_action.setVisible(False) + self.rename_action.setVisible(False) self.create_custom_action.setVisible(False) self.maintain_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) if service_item['service_item'].is_capable(ItemCapabilities.CanEdit) and service_item['service_item'].edit_id: 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): self.maintain_action.setVisible(True) if item.parent() is None: @@ -1482,6 +1488,22 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage if new_item: 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): """ Saves the current text item as a custom slide diff --git a/openlp/core/ui/settingsform.py b/openlp/core/ui/settingsform.py index 5aba66ef2..a1077e1f4 100644 --- a/openlp/core/ui/settingsform.py +++ b/openlp/core/ui/settingsform.py @@ -150,5 +150,5 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog, RegistryProperties): :param function: The function to be called """ - if not function in self.processes: + if function not in self.processes: self.processes.append(function) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 7faf10ca2..ed3ddaeda 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -1039,7 +1039,6 @@ class SlideController(DisplayController, RegistryProperties): """ self.preview_widget.change_slide(row) self.update_preview() - Registry().execute('slidecontroller_%s_changed' % self.type_prefix, row) def update_preview(self): """ diff --git a/openlp/core/ui/themelayoutdialog.py b/openlp/core/ui/themelayoutdialog.py index bf6c1069a..023d6259c 100644 --- a/openlp/core/ui/themelayoutdialog.py +++ b/openlp/core/ui/themelayoutdialog.py @@ -44,7 +44,6 @@ class Ui_ThemeLayoutDialog(object): Set up the UI """ themeLayoutDialog.setObjectName('themeLayoutDialogDialog') - #themeLayoutDialog.resize(300, 200) self.preview_layout = QtGui.QVBoxLayout(themeLayoutDialog) self.preview_layout.setObjectName('preview_layout') self.preview_area = QtGui.QWidget(themeLayoutDialog) diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index 32ed30303..1f54f984b 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -114,17 +114,19 @@ class ThemesTab(SettingsTab): self.global_group_box.setTitle(translate('OpenLP.ThemesTab', 'Global Theme')) 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_label.setText(translate('OpenLP.ThemesTab', 'Use the theme from each song ' - 'in the database. If a song doesn\'t have a theme associated with ' - 'it, then use the service\'s theme. If the service doesn\'t have ' - 'a theme, then use the global theme.')) + self.song_level_label.setText( + translate('OpenLP.ThemesTab', 'Use the theme from each song in the database. If a song doesn\'t have a ' + 'theme associated with it, then use the service\'s theme. If the service ' + 'doesn\'t have a theme, then use the global theme.')) 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, ' - 'overriding any of the individual songs\' themes. If the ' - 'service doesn\'t have a theme, then use the global theme.')) + self.service_level_label.setText( + translate('OpenLP.ThemesTab', 'Use the theme from the service, overriding any of the individual ' + '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_label.setText(translate('OpenLP.ThemesTab', 'Use the global theme, overriding ' - 'any themes associated with either the service or the songs.')) + self.global_level_label.setText(translate('OpenLP.ThemesTab', 'Use the global theme, overriding any themes ' + 'associated with either the service or the ' + 'songs.')) def load(self): """ diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 746c50d71..a5b5f356a 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -56,7 +56,7 @@ if sys.platform != 'win32' and sys.platform != 'darwin': from openlp.core.common import translate -log = logging.getLogger(__name__+'.__init__') +log = logging.getLogger(__name__ + '.__init__') APPLICATION_VERSION = {} IMAGES_FILTER = None diff --git a/openlp/core/utils/languagemanager.py b/openlp/core/utils/languagemanager.py index cd5ce7add..bb584f7bd 100644 --- a/openlp/core/utils/languagemanager.py +++ b/openlp/core/utils/languagemanager.py @@ -74,7 +74,7 @@ class LanguageManager(object): log.debug('Translation files: %s', 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_". file_names = [file_ for file_ in file_names if not file_.startswith('qt_')] return list(map(trans_dir.filePath, file_names)) diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index cf3b7d0ce..76efadf32 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -207,12 +207,12 @@ class AlertsPlugin(Plugin): """ Called to define all translatable texts of the plugin """ - ## Name PluginList ## + # Name PluginList self.text_strings[StringContent.Name] = { 'singular': translate('AlertsPlugin', 'Alert', 'name singular'), 'plural': translate('AlertsPlugin', 'Alerts', 'name plural') } - ## Name for MediaDockManager, SettingsManager ## + # Name for MediaDockManager, SettingsManager self.text_strings[StringContent.VisibleName] = { 'title': translate('AlertsPlugin', 'Alerts', 'container title') } diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 5a51be163..e7f1fdd56 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -88,8 +88,6 @@ class BiblePlugin(Plugin): self.import_bible_item.setVisible(True) action_list = ActionList.get_instance() 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 self.export_bible_item.setVisible(False) 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.remove_action(self.import_bible_item, UiStrings().Import) self.import_bible_item.setVisible(False) - #action_list.remove_action(self.export_bible_item, UiStrings().Export) self.export_bible_item.setVisible(False) def app_startup(self): @@ -115,19 +112,27 @@ class BiblePlugin(Plugin): if self.manager.old_bible_databases: if QtGui.QMessageBox.information( self.main_window, translate('OpenLP', 'Information'), - translate('OpenLP', 'Bible format has changed.\nYou have to upgrade your existing Bibles.\n' - 'Should OpenLP upgrade now?'), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) == \ + translate('OpenLP', 'Bible format has changed.\nYou have to upgrade your ' + 'existing Bibles.\nShould OpenLP upgrade now?'), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) == \ QtGui.QMessageBox.Yes: self.on_tools_upgrade_Item_triggered() def add_import_menu_item(self, import_menu): + """ + + :param import_menu: + """ self.import_bible_item = create_action(import_menu, 'importBibleItem', text=translate('BiblesPlugin', '&Bible'), visible=False, triggers=self.on_bible_import_click) 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', text=translate('BiblesPlugin', '&Bible'), visible=False) export_menu.addAction(self.export_bible_item) @@ -190,12 +195,12 @@ class BiblePlugin(Plugin): """ Called to define all translatable texts of the plugin """ - ## Name PluginList ## + # Name PluginList self.text_strings[StringContent.Name] = { 'singular': translate('BiblesPlugin', 'Bible', 'name singular'), 'plural': translate('BiblesPlugin', 'Bibles', 'name plural') } - ## Name for MediaDockManager, SettingsManager ## + # Name for MediaDockManager, SettingsManager self.text_strings[StringContent.VisibleName] = { 'title': translate('BiblesPlugin', 'Bibles', 'container title') } diff --git a/openlp/plugins/bibles/forms/bibleupgradeform.py b/openlp/plugins/bibles/forms/bibleupgradeform.py index 9925b1ebc..d9936dfe6 100644 --- a/openlp/plugins/bibles/forms/bibleupgradeform.py +++ b/openlp/plugins/bibles/forms/bibleupgradeform.py @@ -78,7 +78,7 @@ class BibleUpgradeForm(OpenLPWizard): Set up the UI for the bible wizard. """ 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): """ diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index 743bb01c6..c94f6ec8c 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -154,7 +154,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): if 'path' in kwargs: self.path = kwargs['path'] self.wizard = None - Registry().execute('openlp_stop_wizard', self.stop_import) + Registry().register_function('openlp_stop_wizard', self.stop_import) def stop_import(self): """ @@ -191,7 +191,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): :param testament: *Defaults to 1.* The testament_reference_id from 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) self.save_object(book) return book @@ -202,7 +202,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): :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) def delete_book(self, db_book): @@ -211,7 +211,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): :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): return True 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 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. for verse_number, verse_text in text_list.items(): verse = Verse.populate( @@ -267,7 +267,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): """ if not isinstance(value, str): 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) if meta: meta.value = value @@ -281,7 +281,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): :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 + '%')) def get_books(self): @@ -292,17 +292,17 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): log.debug('BibleDB.get_books()') 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. - :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) - return self.get_object_filtered(Book, Book.book_reference_id.like(id)) + log.debug('BibleDB.get_book_by_book_ref_id("%s")' % ref_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): - 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 if 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 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 book_names = BibleStrings().BookNames # escape reserved characters @@ -376,14 +376,14 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): [(u'35', 1, 1, 1), (u'35', 2, 2, 3)] :param show_error: """ - log.debug('BibleDB.get_verses("%s")', reference_list) + log.debug('BibleDB.get_verses("%s")' % reference_list) verse_list = [] book_error = False for book_id, chapter, start_verse, end_verse in reference_list: db_book = self.get_book_by_book_ref_id(book_id) if db_book: 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: end_verse = self.get_verse_count(book_id, chapter) verses = self.session.query(Verse) \ @@ -395,7 +395,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): .all() verse_list.extend(verses) 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 if book_error and show_error: 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 values. """ - log.debug('BibleDB.verse_search("%s")', text) + log.debug('BibleDB.verse_search("%s")' % text) verses = self.session.query(Verse) if text.find(',') > -1: 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. """ - 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( Book.book_reference_id == book.book_reference_id).scalar() if not count: @@ -447,7 +447,7 @@ class BibleDB(QtCore.QObject, Manager, RegistryProperties): :param book_ref_id: The book reference id. :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) \ .filter(Book.book_reference_id == book_ref_id) \ .filter(Verse.chapter == chapter) \ @@ -561,9 +561,9 @@ class BiblesResourcesDB(QtCore.QObject, Manager): Return a book by name or abbreviation. :param name: The name or abbreviation of the book. - :param lower: True if the comparsion 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): name = str(name) if lower: @@ -592,7 +592,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager): :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): name = str(string) books = BiblesResourcesDB.run_sql( @@ -611,17 +611,17 @@ class BiblesResourcesDB(QtCore.QObject, Manager): return None @staticmethod - def get_book_by_id(id): + def get_book_by_id(book_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) - if not isinstance(id, int): - id = int(id) + log.debug('BiblesResourcesDB.get_book_by_id("%s")' % book_id) + if not isinstance(book_id, int): + book_id = int(book_id) 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: return { 'id': books[0][0], @@ -641,7 +641,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager): :param book_ref_id: The id of a book. :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): chapter = int(chapter) 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,)) try: return { - 'id': chapters[chapter-1][0], - 'book_reference_id': chapters[chapter-1][1], - 'chapter': chapters[chapter-1][2], - 'verse_count': chapters[chapter-1][3] + 'id': chapters[chapter - 1][0], + 'book_reference_id': chapters[chapter - 1][1], + 'chapter': chapters[chapter - 1][2], + 'verse_count': chapters[chapter - 1][3] } except (IndexError, TypeError): return None @@ -664,7 +664,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager): :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) if details: return details['chapters'] @@ -678,7 +678,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager): :param book_ref_id: The id of the book. :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) if details: return details['verse_count'] @@ -691,7 +691,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager): :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): source = str(source) source = source.title() @@ -712,7 +712,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager): :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): source = str(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 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): abbreviation = str(abbreviation) if not isinstance(source, str): @@ -765,7 +765,7 @@ class BiblesResourcesDB(QtCore.QObject, Manager): :param name: The name to search the id. :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: books = BiblesResourcesDB.run_sql( '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. """ - log.debug('BiblesResourcesDB.get_language("%s")', name) + log.debug('BiblesResourcesDB.get_language("%s")' % name) if not isinstance(name, str): name = str(name) language = BiblesResourcesDB.run_sql( @@ -846,13 +846,13 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager): file_path = os.path.join( AppLocation.get_directory(AppLocation.DataDir), 'bibles', 'alternative_book_names.sqlite') 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.execute( 'CREATE TABLE alternative_book_names(id INTEGER NOT NULL, ' 'book_reference_id INTEGER, language_id INTEGER, name VARCHAR(50), PRIMARY KEY (id))') else: - #use existing DB + # use existing DB AlternativeBookNamesDB.conn = sqlite3.connect(file_path) AlternativeBookNamesDB.cursor = AlternativeBookNamesDB.conn.cursor() return AlternativeBookNamesDB.cursor @@ -880,7 +880,7 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager): :param name: The name to search the id. :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: books = AlternativeBookNamesDB.run_sql( '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 language_id: The language to which the alternative book name belong. """ - log.debug('AlternativeBookNamesDB.create_alternative_book_name("%s", "%s", "%s")', - name, book_reference_id, language_id) + log.debug('AlternativeBookNamesDB.create_alternative_book_name("%s", "%s", "%s")' % + (name, book_reference_id, language_id)) return AlternativeBookNamesDB.run_sql( 'INSERT INTO alternative_book_names(book_reference_id, language_id, name) ' 'VALUES (?, ?, ?)', (book_reference_id, language_id, name), True) diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 340d8ef92..b15e11738 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -552,10 +552,10 @@ class HTTPBible(BibleDB, RegistryProperties): self.application.set_busy_cursor() search_results = self.get_chapter(book, reference[1]) if search_results and search_results.has_verse_list(): - ## We have found a book of the bible lets check to see - ## if it was there. By reusing the returned book name - ## we get a correct book. For example it is possible - ## to request ac and get Acts back. + # We have found a book of the bible lets check to see + # if it was there. By reusing the returned book name + # we get a correct book. For example it is possible + # to request ac and get Acts back. book_name = search_results.book self.application.process_events() # Check to see if book/chapter exists. diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 10fef8e31..a2cb1b594 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -480,6 +480,10 @@ class BibleMediaItem(MediaManagerItem): self.reload_bibles() def on_delete_click(self): + """ + When the delete button is pressed + """ + bible = None if self.quickTab.isVisible(): bible = self.quickVersionComboBox.currentText() elif self.advancedTab.isVisible(): @@ -488,8 +492,9 @@ class BibleMediaItem(MediaManagerItem): if QtGui.QMessageBox.question( self, UiStrings().ConfirmDelete, 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, - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), + 'OpenLP?\n\nYou will need to re-import this Bible to use it ' + 'again.') % bible, + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: return 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.') break bible_text = '%s %d%s%d (%s, %s)' % (book, verse.chapter, verse_separator, verse.verse, version, - second_version) + second_version) else: bible_text = '%s %d%s%d (%s)' % (book, verse.chapter, verse_separator, verse.verse, version) bible_verse = QtGui.QListWidgetItem(bible_text) @@ -840,6 +845,7 @@ class BibleMediaItem(MediaManagerItem): service_item.add_capability(ItemCapabilities.CanPreview) service_item.add_capability(ItemCapabilities.CanLoop) service_item.add_capability(ItemCapabilities.CanWordSplit) + service_item.add_capability(ItemCapabilities.CanEditTitle) # Service Item: Title service_item.title = create_separated_list(raw_title) # Service Item: Theme diff --git a/openlp/plugins/bibles/lib/versereferencelist.py b/openlp/plugins/bibles/lib/versereferencelist.py index 1d3877d1d..7cbba68fb 100644 --- a/openlp/plugins/bibles/lib/versereferencelist.py +++ b/openlp/plugins/bibles/lib/versereferencelist.py @@ -94,5 +94,5 @@ class VerseReferenceList(object): result = result + ', ' + version['permission'] result = result.rstrip() if result.endswith(','): - return result[:len(result)-1] + return result[:len(result) - 1] return result diff --git a/openlp/plugins/custom/customplugin.py b/openlp/plugins/custom/customplugin.py index eb7de530a..2065717cb 100644 --- a/openlp/plugins/custom/customplugin.py +++ b/openlp/plugins/custom/customplugin.py @@ -43,7 +43,7 @@ log = logging.getLogger(__name__) __default_settings__ = { 'custom/db type': 'sqlite', - 'custom/last search type': CustomSearch.Titles, + 'custom/last search type': CustomSearch.Titles, 'custom/display footer': True, 'custom/add custom from service': True } @@ -97,12 +97,12 @@ class CustomPlugin(Plugin): """ Called to define all translatable texts of the plugin """ - ## Name PluginList ## + # Name PluginList self.text_strings[StringContent.Name] = { 'singular': translate('CustomPlugin', 'Custom Slide', 'name singular'), 'plural': translate('CustomPlugin', 'Custom Slides', 'name plural') } - ## Name for MediaDockManager, SettingsManager ## + # Name for MediaDockManager, SettingsManager self.text_strings[StringContent.VisibleName] = { 'title': translate('CustomPlugin', 'Custom Slides', 'container title') } diff --git a/openlp/plugins/custom/forms/editcustomslideform.py b/openlp/plugins/custom/forms/editcustomslideform.py index afce4887b..e6834dafb 100644 --- a/openlp/plugins/custom/forms/editcustomslideform.py +++ b/openlp/plugins/custom/forms/editcustomslideform.py @@ -1,4 +1,3 @@ -#lint:disable # -*- coding: utf-8 -*- # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 diff --git a/openlp/plugins/custom/lib/customxmlhandler.py b/openlp/plugins/custom/lib/customxmlhandler.py index ca42a705b..3e1880055 100644 --- a/openlp/plugins/custom/lib/customxmlhandler.py +++ b/openlp/plugins/custom/lib/customxmlhandler.py @@ -51,7 +51,7 @@ from lxml import etree, objectify 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): """ This class builds the XML used to describe songs. diff --git a/openlp/plugins/images/imageplugin.py b/openlp/plugins/images/imageplugin.py index 693449530..08c31f53c 100644 --- a/openlp/plugins/images/imageplugin.py +++ b/openlp/plugins/images/imageplugin.py @@ -95,12 +95,12 @@ class ImagePlugin(Plugin): """ Called to define all translatable texts of the plugin. """ - ## Name PluginList ## + # Name PluginList self.text_strings[StringContent.Name] = { 'singular': translate('ImagePlugin', 'Image', 'name singular'), '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')} # Middle Header Bar tooltips = { diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index b2eb5b816..d24a18434 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -550,6 +550,7 @@ class ImageMediaItem(MediaManagerItem): service_item.add_capability(ItemCapabilities.CanPreview) service_item.add_capability(ItemCapabilities.CanLoop) service_item.add_capability(ItemCapabilities.CanAppend) + service_item.add_capability(ItemCapabilities.CanEditTitle) # force a nonexistent theme service_item.theme = -1 missing_items_file_names = [] diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 56d3a49f4..87d8e3311 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -95,7 +95,6 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties): self.reset_action.setToolTip(UiStrings().ResetLiveBG) self.automatic = UiStrings().Automatic self.display_type_label.setText(translate('MediaPlugin.MediaItem', 'Use Player:')) - #self.rebuild_players() def required_icons(self): """ @@ -141,7 +140,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties): if index == 0: set_media_players(player) else: - set_media_players(player, player[index-1]) + set_media_players(player, player[index - 1]) def on_reset_click(self): """ @@ -216,6 +215,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties): if not self.media_controller.media_length(service_item): return False service_item.add_capability(ItemCapabilities.CanAutoStartForLive) + service_item.add_capability(ItemCapabilities.CanEditTitle) service_item.add_capability(ItemCapabilities.RequiresMedia) if Settings().value(self.settings_section + '/media auto start') == QtCore.Qt.Checked: service_item.will_auto_start = True diff --git a/openlp/plugins/media/mediaplugin.py b/openlp/plugins/media/mediaplugin.py index 6cf241d1d..d0e082f53 100644 --- a/openlp/plugins/media/mediaplugin.py +++ b/openlp/plugins/media/mediaplugin.py @@ -73,12 +73,12 @@ class MediaPlugin(Plugin): """ Called to define all translatable texts of the plugin """ - ## Name PluginList ## + # Name PluginList self.text_strings[StringContent.Name] = { 'singular': translate('MediaPlugin', 'Media', 'name singular'), 'plural': translate('MediaPlugin', 'Media', 'name plural') } - ## Name for MediaDockManager, SettingsManager ## + # Name for MediaDockManager, SettingsManager self.text_strings[StringContent.VisibleName] = { 'title': translate('MediaPlugin', 'Media', 'container title') } diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index c55873c5f..584c1401f 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -377,8 +377,6 @@ class ImpressDocument(PresentationDocument): Stop the presentation, remove from screen. """ log.debug('stop presentation OpenOffice') - # deactivate should hide the screen according to docs, but doesn't - #self.control.deactivate() self.presentation.end() self.control = None diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 1894cbf1f..5b503d50f 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -263,6 +263,7 @@ class PresentationMediaItem(MediaManagerItem): file_type = os.path.splitext(filename)[1][1:] if not self.display_type_combo_box.currentText(): return False + service_item.add_capability(ItemCapabilities.CanEditTitle) if (file_type == 'pdf' or file_type == 'xps') and context != ServiceItemContext.Service: service_item.add_capability(ItemCapabilities.CanMaintain) service_item.add_capability(ItemCapabilities.CanPreview) diff --git a/openlp/plugins/presentations/lib/pdfcontroller.py b/openlp/plugins/presentations/lib/pdfcontroller.py index 597b7d78b..1365e59a9 100644 --- a/openlp/plugins/presentations/lib/pdfcontroller.py +++ b/openlp/plugins/presentations/lib/pdfcontroller.py @@ -74,7 +74,7 @@ class PdfController(PresentationController): runlog = '' log.debug('testing program_path: %s', program_path) try: - runlog = check_output([program_path, '--help'], stderr=STDOUT) + runlog = check_output([program_path, '--help'], stderr=STDOUT) except CalledProcessError as e: runlog = e.output except Exception: @@ -183,7 +183,7 @@ class PdfDocument(PresentationDocument): self.image_files = [] self.num_pages = -1 - def gs_get_resolution(self, size): + def gs_get_resolution(self, size): """ Only used when using ghostscript 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')): created_files = sorted(os.listdir(self.get_temp_folder())) 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.num_pages = len(self.image_files) return True diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index d6447adce..09fdf2fcc 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -247,7 +247,7 @@ class PowerpointDocument(PresentationDocument): Starts a presentation from the beginning. """ log.debug('start_presentation') - #SlideShowWindow measures its size/position by points, not pixels + # SlideShowWindow measures its size/position by points, not pixels try: dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88) except win32ui.error: diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index 16008f7e9..a9090dd1e 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -87,7 +87,7 @@ class PptviewController(PresentationController): return log.debug('start PPTView') dll_path = os.path.join(AppLocation.get_directory(AppLocation.AppDir), - 'presentations', 'lib', 'pptviewlib', 'pptviewlib.dll') + 'plugins', 'presentations', 'lib', 'pptviewlib', 'pptviewlib.dll') self.process = cdll.LoadLibrary(dll_path) if log.isEnabledFor(logging.DEBUG): self.process.SetDebug(1) diff --git a/openlp/plugins/presentations/lib/presentationtab.py b/openlp/plugins/presentations/lib/presentationtab.py index 7d5c81366..590289014 100644 --- a/openlp/plugins/presentations/lib/presentationtab.py +++ b/openlp/plugins/presentations/lib/presentationtab.py @@ -175,10 +175,10 @@ class PresentationTab(SettingsTab): if pdf_program == '': enable_pdf_program = 0 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 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 if changed: self.settings_form.register_post_process('mediaitem_suffix_reset') diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index de0a0c5a5..5e0d7395d 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -156,12 +156,12 @@ class PresentationPlugin(Plugin): """ Called to define all translatable texts of the plugin. """ - ## Name PluginList ## + # Name PluginList self.text_strings[StringContent.Name] = { 'singular': translate('PresentationPlugin', 'Presentation', 'name singular'), 'plural': translate('PresentationPlugin', 'Presentations', 'name plural') } - ## Name for MediaDockManager, SettingsManager ## + # Name for MediaDockManager, SettingsManager self.text_strings[StringContent.VisibleName] = { 'title': translate('PresentationPlugin', 'Presentations', 'container title') } diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py index fa578184b..22d0349f8 100644 --- a/openlp/plugins/remotes/lib/httpserver.py +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -28,15 +28,15 @@ ############################################################################### """ -The :mod:`http` module contains the API web server. This is a lightweight web -server used by remotes to interact with OpenLP. It uses JSON to communicate with -the remotes. +The :mod:`http` module contains the API web server. This is a lightweight web server used by remotes to interact +with OpenLP. It uses JSON to communicate with the remotes. """ import ssl import socket import os import logging +import time from PyQt4 import QtCore @@ -53,8 +53,8 @@ log = logging.getLogger(__name__) class CustomHandler(BaseHTTPRequestHandler, HttpRouter): """ Stateless session handler to handle the HTTP request and process it. - This class handles just the overrides to the base methods and the logic to invoke the - methods within the HttpRouter class. + This class handles just the overrides to the base methods and the logic to invoke the methods within the HttpRouter + class. DO not try change the structure as this is as per the documentation. """ @@ -116,9 +116,20 @@ class OpenLPServer(): log.debug('Started ssl httpd...') else: port = Settings().value(self.settings_section + '/port') - self.httpd = ThreadingHTTPServer((address, port), CustomHandler) + loop = 1 + while loop < 3: + try: + self.httpd = ThreadingHTTPServer((address, port), CustomHandler) + except OSError: + loop += 1 + time.sleep(0.1) + except: + log.error('Failed to start server ') log.debug('Started non ssl httpd...') - self.httpd.serve_forever() + if hasattr(self, 'httpd') and self.httpd: + self.httpd.serve_forever() + else: + log.debug('Failed to start server') def stop_server(self): """ diff --git a/openlp/plugins/remotes/remoteplugin.py b/openlp/plugins/remotes/remoteplugin.py index 393f08dd9..d3dc6e58a 100644 --- a/openlp/plugins/remotes/remoteplugin.py +++ b/openlp/plugins/remotes/remoteplugin.py @@ -92,12 +92,12 @@ class RemotesPlugin(Plugin): """ Called to define all translatable texts of the plugin """ - ## Name PluginList ## + # Name PluginList self.text_strings[StringContent.Name] = { 'singular': translate('RemotePlugin', 'Remote', 'name singular'), 'plural': translate('RemotePlugin', 'Remotes', 'name plural') } - ## Name for MediaDockManager, SettingsManager ## + # Name for MediaDockManager, SettingsManager self.text_strings[StringContent.VisibleName] = { 'title': translate('RemotePlugin', 'Remote', 'container title') } diff --git a/openlp/plugins/songs/forms/duplicatesongremovalform.py b/openlp/plugins/songs/forms/duplicatesongremovalform.py index 22299cde5..d85197223 100644 --- a/openlp/plugins/songs/forms/duplicatesongremovalform.py +++ b/openlp/plugins/songs/forms/duplicatesongremovalform.py @@ -114,7 +114,7 @@ class DuplicateSongRemovalForm(OpenLPWizard, RegistryProperties): self.review_layout.addWidget(self.review_scroll_area) 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 - #review page. + # review page. self.dummy_page = QtGui.QWizardPage() self.dummy_page_id = self.addPage(self.dummy_page) @@ -217,12 +217,12 @@ class DuplicateSongRemovalForm(OpenLPWizard, RegistryProperties): duplicate_added = False 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. - 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_found = True duplicate_added = True 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_found = True duplicate_added = True diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index b655c0f73..60c6eae78 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -675,14 +675,13 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog, RegistryProperties): separator = parts.find(':') if separator >= 0: verse_name = parts[0:separator].strip() - verse_num = parts[separator+1:].strip() + verse_num = parts[separator + 1:].strip() else: verse_name = parts verse_num = '1' verse_index = VerseType.from_loose_input(verse_name) verse_tag = VerseType.tags[verse_index] # Later we need to handle v1a as well. - #regex = re.compile(r'(\d+\w.)') regex = re.compile(r'\D*(\d+)\D*') match = regex.match(verse_num) if match: diff --git a/openlp/plugins/songs/forms/editverseform.py b/openlp/plugins/songs/forms/editverseform.py index 038cff539..79a69a015 100644 --- a/openlp/plugins/songs/forms/editverseform.py +++ b/openlp/plugins/songs/forms/editverseform.py @@ -75,7 +75,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): text = self.verse_text_edit.toPlainText() position = self.verse_text_edit.textCursor().position() insert_string = '[---]' - if position and text[position-1] != '\n': + if position and text[position - 1] != '\n': insert_string = '\n' + insert_string if position == len(text) or text[position] != '\n': insert_string += '\n' diff --git a/openlp/plugins/songs/forms/mediafilesdialog.py b/openlp/plugins/songs/forms/mediafilesdialog.py index a0392e3db..3a1db39ed 100644 --- a/openlp/plugins/songs/forms/mediafilesdialog.py +++ b/openlp/plugins/songs/forms/mediafilesdialog.py @@ -66,8 +66,10 @@ class Ui_MediaFilesDialog(object): def retranslateUi(self, media_files_dialog): """ Translate the UI on the fly. + + :param media_files_dialog: """ media_files_dialog.setWindowTitle(translate('SongsPlugin.MediaFilesForm', 'Select Media File(s)')) - self.select_label.setText(translate('SongsPlugin.MediaFilesForm', - 'Select one or more audio files from the list below, and click OK to import them ' - 'into this song.')) + self.select_label.setText(translate('SongsPlugin.MediaFilesForm', 'Select one or more audio files from the ' + 'list below, and click OK to import them ' + 'into this song.')) diff --git a/openlp/plugins/songs/forms/songexportform.py b/openlp/plugins/songs/forms/songexportform.py index 4e345b750..589da4d33 100644 --- a/openlp/plugins/songs/forms/songexportform.py +++ b/openlp/plugins/songs/forms/songexportform.py @@ -152,9 +152,9 @@ class SongExportForm(OpenLPWizard): self.setWindowTitle(translate('SongsPlugin.ExportWizardForm', 'Song Export Wizard')) self.title_label.setText(WizardStrings.HeaderStyle % translate('OpenLP.Ui', 'Welcome to the Song Export Wizard')) - self.information_label.setText(translate('SongsPlugin.ExportWizardForm', 'This wizard will help to' - ' export your songs to the open and free OpenLyrics worship ' - 'song format.')) + self.information_label.setText( + translate('SongsPlugin.ExportWizardForm', 'This wizard will help to export your songs to the open and free ' + 'OpenLyrics worship song format.')) self.available_songs_page.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Songs')) self.available_songs_page.setSubTitle(translate('SongsPlugin.ExportWizardForm', 'Check the songs you want to export.')) diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index 0866a1cc7..5c1fbdcb2 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -270,13 +270,13 @@ class CCLIFileImport(SongImport): verse_text = '' verse_start = False else: - #line_number=0, song title + # line_number=0, song title if line_number == 0: self.title = clean_line line_number += 1 - #line_number=1, verses + # line_number=1, verses 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'): line_number += 1 ccli_parts = clean_line.split(' ') @@ -319,21 +319,21 @@ class CCLIFileImport(SongImport): # last part. Add l so as to keep the CRLF verse_text = verse_text + line else: - #line_number=2, copyright + # line_number=2, copyright if line_number == 2: line_number += 1 if clean_line.startswith('©'): self.copyright = clean_line else: song_author = clean_line - #n=3, authors + # n=3, authors elif line_number == 3: line_number += 1 if song_author: self.copyright = clean_line else: 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'): self.comments += clean_line # split on known separators diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index cde0b1692..ca201279a 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -305,7 +305,7 @@ class EasyWorshipSongImport(SongImport): elif field_desc.field_type == FieldType.Logical: return field ^ 0x80 == 1 elif field_desc.field_type == FieldType.Memo or field_desc.field_type == FieldType.Blob: - block_start, blob_size = struct.unpack_from('= 0) diff --git a/tests/functional/openlp_core_ui/test_formattingtagscontroller.py b/tests/functional/openlp_core_ui/test_formattingtagscontroller.py index b09b095be..1d8512940 100644 --- a/tests/functional/openlp_core_ui/test_formattingtagscontroller.py +++ b/tests/functional/openlp_core_ui/test_formattingtagscontroller.py @@ -72,9 +72,10 @@ class TestFormattingTagController(TestCase): # THEN: The result should match the predetermined value. self.assertTrue(result == test['gen'], - 'Function should handle end tag correctly : %s and %s for %s ' % (test['gen'], result, test['start'])) - self.assertTrue(error == test['valid'], - 'Function should not generate unexpected error messages : %s ' % error) + 'Function should handle end tag correctly : %s and %s for %s ' % + (test['gen'], result, test['start'])) + self.assertTrue(error == test['valid'], 'Function should not generate unexpected error messages : %s ' % + error) def test_start_tag_changed_processes_correctly(self): """ @@ -94,10 +95,10 @@ class TestFormattingTagController(TestCase): error, result = self.services.start_tag_changed(test['start'], test['end']) # THEN: The result should match the predetermined value. - self.assertTrue(result == test['gen'], - 'Function should handle end tag correctly : %s and %s ' % (test['gen'], result)) - self.assertTrue(error == test['valid'], - 'Function should not generate unexpected error messages : %s ' % error) + self.assertTrue(result == test['gen'], 'Function should handle end tag correctly : %s and %s ' % + (test['gen'], result)) + self.assertTrue(error == test['valid'], 'Function should not generate unexpected error messages : %s ' % + error) def test_start_html_to_end_html(self): """ @@ -112,5 +113,5 @@ class TestFormattingTagController(TestCase): result = self.services.start_html_to_end_html(test1) # THEN: The result should match the predetermined value. - self.assertTrue(result == test2, 'Calculated end tag should be valid: %s and %s = %s' - % (test1, test2, result)) \ No newline at end of file + self.assertTrue(result == test2, 'Calculated end tag should be valid: %s and %s = %s' % + (test1, test2, result)) diff --git a/tests/functional/openlp_core_ui/test_formattingtagsform.py b/tests/functional/openlp_core_ui/test_formattingtagsform.py index f9a9621aa..05b5fed74 100644 --- a/tests/functional/openlp_core_ui/test_formattingtagsform.py +++ b/tests/functional/openlp_core_ui/test_formattingtagsform.py @@ -74,4 +74,3 @@ class TestFormattingTagForm(TestCase): # THEN: setEnabled and setDefault should have been called on save_push_button #form.save_button.setEnabled.assert_called_with(True) - diff --git a/tests/functional/openlp_core_ui/test_mainwindow.py b/tests/functional/openlp_core_ui/test_mainwindow.py new file mode 100644 index 000000000..0b17828b9 --- /dev/null +++ b/tests/functional/openlp_core_ui/test_mainwindow.py @@ -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' diff --git a/tests/functional/openlp_core_ui/test_servicemanager.py b/tests/functional/openlp_core_ui/test_servicemanager.py index 3de560786..260f88b6b 100644 --- a/tests/functional/openlp_core_ui/test_servicemanager.py +++ b/tests/functional/openlp_core_ui/test_servicemanager.py @@ -74,4 +74,4 @@ class TestServiceManager(TestCase): # THEN: The the controller should be registered in the registry. self.assertNotEqual(service, None, 'The base service should be created') self.assertEqual(service['openlp_core']['service-theme'], 'test_theme', 'The test theme should be saved') - self.assertEqual(service['openlp_core']['lite-service'], False, 'The lite service should be saved') \ No newline at end of file + self.assertEqual(service['openlp_core']['lite-service'], False, 'The lite service should be saved') diff --git a/tests/functional/openlp_core_utils/__init__.py b/tests/functional/openlp_core_utils/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/functional/openlp_core_utils/__init__.py +++ b/tests/functional/openlp_core_utils/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/functional/openlp_core_utils/test_actions.py b/tests/functional/openlp_core_utils/test_actions.py index 092c96ac1..2868f8555 100644 --- a/tests/functional/openlp_core_utils/test_actions.py +++ b/tests/functional/openlp_core_utils/test_actions.py @@ -149,5 +149,3 @@ class TestActionList(TestCase, TestMixin): # THEN: Both action should keep their shortcuts. assert len(action3.shortcuts()) == 2, 'The action should have two shortcut assigned.' assert len(action_with_same_shortcuts3.shortcuts()) == 2, 'The action should have two shortcuts assigned.' - - diff --git a/tests/functional/openlp_core_utils/test_utils.py b/tests/functional/openlp_core_utils/test_utils.py index d6405d77b..a97d757ea 100644 --- a/tests/functional/openlp_core_utils/test_utils.py +++ b/tests/functional/openlp_core_utils/test_utils.py @@ -107,7 +107,7 @@ class TestUtils(TestCase): """ # GIVEN: sys.getfilesystemencoding returns "cp1252" with patch('openlp.core.utils.sys.getfilesystemencoding') as mocked_getfilesystemencoding, \ - patch('openlp.core.utils.sys.getdefaultencoding') as mocked_getdefaultencoding: + patch('openlp.core.utils.sys.getdefaultencoding') as mocked_getdefaultencoding: mocked_getfilesystemencoding.return_value = 'cp1252' # WHEN: get_filesystem_encoding() is called @@ -124,7 +124,7 @@ class TestUtils(TestCase): """ # GIVEN: sys.getfilesystemencoding returns None and sys.getdefaultencoding returns "utf-8" with patch('openlp.core.utils.sys.getfilesystemencoding') as mocked_getfilesystemencoding, \ - patch('openlp.core.utils.sys.getdefaultencoding') as mocked_getdefaultencoding: + patch('openlp.core.utils.sys.getdefaultencoding') as mocked_getdefaultencoding: mocked_getfilesystemencoding.return_value = None mocked_getdefaultencoding.return_value = 'utf-8' @@ -175,7 +175,7 @@ class TestUtils(TestCase): # THEN: A tuple should be returned. self.assertEqual(wanted_result, result, - 'A two-entry tuple with the directory and file name (empty) should have been returned.') + 'A two-entry tuple with the directory and file name (empty) should have been returned.') def clean_filename_test(self): """ @@ -206,7 +206,7 @@ class TestUtils(TestCase): # THEN: We get a properly sorted list self.assertEqual(['Aushang', '\u00C4u\u00DFerung', 'Auszug'], sorted_list, - 'Strings should be sorted properly') + 'Strings should be sorted properly') def get_natural_key_test(self): """ diff --git a/tests/functional/openlp_plugins/bibles/__init__.py b/tests/functional/openlp_plugins/bibles/__init__.py index 4c8c00fec..6b241e7fc 100644 --- a/tests/functional/openlp_plugins/bibles/__init__.py +++ b/tests/functional/openlp_plugins/bibles/__init__.py @@ -26,4 +26,3 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### - diff --git a/tests/functional/openlp_plugins/bibles/test_http.py b/tests/functional/openlp_plugins/bibles/test_http.py index 9a1be8d0e..b9bb8f11c 100644 --- a/tests/functional/openlp_plugins/bibles/test_http.py +++ b/tests/functional/openlp_plugins/bibles/test_http.py @@ -116,7 +116,8 @@ class TestBSExtract(TestCase): self.mock_get_soup_for_bible_ref.assert_called_once_with( 'http://m.bibleserver.com/overlay/selectBook?translation=NIV') self.assertIsNone(result, - 'BSExtract.get_books_from_http should return None when get_soup_for_bible_ref returns a false value') + 'BSExtract.get_books_from_http should return None when get_soup_for_bible_ref returns a ' + 'false value') def get_books_from_http_no_content_test(self): """ @@ -146,7 +147,8 @@ class TestBSExtract(TestCase): self.mock_log.error.assert_called_once_with('No books found in the Bibleserver response.') self.mock_send_error_message.assert_called_once_with('parse') self.assertIsNone(result, - 'BSExtract.get_books_from_http should return None when get_soup_for_bible_ref returns a false value') + 'BSExtract.get_books_from_http should return None when get_soup_for_bible_ref returns a ' + 'false value') def get_books_from_http_content_test(self): """ diff --git a/tests/functional/openlp_plugins/bibles/test_lib.py b/tests/functional/openlp_plugins/bibles/test_lib.py index 9b3e79591..0c8bb8211 100644 --- a/tests/functional/openlp_plugins/bibles/test_lib.py +++ b/tests/functional/openlp_plugins/bibles/test_lib.py @@ -85,5 +85,3 @@ class TestLib(TestCase): # THEN: It should be False self.assertFalse(has_verse_list, 'The SearchResults object should have a verse list') - - diff --git a/tests/functional/openlp_plugins/images/__init__.py b/tests/functional/openlp_plugins/images/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/functional/openlp_plugins/images/__init__.py +++ b/tests/functional/openlp_plugins/images/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/functional/openlp_plugins/images/test_lib.py b/tests/functional/openlp_plugins/images/test_lib.py index 80d452644..202b5a42b 100644 --- a/tests/functional/openlp_plugins/images/test_lib.py +++ b/tests/functional/openlp_plugins/images/test_lib.py @@ -108,7 +108,7 @@ class TestImageMediaItem(TestCase): Test that the save_new_images_list() saves all images in the list """ # GIVEN: A list with 3 images - image_list = [ 'test_image_1.jpg', 'test_image_2.jpg', 'test_image_3.jpg' ] + image_list = ['test_image_1.jpg', 'test_image_2.jpg', 'test_image_3.jpg'] with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') as mocked_load_full_list: self.media_item.manager = MagicMock() @@ -124,7 +124,7 @@ class TestImageMediaItem(TestCase): Test that the save_new_images_list() ignores everything in the provided list except strings """ # GIVEN: A list with images and objects - image_list = [ 'test_image_1.jpg', None, True, ImageFilenames(), 'test_image_2.jpg' ] + image_list = ['test_image_1.jpg', None, True, ImageFilenames(), 'test_image_2.jpg'] with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') as mocked_load_full_list: self.media_item.manager = MagicMock() @@ -171,7 +171,7 @@ class TestImageMediaItem(TestCase): assert self.media_item.manager.delete_object.call_count == 7, \ 'manager.delete_object() should be called exactly 7 times' - # CLEANUP: Remove added attribute from ImageFilenames and ImageGroups + # CLEANUP: Remove added attribute from Image Filenames and ImageGroups delattr(ImageFilenames, 'group_id') delattr(ImageGroups, 'parent_id') diff --git a/tests/functional/openlp_plugins/presentations/__init__.py b/tests/functional/openlp_plugins/presentations/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/functional/openlp_plugins/presentations/__init__.py +++ b/tests/functional/openlp_plugins/presentations/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py index 65c7bf916..277e83a5b 100644 --- a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py @@ -33,6 +33,7 @@ import os import shutil from unittest import TestCase, SkipTest from tempfile import mkdtemp +from PyQt4 import QtCore, QtGui from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument from tests.functional import MagicMock @@ -45,6 +46,12 @@ __default_settings__ = { 'presentations/enable_pdf_program': False } +SCREEN = { + 'primary': False, + 'number': 1, + 'size': QtCore.QRect(0, 0, 1024, 768) +} + class TestPdfController(TestCase, TestMixin): """ @@ -56,7 +63,12 @@ class TestPdfController(TestCase, TestMixin): """ self.get_application() self.build_settings() - ScreenList.create(self.app.desktop()) + # Mocked out desktop object + self.desktop = MagicMock() + self.desktop.primaryScreen.return_value = SCREEN['primary'] + self.desktop.screenCount.return_value = SCREEN['number'] + self.desktop.screenGeometry.return_value = SCREEN['size'] + self.screens = ScreenList.create(self.desktop) Settings().extend_default_settings(__default_settings__) self.temp_folder = mkdtemp() self.thumbnail_folder = mkdtemp() @@ -67,12 +79,10 @@ class TestPdfController(TestCase, TestMixin): """ Delete all the C++ objects at the end so that we don't have a segfault """ - try: - self.destroy_settings() - shutil.rmtree(self.thumbnail_folder) - shutil.rmtree(self.temp_folder) - except OSError: - pass + del self.screens + self.destroy_settings() + shutil.rmtree(self.thumbnail_folder) + shutil.rmtree(self.temp_folder) def constructor_test(self): """ @@ -106,3 +116,30 @@ class TestPdfController(TestCase, TestMixin): # THEN: The load should succeed and we should be able to get a pagecount self.assertTrue(loaded, 'The loading of the PDF should succeed.') self.assertEqual(3, document.get_slide_count(), 'The pagecount of the PDF should be 3.') + + def load_pdf_pictures_test(self): + """ + Test loading of a Pdf and check size of generate pictures + """ + # GIVEN: A Pdf-file + test_file = os.path.join(TEST_RESOURCES_PATH, 'presentations', 'pdf_test1.pdf') + + # WHEN: The Pdf is loaded + controller = PdfController(plugin=self.mock_plugin) + if not controller.check_available(): + raise SkipTest('Could not detect mudraw or ghostscript, so skipping PDF test') + controller.temp_folder = self.temp_folder + controller.thumbnail_folder = self.thumbnail_folder + document = PdfDocument(controller, test_file) + loaded = document.load_presentation() + + # THEN: The load should succeed and pictures should be created and have been scales to fit the screen + self.assertTrue(loaded, 'The loading of the PDF should succeed.') + image = QtGui.QImage(os.path.join(self.temp_folder, 'pdf_test1.pdf', 'mainslide001.png')) + # Based on the converter used the resolution will differ a bit + if controller.gsbin: + self.assertEqual(760, image.height(), 'The height should be 760') + self.assertEqual(537, image.width(), 'The width should be 537') + else: + self.assertEqual(767, image.height(), 'The height should be 767') + self.assertEqual(543, image.width(), 'The width should be 543') diff --git a/tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py b/tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py index 1b43615f3..8a8897cec 100644 --- a/tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_pptviewcontroller.py @@ -80,7 +80,8 @@ class TestPptviewController(TestCase, TestMixin): controller = PptviewController(plugin=self.mock_plugin) # THEN: The name of the presentation controller should be correct - self.assertEqual('Powerpoint Viewer', controller.name, 'The name of the presentation controller should be correct') + self.assertEqual('Powerpoint Viewer', controller.name, + 'The name of the presentation controller should be correct') def check_available_test(self): """ @@ -98,9 +99,9 @@ class TestPptviewController(TestCase, TestMixin): # THEN: On windows it should return True, on other platforms False if os.name == 'nt': - self.assertTrue(available, 'check_available should return True on windows.') + self.assertTrue(available, 'check_available should return True on windows.') else: - self.assertFalse(available, 'check_available should return False when not on windows.') + self.assertFalse(available, 'check_available should return False when not on windows.') class TestPptviewDocument(TestCase): diff --git a/tests/functional/openlp_plugins/remotes/__init__.py b/tests/functional/openlp_plugins/remotes/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/functional/openlp_plugins/remotes/__init__.py +++ b/tests/functional/openlp_plugins/remotes/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/functional/openlp_plugins/remotes/test_router.py b/tests/functional/openlp_plugins/remotes/test_router.py index 774ce5fcd..9e13a448b 100644 --- a/tests/functional/openlp_plugins/remotes/test_router.py +++ b/tests/functional/openlp_plugins/remotes/test_router.py @@ -111,7 +111,8 @@ class TestRouter(TestCase, TestMixin): Test the get_content_type logic """ # GIVEN: a set of files and their corresponding types - headers = [ ['test.html', 'text/html'], ['test.css', 'text/css'], + headers = [ + ['test.html', 'text/html'], ['test.css', 'text/css'], ['test.js', 'application/javascript'], ['test.jpg', 'image/jpeg'], ['test.gif', 'image/gif'], ['test.ico', 'image/x-icon'], ['test.png', 'image/png'], ['test.whatever', 'text/plain'], @@ -142,7 +143,7 @@ class TestRouter(TestCase, TestMixin): # THEN: it should return a 404 self.router.send_response.assert_called_once_with(404) - self.router.send_header.assert_called_once_with('Content-type','text/html') + self.router.send_header.assert_called_once_with('Content-type', 'text/html') self.assertEqual(self.router.end_headers.call_count, 1, 'end_headers called once') def serve_file_with_valid_params_test(self): diff --git a/tests/functional/openlp_plugins/songs/test_ewimport.py b/tests/functional/openlp_plugins/songs/test_ewimport.py index f98ba57d2..9e327517c 100644 --- a/tests/functional/openlp_plugins/songs/test_ewimport.py +++ b/tests/functional/openlp_plugins/songs/test_ewimport.py @@ -41,33 +41,33 @@ TEST_PATH = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'easyworshipsongs')) SONG_TEST_DATA = [ {'title': 'Amazing Grace', - 'authors': ['John Newton'], - 'copyright': 'Public Domain', - 'ccli_number': 0, - 'verses': - [('Amazing grace how sweet the sound,\nThat saved a wretch like me;\n' - 'I once was lost, but now am found\nWas blind, but now I see.', 'v1'), - ('T\'was grace that taught my heart to fear,\nAnd grace my fears relieved;\n' - 'How precious did that grace appear\nThe hour I first believed.', 'v2'), - ('Through many dangers, toil and snares,\nI have already come;\n' - '\'Tis grace has brought me safe thus far,\nAnd grace will lead me home.', 'v3'), - ('When we\'ve been there ten thousand years\nBright shining as the sun,\n' - 'We\'ve no less days to sing God\'s praise\nThan when we\'ve first begun.', 'v4')], - 'verse_order_list': []}, + 'authors': ['John Newton'], + 'copyright': 'Public Domain', + 'ccli_number': 0, + 'verses': + [('Amazing grace how sweet the sound,\nThat saved a wretch like me;\n' + 'I once was lost, but now am found\nWas blind, but now I see.', 'v1'), + ('T\'was grace that taught my heart to fear,\nAnd grace my fears relieved;\n' + 'How precious did that grace appear\nThe hour I first believed.', 'v2'), + ('Through many dangers, toil and snares,\nI have already come;\n' + '\'Tis grace has brought me safe thus far,\nAnd grace will lead me home.', 'v3'), + ('When we\'ve been there ten thousand years\nBright shining as the sun,\n' + 'We\'ve no less days to sing God\'s praise\nThan when we\'ve first begun.', 'v4')], + 'verse_order_list': []}, {'title': 'Beautiful Garden Of Prayer', - 'authors': ['Eleanor Allen Schroll James H. Fillmore'], - 'copyright': 'Public Domain', - 'ccli_number': 0, - 'verses': - [('O the beautiful garden, the garden of prayer,\nO the beautiful garden of prayer.\n' - 'There my Savior awaits, and He opens the gates\nTo the beautiful garden of prayer.', 'c1'), - ('There\'s a garden where Jesus is waiting,\nThere\'s a place that is wondrously fair.\n' - 'For it glows with the light of His presence,\n\'Tis the beautiful garden of prayer.', 'v1'), - ('There\'s a garden where Jesus is waiting,\nAnd I go with my burden and care.\n' - 'Just to learn from His lips, words of comfort,\nIn the beautiful garden of prayer.', 'v2'), - ('There\'s a garden where Jesus is waiting,\nAnd He bids you to come meet Him there,\n' - 'Just to bow and receive a new blessing,\nIn the beautiful garden of prayer.', 'v3')], - 'verse_order_list': []}] + 'authors': ['Eleanor Allen Schroll James H. Fillmore'], + 'copyright': 'Public Domain', + 'ccli_number': 0, + 'verses': + [('O the beautiful garden, the garden of prayer,\nO the beautiful garden of prayer.\n' + 'There my Savior awaits, and He opens the gates\nTo the beautiful garden of prayer.', 'c1'), + ('There\'s a garden where Jesus is waiting,\nThere\'s a place that is wondrously fair.\n' + 'For it glows with the light of His presence,\n\'Tis the beautiful garden of prayer.', 'v1'), + ('There\'s a garden where Jesus is waiting,\nAnd I go with my burden and care.\n' + 'Just to learn from His lips, words of comfort,\nIn the beautiful garden of prayer.', 'v2'), + ('There\'s a garden where Jesus is waiting,\nAnd He bids you to come meet Him there,\n' + 'Just to bow and receive a new blessing,\nIn the beautiful garden of prayer.', 'v3')], + 'verse_order_list': []}] class EasyWorshipSongImportLogger(EasyWorshipSongImport): @@ -95,26 +95,32 @@ class TestFieldDesc: self.size = size TEST_DATA_ENCODING = 'cp1252' -CODE_PAGE_MAPPINGS = [(852, 'cp1250'), (737, 'cp1253'), (775, 'cp1257'), (855, 'cp1251'), (857, 'cp1254'), +CODE_PAGE_MAPPINGS = [ + (852, 'cp1250'), (737, 'cp1253'), (775, 'cp1257'), (855, 'cp1251'), (857, 'cp1254'), (866, 'cp1251'), (869, 'cp1253'), (862, 'cp1255'), (874, 'cp874')] -TEST_FIELD_DESCS = [TestFieldDesc('Title', FieldType.String, 50), +TEST_FIELD_DESCS = [ + TestFieldDesc('Title', FieldType.String, 50), TestFieldDesc('Text Percentage Bottom', FieldType.Int16, 2), TestFieldDesc('RecID', FieldType.Int32, 4), TestFieldDesc('Default Background', FieldType.Logical, 1), TestFieldDesc('Words', FieldType.Memo, 250), TestFieldDesc('Words', FieldType.Memo, 250), TestFieldDesc('BK Bitmap', FieldType.Blob, 10), TestFieldDesc('Last Modified', FieldType.Timestamp, 10)] -TEST_FIELDS = [b'A Heart Like Thine\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', 32868, 2147483750, +TEST_FIELDS = [ + b'A Heart Like Thine\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', 32868, 2147483750, 129, b'{\\rtf1\\ansi\\deff0\\deftab254{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}{\\f1\\fnil\\fcharset0 Verdana;}}' - b'{\\colortbl\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0\\blue255;' - b'\\red255\\green255\\blue0;\\red255\\green0\\blue255;\\red128\\g\xBF\xBD\7\0f\r\0\0\1\0', - b'{\\rtf1\\ansi\\deff0\\deftab254{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}{\\f1\\fnil\\fcharset0 Verdana;}}' - b'{\\colortbl\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0\\blue255;\\red255' - b'\\green255\\blue0;\\red255\\green0\\blue255;\\red128\\g\6\0\xEF\xBF\xBD\6\0\0\1\0', b'\0\0\0\0\0\0\0\0\0\0', 0] + b'{\\colortbl\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0\\blue255;' + b'\\red255\\green255\\blue0;\\red255\\green0\\blue255;\\red128\\g\xBF\xBD\7\0f\r\0\0\1\0', + b'{\\rtf1\\ansi\\deff0\\deftab254{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}{\\f1\\fnil\\fcharset0 Verdana;}}' + b'{\\colortbl\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0' + b'\\blue255;\\red255' + b'\\green255\\blue0;\\red255\\green0\\blue255;\\red128\\g\6\0\xEF\xBF\xBD\6\0\0\1\0', + b'\0\0\0\0\0\0\0\0\0\0', 0] GET_MEMO_FIELD_TEST_RESULTS = [ - (4, b'\2', {'return': b'\2','read': (1, 3430), 'seek': (507136, (8, os.SEEK_CUR))}), + (4, b'\2', {'return': b'\2', 'read': (1, 3430), 'seek': (507136, (8, os.SEEK_CUR))}), (4, b'\3', {'return': b'', 'read': (1, ), 'seek': (507136, )}), (5, b'\3', {'return': b'\3', 'read': (1, 1725), 'seek': (3220111360, (41, os.SEEK_CUR), 3220111408)}), (5, b'\4', {'return': b'', 'read': (), 'seek': ()})] + class TestEasyWorshipSongImport(TestCase): """ Test the functions in the :mod:`ewimport` module. @@ -135,7 +141,7 @@ class TestEasyWorshipSongImport(TestCase): self.assertIsNotNone(field_desc_entry, 'Import should not be none') self.assertEquals(field_desc_entry.name, name, 'FieldDescEntry.name should be the same as the name argument') self.assertEquals(field_desc_entry.field_type, field_type, - 'FieldDescEntry.type should be the same as the typeargument') + 'FieldDescEntry.type should be the same as the type argument') self.assertEquals(field_desc_entry.size, size, 'FieldDescEntry.size should be the same as the size argument') def create_importer_test(self): @@ -164,7 +170,7 @@ class TestEasyWorshipSongImport(TestCase): # WHEN: Called with a field name that exists existing_fields = ['Title', 'Text Percentage Bottom', 'RecID', 'Default Background', 'Words', - 'BK Bitmap', 'Last Modified'] + 'BK Bitmap', 'Last Modified'] for field_name in existing_fields: # THEN: The item corresponding the index returned should have the same name attribute @@ -194,7 +200,7 @@ class TestEasyWorshipSongImport(TestCase): # GIVEN: A mocked out SongImport class, a mocked out struct class, and a mocked out "manager" and a list of # field descriptions with patch('openlp.plugins.songs.lib.ewimport.SongImport'), \ - patch('openlp.plugins.songs.lib.ewimport.struct') as mocked_struct: + patch('openlp.plugins.songs.lib.ewimport.struct') as mocked_struct: mocked_manager = MagicMock() importer = EasyWorshipSongImport(mocked_manager, filenames=[]) @@ -225,7 +231,8 @@ class TestEasyWorshipSongImport(TestCase): # THEN: get_field should return the known results self.assertEquals(return_value, result, - 'get_field should return "%s" when called with "%s"' % (result, TEST_FIELDS[field_index])) + 'get_field should return "%s" when called with "%s"' % + (result, TEST_FIELDS[field_index])) def get_memo_field_test(self): """ @@ -265,7 +272,7 @@ class TestEasyWorshipSongImport(TestCase): """ # GIVEN: A mocked out SongImport class, a mocked out "manager" with patch('openlp.plugins.songs.lib.ewimport.SongImport'), \ - patch('openlp.plugins.songs.lib.ewimport.os.path') as mocked_os_path: + patch('openlp.plugins.songs.lib.ewimport.os.path') as mocked_os_path: mocked_manager = MagicMock() importer = EasyWorshipSongImport(mocked_manager, filenames=[]) mocked_os_path.isfile.side_effect = [True, False] @@ -284,7 +291,7 @@ class TestEasyWorshipSongImport(TestCase): """ # GIVEN: A mocked out SongImport class, os.path and a mocked out "manager" with patch('openlp.plugins.songs.lib.ewimport.SongImport'), \ - patch('openlp.plugins.songs.lib.ewimport.os.path') as mocked_os_path: + patch('openlp.plugins.songs.lib.ewimport.os.path') as mocked_os_path: mocked_manager = MagicMock() importer = EasyWorshipSongImport(mocked_manager, filenames=[]) mocked_os_path.isfile.return_value = True @@ -305,7 +312,7 @@ class TestEasyWorshipSongImport(TestCase): with patch('openlp.plugins.songs.lib.ewimport.SongImport'), \ patch('openlp.plugins.songs.lib.ewimport.os.path') as mocked_os_path, \ patch('builtins.open') as mocked_open, \ - patch('openlp.plugins.songs.lib.ewimport.struct') as mocked_struct: + patch('openlp.plugins.songs.lib.ewimport.struct') as mocked_struct: mocked_manager = MagicMock() importer = EasyWorshipSongImport(mocked_manager, filenames=[]) mocked_os_path.isfile.return_value = True @@ -320,7 +327,7 @@ class TestEasyWorshipSongImport(TestCase): for effect in struct_unpack_return_values: self.assertIsNone(importer.do_import(), 'do_import should return None when db_size is less than 0x800') self.assertEqual(mocked_open().close.call_count, 2, - 'The open db and memo files should have been closed') + 'The open db and memo files should have been closed') mocked_open().close.reset_mock() self.assertIs(mocked_open().seek.called, False, 'db_file.seek should not have been called.') @@ -332,7 +339,8 @@ class TestEasyWorshipSongImport(TestCase): with patch('openlp.plugins.songs.lib.ewimport.SongImport'), \ patch('openlp.plugins.songs.lib.ewimport.os.path') as mocked_os_path, \ patch('builtins.open'), patch('openlp.plugins.songs.lib.ewimport.struct') as mocked_struct, \ - patch('openlp.plugins.songs.lib.ewimport.retrieve_windows_encoding') as mocked_retrieve_windows_encoding: + patch('openlp.plugins.songs.lib.ewimport.retrieve_windows_encoding') as \ + mocked_retrieve_windows_encoding: mocked_manager = MagicMock() importer = EasyWorshipSongImport(mocked_manager, filenames=[]) mocked_os_path.isfile.return_value = True @@ -357,7 +365,8 @@ class TestEasyWorshipSongImport(TestCase): # GIVEN: Test files with a mocked out SongImport class, a mocked out "manager", a mocked out "import_wizard", # and mocked out "author", "add_copyright", "add_verse", "finish" methods. with patch('openlp.plugins.songs.lib.ewimport.SongImport'), \ - patch('openlp.plugins.songs.lib.ewimport.retrieve_windows_encoding') as mocked_retrieve_windows_encoding: + patch('openlp.plugins.songs.lib.ewimport.retrieve_windows_encoding') as \ + mocked_retrieve_windows_encoding: mocked_retrieve_windows_encoding.return_value = 'cp1252' mocked_manager = MagicMock() mocked_import_wizard = MagicMock() @@ -395,10 +404,10 @@ class TestEasyWorshipSongImport(TestCase): self.assertEqual(importer.copyright, song_copyright) if ccli_number: self.assertEquals(importer.ccli_number, ccli_number, 'ccli_number for %s should be %s' - % (title, ccli_number)) + % (title, ccli_number)) for verse_text, verse_tag in add_verse_calls: mocked_add_verse.assert_any_call(verse_text, verse_tag) if verse_order_list: - self.assertEquals(importer.verse_order_list, verse_order_list, 'verse_order_list for %s should be %s' - % (title, verse_order_list)) + self.assertEquals(importer.verse_order_list, verse_order_list, + 'verse_order_list for %s should be %s' % (title, verse_order_list)) mocked_finish.assert_called_with() diff --git a/tests/functional/openlp_plugins/songs/test_lib.py b/tests/functional/openlp_plugins/songs/test_lib.py index beff6d0d5..f6e5d98b9 100644 --- a/tests/functional/openlp_plugins/songs/test_lib.py +++ b/tests/functional/openlp_plugins/songs/test_lib.py @@ -44,20 +44,20 @@ class TestLib(TestCase): """ Mock up two songs and provide a set of lyrics for the songs_probably_equal tests. """ - self.full_lyrics ='''amazing grace how sweet the sound that saved a wretch like me i once was lost but now am + self.full_lyrics = '''amazing grace how sweet the sound that saved a wretch like me i once was lost but now am found was blind but now i see twas grace that taught my heart to fear and grace my fears relieved how - precious did that grace appear the hour i first believed through many dangers toils and snares i have already - come tis grace that brought me safe thus far and grace will lead me home''' - self.short_lyrics ='''twas grace that taught my heart to fear and grace my fears relieved how precious did that - grace appear the hour i first believed''' - self.error_lyrics ='''amazing how sweet the trumpet that saved a wrench like me i once was losst but now am + precious did that grace appear the hour i first believed through many dangers toils and snares i have + already come tis grace that brought me safe thus far and grace will lead me home''' + self.short_lyrics = '''twas grace that taught my heart to fear and grace my fears relieved how precious did + that grace appear the hour i first believed''' + self.error_lyrics = '''amazing how sweet the trumpet that saved a wrench like me i once was losst but now am found waf blind but now i see it was grace that taught my heart to fear and grace my fears relieved how precious did that grace appppppppear the hour i first believedxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx snares i have already come to this grace that brought me safe so far and grace will lead me home''' - self.different_lyrics='''on a hill far away stood an old rugged cross the emblem of suffering and shame and i love - that old cross where the dearest and best for a world of lost sinners was slain so ill cherish the old rugged - cross till my trophies at last i lay down i will cling to the old rugged cross and exchange it some day for a - crown''' + self.different_lyrics = '''on a hill far away stood an old rugged cross the emblem of suffering and shame and + i love that old cross where the dearest and best for a world of lost sinners was slain so ill cherish the + old rugged cross till my trophies at last i lay down i will cling to the old rugged cross and exchange it + some day for a crown''' self.song1 = MagicMock() self.song2 = MagicMock() @@ -99,7 +99,7 @@ class TestLib(TestCase): result = songs_probably_equal(self.song1, self.song2) # THEN: The result should be True. - assert result == True, 'The result should be True' + assert result is True, 'The result should be True' def songs_probably_equal_short_song_test(self): """ @@ -113,7 +113,7 @@ class TestLib(TestCase): result = songs_probably_equal(self.song1, self.song2) # THEN: The result should be True. - assert result == True, 'The result should be True' + assert result is True, 'The result should be True' def songs_probably_equal_error_song_test(self): """ @@ -127,7 +127,7 @@ class TestLib(TestCase): result = songs_probably_equal(self.song1, self.song2) # THEN: The result should be True. - assert result == True, 'The result should be True' + assert result is True, 'The result should be True' def songs_probably_equal_different_song_test(self): """ @@ -141,7 +141,7 @@ class TestLib(TestCase): result = songs_probably_equal(self.song1, self.song2) # THEN: The result should be False. - assert result == False, 'The result should be False' + assert result is False, 'The result should be False' def remove_typos_beginning_test(self): """ @@ -267,8 +267,8 @@ class TestLib(TestCase): # WHEN: We call strip_rtf on the input RTF result, result_enc = strip_rtf( - '{\\rtf1 \\ansi \\ansicpg1252 {\\fonttbl \\f0 \\fswiss \\fcharset%s Helvetica;}' \ - '{\\colortbl ;\\red0 \\green0 \\blue0 ;}\\pard \\f0 %s}' % (charset, input)) + '{\\rtf1 \\ansi \\ansicpg1252 {\\fonttbl \\f0 \\fswiss \\fcharset%s Helvetica;}' + '{\\colortbl ;\\red0 \\green0 \\blue0 ;}\\pard \\f0 %s}' % (charset, input)) # THEN: The stripped text matches thed expected result assert result == exp_result, 'The result should be %s' % exp_result diff --git a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py index a968975b3..e7bd891d3 100644 --- a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py +++ b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py @@ -110,7 +110,7 @@ class TestSongBeamerImport(TestCase): # THEN: do_import should return none and the progress bar setMaximum should be called with the length of # import_source. self.assertIsNone(importer.do_import(), - 'do_import should return None when import_source is a list and stop_import_flag is True') + 'do_import should return None when import_source is a list and stop_import_flag is True') mocked_import_wizard.progress_bar.setMaximum.assert_called_with(len(importer.import_source)) def file_import_test(self): @@ -147,9 +147,9 @@ class TestSongBeamerImport(TestCase): for verse_text, verse_tag in add_verse_calls: mocked_add_verse.assert_any_call(verse_text, verse_tag) if song_book_name: - self.assertEquals(importer.song_book_name, song_book_name, 'song_book_name for %s should be "%s"' - % (song_file, song_book_name)) + self.assertEquals(importer.song_book_name, song_book_name, 'song_book_name for %s should be "%s"' % + (song_file, song_book_name)) if song_number: - self.assertEquals(importer.song_number, song_number, 'song_number for %s should be %s' - % (song_file, song_number)) + self.assertEquals(importer.song_number, song_number, 'song_number for %s should be %s' % + (song_file, song_number)) mocked_finish.assert_called_with() diff --git a/tests/functional/openlp_plugins/songs/test_songselect.py b/tests/functional/openlp_plugins/songs/test_songselect.py index 0b32cff95..8d1237190 100644 --- a/tests/functional/openlp_plugins/songs/test_songselect.py +++ b/tests/functional/openlp_plugins/songs/test_songselect.py @@ -352,7 +352,7 @@ class TestSongSelect(TestCase): """ # GIVEN: A song to save, and some mocked out objects with patch('openlp.plugins.songs.lib.songselect.clean_song') as mocked_clean_song, \ - patch('openlp.plugins.songs.lib.songselect.Author') as MockedAuthor: + patch('openlp.plugins.songs.lib.songselect.Author') as MockedAuthor: song_dict = { 'title': 'Arky Arky', 'authors': ['Public Domain'], diff --git a/tests/functional/openlp_plugins/songs/test_songshowplusimport.py b/tests/functional/openlp_plugins/songs/test_songshowplusimport.py index 16af347b2..7876558e9 100644 --- a/tests/functional/openlp_plugins/songs/test_songshowplusimport.py +++ b/tests/functional/openlp_plugins/songs/test_songshowplusimport.py @@ -115,8 +115,8 @@ class TestSongShowPlusImport(TestCase): # THEN: do_import should return none and the progress bar setMaximum should be called with the length of # import_source. - self.assertIsNone(importer.do_import(), - 'do_import should return None when import_source is a list and stop_import_flag is True') + self.assertIsNone(importer.do_import(), 'do_import should return None when import_source is a list ' + 'and stop_import_flag is True') mocked_import_wizard.progress_bar.setMaximum.assert_called_with(len(importer.import_source)) def to_openlp_verse_tag_test(self): @@ -129,7 +129,8 @@ class TestSongShowPlusImport(TestCase): importer = SongShowPlusImport(mocked_manager, filenames=[]) # WHEN: Supplied with the following arguments replicating verses being added - test_values = [('Verse 1', VerseType.tags[VerseType.Verse] + '1'), + test_values = [ + ('Verse 1', VerseType.tags[VerseType.Verse] + '1'), ('Verse 2', VerseType.tags[VerseType.Verse] + '2'), ('verse1', VerseType.tags[VerseType.Verse] + '1'), ('Verse', VerseType.tags[VerseType.Verse] + '1'), @@ -143,8 +144,8 @@ class TestSongShowPlusImport(TestCase): # THEN: The returned value should should correlate with the input arguments for original_tag, openlp_tag in test_values: self.assertEquals(importer.to_openlp_verse_tag(original_tag), openlp_tag, - 'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"' - % (openlp_tag, original_tag)) + 'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"' % + (openlp_tag, original_tag)) def to_openlp_verse_tag_verse_order_test(self): """ @@ -156,7 +157,8 @@ class TestSongShowPlusImport(TestCase): importer = SongShowPlusImport(mocked_manager, filenames=[]) # WHEN: Supplied with the following arguments replicating a verse order being added - test_values = [('Verse 1', VerseType.tags[VerseType.Verse] + '1'), + test_values = [ + ('Verse 1', VerseType.tags[VerseType.Verse] + '1'), ('Verse 2', VerseType.tags[VerseType.Verse] + '2'), ('verse1', VerseType.tags[VerseType.Verse] + '1'), ('Verse', VerseType.tags[VerseType.Verse] + '1'), @@ -171,5 +173,5 @@ class TestSongShowPlusImport(TestCase): # THEN: The returned value should should correlate with the input arguments for original_tag, openlp_tag in test_values: self.assertEquals(importer.to_openlp_verse_tag(original_tag, ignore_unique=True), openlp_tag, - 'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"' - % (openlp_tag, original_tag)) + 'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"' % + (openlp_tag, original_tag)) diff --git a/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py b/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py index 630fb572e..9a58a6c2b 100644 --- a/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py +++ b/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py @@ -73,35 +73,37 @@ class WorshipCenterProImportLogger(WorshipCenterProImport): RECORDSET_TEST_DATA = [TestRecord(1, 'TITLE', 'Amazing Grace'), - TestRecord(1, 'LYRICS', - 'Amazing grace! How&crlf;sweet the sound&crlf;That saved a wretch like me!&crlf;' - 'I once was lost,&crlf;but now am found;&crlf;Was blind, but now I see.&crlf;&crlf;' - '\'Twas grace that&crlf;taught my heart to fear,&crlf;And grace my fears relieved;&crlf;' - 'How precious did&crlf;that grace appear&crlf;The hour I first believed.&crlf;&crlf;' - 'Through many dangers,&crlf;toils and snares,&crlf;I have already come;&crlf;' - '\'Tis grace hath brought&crlf;me safe thus far,&crlf;' - 'And grace will lead me home.&crlf;&crlf;The Lord has&crlf;promised good to me,&crlf;' - 'His Word my hope secures;&crlf;He will my Shield&crlf;and Portion be,&crlf;' - 'As long as life endures.&crlf;&crlf;Yea, when this flesh&crlf;and heart shall fail,&crlf;' - 'And mortal life shall cease,&crlf;I shall possess,&crlf;within the veil,&crlf;' - 'A life of joy and peace.&crlf;&crlf;The earth shall soon&crlf;dissolve like snow,&crlf;' - 'The sun forbear to shine;&crlf;But God, Who called&crlf;me here below,&crlf;' - 'Shall be forever mine.&crlf;&crlf;When we\'ve been there&crlf;ten thousand years,&crlf;' - 'Bright shining as the sun,&crlf;We\'ve no less days to&crlf;sing God\'s praise&crlf;' - 'Than when we\'d first begun.&crlf;&crlf;'), + TestRecord( + 1, 'LYRICS', + 'Amazing grace! How&crlf;sweet the sound&crlf;That saved a wretch like me!&crlf;' + 'I once was lost,&crlf;but now am found;&crlf;Was blind, but now I see.&crlf;&crlf;' + '\'Twas grace that&crlf;taught my heart to fear,&crlf;And grace my fears relieved;&crlf;' + 'How precious did&crlf;that grace appear&crlf;The hour I first believed.&crlf;&crlf;' + 'Through many dangers,&crlf;toils and snares,&crlf;I have already come;&crlf;' + '\'Tis grace hath brought&crlf;me safe thus far,&crlf;' + 'And grace will lead me home.&crlf;&crlf;The Lord has&crlf;promised good to me,&crlf;' + 'His Word my hope secures;&crlf;He will my Shield&crlf;and Portion be,&crlf;' + 'As long as life endures.&crlf;&crlf;Yea, when this flesh&crlf;and heart shall fail,&crlf;' + 'And mortal life shall cease,&crlf;I shall possess,&crlf;within the veil,&crlf;' + 'A life of joy and peace.&crlf;&crlf;The earth shall soon&crlf;dissolve like snow,&crlf;' + 'The sun forbear to shine;&crlf;But God, Who called&crlf;me here below,&crlf;' + 'Shall be forever mine.&crlf;&crlf;When we\'ve been there&crlf;ten thousand years,&crlf;' + 'Bright shining as the sun,&crlf;We\'ve no less days to&crlf;sing God\'s praise&crlf;' + 'Than when we\'d first begun.&crlf;&crlf;'), TestRecord(2, 'TITLE', 'Beautiful Garden Of Prayer, The'), - TestRecord(2, 'LYRICS', - 'There\'s a garden where&crlf;Jesus is waiting,&crlf;' - 'There\'s a place that&crlf;is wondrously fair,&crlf;For it glows with the&crlf;' - 'light of His presence.&crlf;\'Tis the beautiful&crlf;garden of prayer.&crlf;&crlf;' - 'Oh, the beautiful garden,&crlf;the garden of prayer!&crlf;Oh, the beautiful&crlf;' - 'garden of prayer!&crlf;There my Savior awaits,&crlf;and He opens the gates&crlf;' - 'To the beautiful&crlf;garden of prayer.&crlf;&crlf;There\'s a garden where&crlf;' - 'Jesus is waiting,&crlf;And I go with my&crlf;burden and care,&crlf;' - 'Just to learn from His&crlf;lips words of comfort&crlf;In the beautiful&crlf;' - 'garden of prayer.&crlf;&crlf;There\'s a garden where&crlf;Jesus is waiting,&crlf;' - 'And He bids you to come,&crlf;meet Him there;&crlf;Just to bow and&crlf;' - 'receive a new blessing&crlf;In the beautiful&crlf;garden of prayer.&crlf;&crlf;')] + TestRecord( + 2, 'LYRICS', + 'There\'s a garden where&crlf;Jesus is waiting,&crlf;' + 'There\'s a place that&crlf;is wondrously fair,&crlf;For it glows with the&crlf;' + 'light of His presence.&crlf;\'Tis the beautiful&crlf;garden of prayer.&crlf;&crlf;' + 'Oh, the beautiful garden,&crlf;the garden of prayer!&crlf;Oh, the beautiful&crlf;' + 'garden of prayer!&crlf;There my Savior awaits,&crlf;and He opens the gates&crlf;' + 'To the beautiful&crlf;garden of prayer.&crlf;&crlf;There\'s a garden where&crlf;' + 'Jesus is waiting,&crlf;And I go with my&crlf;burden and care,&crlf;' + 'Just to learn from His&crlf;lips words of comfort&crlf;In the beautiful&crlf;' + 'garden of prayer.&crlf;&crlf;There\'s a garden where&crlf;Jesus is waiting,&crlf;' + 'And He bids you to come,&crlf;meet Him there;&crlf;Just to bow and&crlf;' + 'receive a new blessing&crlf;In the beautiful&crlf;garden of prayer.&crlf;&crlf;')] SONG_TEST_DATA = [{'title': 'Amazing Grace', 'verses': [ ('Amazing grace! How\nsweet the sound\nThat saved a wretch like me!\nI once was lost,\n' @@ -118,7 +120,7 @@ SONG_TEST_DATA = [{'title': 'Amazing Grace', 'me here below,\nShall be forever mine.'), ('When we\'ve been there\nten thousand years,\nBright shining as the sun,\n' 'We\'ve no less days to\nsing God\'s praise\nThan when we\'d first begun.')]}, - {'title': 'Beautiful Garden Of Prayer, The', + {'title': 'Beautiful Garden Of Prayer, The', 'verses': [ ('There\'s a garden where\nJesus is waiting,\nThere\'s a place that\nis wondrously fair,\n' 'For it glows with the\nlight of His presence.\n\'Tis the beautiful\ngarden of prayer.'), @@ -129,6 +131,7 @@ SONG_TEST_DATA = [{'title': 'Amazing Grace', ('There\'s a garden where\nJesus is waiting,\nAnd He bids you to come,\nmeet Him there;\n' 'Just to bow and\nreceive a new blessing\nIn the beautiful\ngarden of prayer.')]}] + class TestWorshipCenterProSongImport(TestCase): """ Test the functions in the :mod:`worshipcenterproimport` module. @@ -155,7 +158,7 @@ class TestWorshipCenterProSongImport(TestCase): # a mocked "manager" and a mocked out log_error method. with patch('openlp.plugins.songs.lib.worshipcenterproimport.SongImport'), \ patch('openlp.plugins.songs.lib.worshipcenterproimport.pyodbc.connect') as mocked_pyodbc_connect, \ - patch('openlp.plugins.songs.lib.worshipcenterproimport.translate') as mocked_translate: + patch('openlp.plugins.songs.lib.worshipcenterproimport.translate') as mocked_translate: mocked_manager = MagicMock() mocked_log_error = MagicMock() mocked_translate.return_value = 'Translated Text' @@ -171,9 +174,9 @@ class TestWorshipCenterProSongImport(TestCase): # THEN: do_import should return None, and pyodbc, translate & log_error are called with known calls self.assertIsNone(return_value, 'do_import should return None when pyodbc raises an exception.') - mocked_pyodbc_connect.assert_called_with( 'DRIVER={Microsoft Access Driver (*.mdb)};DBQ=import_source') + mocked_pyodbc_connect.assert_called_with('DRIVER={Microsoft Access Driver (*.mdb)};DBQ=import_source') mocked_translate.assert_called_with('SongsPlugin.WorshipCenterProImport', - 'Unable to connect the WorshipCenter Pro database.') + 'Unable to connect the WorshipCenter Pro database.') mocked_log_error.assert_called_with('import_source', 'Translated Text') def song_import_test(self): @@ -184,7 +187,7 @@ class TestWorshipCenterProSongImport(TestCase): # translate method, a mocked "manager", add_verse method & mocked_finish method. with patch('openlp.plugins.songs.lib.worshipcenterproimport.SongImport'), \ patch('openlp.plugins.songs.lib.worshipcenterproimport.pyodbc') as mocked_pyodbc, \ - patch('openlp.plugins.songs.lib.worshipcenterproimport.translate') as mocked_translate: + patch('openlp.plugins.songs.lib.worshipcenterproimport.translate') as mocked_translate: mocked_manager = MagicMock() mocked_import_wizard = MagicMock() mocked_add_verse = MagicMock() @@ -201,9 +204,8 @@ class TestWorshipCenterProSongImport(TestCase): # WHEN: Calling the do_import method return_value = importer.do_import() - - # THEN: do_import should return None, and pyodbc, import_wizard, importer.title and add_verse are called with - # known calls + # THEN: do_import should return None, and pyodbc, import_wizard, importer.title and add_verse are called + # with known calls self.assertIsNone(return_value, 'do_import should return None when pyodbc raises an exception.') mocked_pyodbc.connect.assert_called_with('DRIVER={Microsoft Access Driver (*.mdb)};DBQ=import_source') mocked_pyodbc.connect().cursor.assert_any_call() @@ -214,10 +216,10 @@ class TestWorshipCenterProSongImport(TestCase): for song_data in SONG_TEST_DATA: title_value = song_data['title'] self.assertIn(title_value, importer._title_assignment_list, - 'title should have been set to %s' % title_value) + 'title should have been set to %s' % title_value) verse_calls = song_data['verses'] add_verse_call_count += len(verse_calls) for call in verse_calls: mocked_add_verse.assert_any_call(call) self.assertEqual(mocked_add_verse.call_count, add_verse_call_count, - 'Incorrect number of calls made to add_verse') + 'Incorrect number of calls made to add_verse') diff --git a/tests/helpers/songfileimport.py b/tests/helpers/songfileimport.py index 12754f55a..cc67770c1 100644 --- a/tests/helpers/songfileimport.py +++ b/tests/helpers/songfileimport.py @@ -116,28 +116,27 @@ class SongImportTestHelper(TestCase): if song_copyright: self.mocked_add_copyright.assert_called_with(song_copyright) if ccli_number: - self.assertEquals(importer.ccli_number, ccli_number, 'ccli_number for %s should be %s' - % (source_file_name, ccli_number)) + self.assertEquals(importer.ccli_number, ccli_number, 'ccli_number for %s should be %s' % + (source_file_name, ccli_number)) for verse_text, verse_tag in add_verse_calls: self.mocked_add_verse.assert_any_call(verse_text, verse_tag) if topics: self.assertEquals(importer.topics, topics, 'topics for %s should be %s' % (source_file_name, topics)) if comments: - self.assertEquals(importer.comments, comments, 'comments for %s should be "%s"' - % (source_file_name, comments)) + self.assertEquals(importer.comments, comments, 'comments for %s should be "%s"' % + (source_file_name, comments)) if song_book_name: - self.assertEquals(importer.song_book_name, song_book_name, 'song_book_name for %s should be "%s"' - % (source_file_name, song_book_name)) + self.assertEquals(importer.song_book_name, song_book_name, 'song_book_name for %s should be "%s"' % + (source_file_name, song_book_name)) if song_number: - self.assertEquals(importer.song_number, song_number, 'song_number for %s should be %s' - % (source_file_name, song_number)) + self.assertEquals(importer.song_number, song_number, 'song_number for %s should be %s' % + (source_file_name, song_number)) if verse_order_list: - self.assertEquals(importer.verse_order_list, [], 'verse_order_list for %s should be %s' - % (source_file_name, verse_order_list)) + self.assertEquals(importer.verse_order_list, [], 'verse_order_list for %s should be %s' % + (source_file_name, verse_order_list)) self.mocked_finish.assert_called_with() def _get_data(self, data, key): if key in data: return data[key] return '' - diff --git a/tests/interfaces/openlp_core_lib/__init__.py b/tests/interfaces/openlp_core_lib/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/interfaces/openlp_core_lib/__init__.py +++ b/tests/interfaces/openlp_core_lib/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/interfaces/openlp_core_lib/test_pluginmanager.py b/tests/interfaces/openlp_core_lib/test_pluginmanager.py index 054aa6dc1..262f9f2f3 100644 --- a/tests/interfaces/openlp_core_lib/test_pluginmanager.py +++ b/tests/interfaces/openlp_core_lib/test_pluginmanager.py @@ -95,4 +95,3 @@ class TestPluginManager(TestCase, TestMixin): assert 'songusage' in plugin_names, 'There should be a "songusage" plugin.' assert 'alerts' in plugin_names, 'There should be a "alerts" plugin.' assert 'remotes' in plugin_names, 'There should be a "remotes" plugin.' - diff --git a/tests/interfaces/openlp_core_lib/test_searchedit.py b/tests/interfaces/openlp_core_lib/test_searchedit.py new file mode 100644 index 000000000..22bf6fae3 --- /dev/null +++ b/tests/interfaces/openlp_core_lib/test_searchedit.py @@ -0,0 +1,135 @@ +# -*- 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 # +############################################################################### +""" +Module to test the EditCustomForm. +""" +from unittest import TestCase +from unittest.mock import MagicMock + +from PyQt4 import QtCore, QtGui, QtTest + +from openlp.core.common import Registry +from openlp.core.lib.searchedit import SearchEdit +from tests.helpers.testmixin import TestMixin + + +class SearchTypes(object): + First = 0 + Second = 1 + + +SECOND_PLACEHOLDER_TEXT = "Second Placeholder Text" +SEARCH_TYPES = [(SearchTypes.First, QtGui.QIcon(), "First", "First Placeholder Text"), + (SearchTypes.Second, QtGui.QIcon(), "Second", SECOND_PLACEHOLDER_TEXT)] + + +class TestSearchEdit(TestCase, TestMixin): + """ + Test the EditCustomForm. + """ + def setUp(self): + """ + Create the UI + """ + Registry.create() + self.get_application() + self.main_window = QtGui.QMainWindow() + Registry().register('main_window', self.main_window) + + self.search_edit = SearchEdit(self.main_window) + # To complete set up we have to set the search types. + self.search_edit.set_search_types(SEARCH_TYPES) + + def tearDown(self): + """ + Delete all the C++ objects at the end so that we don't have a segfault + """ + del self.main_window + + def set_search_types_test(self): + """ + Test setting the search types of the search edit. + """ + # GIVEN: The search edit with the search types set. NOTE: The set_search_types(types) is called in the setUp() + # method! + + # WHEN: + + # THEN: The first search type should be the first one in the list. + assert self.search_edit.current_search_type() == SearchTypes.First, "The first search type should be selected." + + def set_current_search_type_test(self): + """ + Test if changing the search type works. + """ + # GIVEN: + # WHEN: Change the search type + result = self.search_edit.set_current_search_type(SearchTypes.Second) + + # THEN: + assert result, "The call should return success (True)." + assert self.search_edit.current_search_type() == SearchTypes.Second,\ + "The search type should be SearchTypes.Second" + assert self.search_edit.placeholderText() == SECOND_PLACEHOLDER_TEXT,\ + "The correct placeholder text should be 'Second Placeholder Text'." + + def clear_button_visibility_test(self): + """ + Test if the clear button is hidden/shown correctly. + """ + # GIVEN: Everything is left to its defaults (hidden). + assert self.search_edit.clear_button.isHidden(), "Pre condition not met. Button should be hidden." + + # WHEN: Type something in the search edit. + QtTest.QTest.keyPress(self.search_edit, QtCore.Qt.Key_A) + QtTest.QTest.keyRelease(self.search_edit, QtCore.Qt.Key_A) + + # THEN: The clear button should not be hidden any more. + assert not self.search_edit.clear_button.isHidden(), "The clear button should be visible." + + def press_clear_button_test(self): + """ + Check if the search edit behaves correctly when pressing the clear button. + """ + # GIVEN: A search edit with text. + QtTest.QTest.keyPress(self.search_edit, QtCore.Qt.Key_A) + QtTest.QTest.keyRelease(self.search_edit, QtCore.Qt.Key_A) + + # WHEN: Press the clear button. + QtTest.QTest.mouseClick(self.search_edit.clear_button, QtCore.Qt.LeftButton) + + # THEN: The search edit text should be cleared and the button be hidden. + assert not self.search_edit.text(), "The search edit should not have any text." + assert self.search_edit.clear_button.isHidden(), "The clear button should be hidden." + + def resize_event_test(self): + """ + Just check if the resizeEvent() method is re-implemented. + """ + assert hasattr(self.search_edit, "resizeEvent"), "The search edit should re-implement the resizeEvent method." diff --git a/tests/interfaces/openlp_core_ui/test_mainwindow.py b/tests/interfaces/openlp_core_ui/test_mainwindow.py index de5452632..b79036547 100644 --- a/tests/interfaces/openlp_core_ui/test_mainwindow.py +++ b/tests/interfaces/openlp_core_ui/test_mainwindow.py @@ -85,4 +85,3 @@ class TestMainWindow(TestCase, TestMixin): # THEN: The current widget should have been set. self.main_window.media_tool_box.setCurrentIndex.assert_called_with(2) - diff --git a/tests/interfaces/openlp_core_ui/test_servicemanager.py b/tests/interfaces/openlp_core_ui/test_servicemanager.py index f4f5f26fc..78df788ab 100644 --- a/tests/interfaces/openlp_core_ui/test_servicemanager.py +++ b/tests/interfaces/openlp_core_ui/test_servicemanager.py @@ -313,6 +313,7 @@ class TestServiceManager(TestCase, TestMixin): self.service_manager.notes_action.setVisible = MagicMock() self.service_manager.time_action.setVisible = MagicMock() self.service_manager.auto_start_action.setVisible = MagicMock() + self.service_manager.rename_action.setVisible = MagicMock() # WHEN: Show the context menu. self.service_manager.context_menu(q_point) @@ -329,6 +330,8 @@ class TestServiceManager(TestCase, TestMixin): 'The action should be set invisible.' self.service_manager.auto_start_action.setVisible.assert_called_with(True), \ '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): """ diff --git a/tests/interfaces/openlp_core_ui/test_servicenotedialog.py b/tests/interfaces/openlp_core_ui/test_servicenotedialog.py index 7344dc633..86fc425c1 100644 --- a/tests/interfaces/openlp_core_ui/test_servicenotedialog.py +++ b/tests/interfaces/openlp_core_ui/test_servicenotedialog.py @@ -90,9 +90,8 @@ class TestStartNoteDialog(TestCase, TestMixin): with patch('PyQt4.QtGui.QDialog.exec_'): self.form.exec_() self.form.text_edit.setPlainText(text) - okWidget = self.form.button_box.button(self.form.button_box.Save) - QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton) + ok_widget = self.form.button_box.button(self.form.button_box.Save) + QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton) # THEN the following text is returned self.assertEqual(self.form.text_edit.toPlainText(), text, 'The new text should be returned') - diff --git a/tests/interfaces/openlp_core_ui/test_splashscreen.py b/tests/interfaces/openlp_core_ui/test_splashscreen.py new file mode 100644 index 000000000..35c15f9ec --- /dev/null +++ b/tests/interfaces/openlp_core_ui/test_splashscreen.py @@ -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.' diff --git a/tests/interfaces/openlp_core_utils/__init__.py b/tests/interfaces/openlp_core_utils/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/interfaces/openlp_core_utils/__init__.py +++ b/tests/interfaces/openlp_core_utils/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/interfaces/openlp_core_utils/test_utils.py b/tests/interfaces/openlp_core_utils/test_utils.py index 3c3879b34..3da1db2e2 100644 --- a/tests/interfaces/openlp_core_utils/test_utils.py +++ b/tests/interfaces/openlp_core_utils/test_utils.py @@ -86,4 +86,3 @@ class TestUtils(TestCase, TestMixin): # THEN the result is false assert result is True, 'The file is not an image file so the test should return True' - diff --git a/tests/interfaces/openlp_plugins/__init__.py b/tests/interfaces/openlp_plugins/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/interfaces/openlp_plugins/__init__.py +++ b/tests/interfaces/openlp_plugins/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/interfaces/openlp_plugins/bibles/test_lib_http.py b/tests/interfaces/openlp_plugins/bibles/test_lib_http.py index 9f90df64e..517732e4d 100644 --- a/tests/interfaces/openlp_plugins/bibles/test_lib_http.py +++ b/tests/interfaces/openlp_plugins/bibles/test_lib_http.py @@ -97,4 +97,3 @@ class TestBibleHTTP(TestCase): # THEN: We should get back a valid service item assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed' - diff --git a/tests/interfaces/openlp_plugins/bibles/test_lib_manager.py b/tests/interfaces/openlp_plugins/bibles/test_lib_manager.py index b00bbee00..7296cfc08 100644 --- a/tests/interfaces/openlp_plugins/bibles/test_lib_manager.py +++ b/tests/interfaces/openlp_plugins/bibles/test_lib_manager.py @@ -115,4 +115,3 @@ class TestBibleManager(TestCase, TestMixin): verses = self.manager.get_verse_count_by_book_ref_id('tests', 54, 3) # THEN the chapter count should be returned self.assertEqual(16, verses, '1 Timothy v3 should have 16 verses returned from the bible') - diff --git a/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py b/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py index 811d048db..b085bd1df 100644 --- a/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py +++ b/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py @@ -83,7 +83,7 @@ class TestBibleManager(TestCase, TestMixin): # WHEN asking to parse the bible reference results = parse_reference('1 Timothy 1', self.manager.db_cache['tests'], MagicMock(), 54) # THEN a verse array should be returned - self.assertEquals([(54, 1, 1, -1)], results , "The bible verses should matches the expected results") + self.assertEquals([(54, 1, 1, -1)], results, "The bible verses should matches the expected results") def parse_reference_two_test(self): """ @@ -93,7 +93,7 @@ class TestBibleManager(TestCase, TestMixin): # WHEN asking to parse the bible reference results = parse_reference('1 Timothy 1:1-2', self.manager.db_cache['tests'], MagicMock(), 54) # THEN a verse array should be returned - self.assertEquals([(54, 1, 1, 2)], results , "The bible verses should matches the expected results") + self.assertEquals([(54, 1, 1, 2)], results, "The bible verses should matches the expected results") def parse_reference_three_test(self): """ @@ -103,4 +103,5 @@ class TestBibleManager(TestCase, TestMixin): # WHEN asking to parse the bible reference results = parse_reference('1 Timothy 1:1-2:1', self.manager.db_cache['tests'], MagicMock(), 54) # THEN a verse array should be returned - self.assertEquals([(54,1,1,-1),(54,2,1,1)], results , "The bible verses should matches the expected results") \ No newline at end of file + self.assertEquals([(54, 1, 1, -1), (54, 2, 1, 1)], results, "The bible verses should matches the expected " + "results") diff --git a/tests/interfaces/openlp_plugins/custom/forms/__init__.py b/tests/interfaces/openlp_plugins/custom/forms/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/interfaces/openlp_plugins/custom/forms/__init__.py +++ b/tests/interfaces/openlp_plugins/custom/forms/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/interfaces/openlp_plugins/custom/forms/test_customform.py b/tests/interfaces/openlp_plugins/custom/forms/test_customform.py index 93b271797..ca238b1a6 100644 --- a/tests/interfaces/openlp_plugins/custom/forms/test_customform.py +++ b/tests/interfaces/openlp_plugins/custom/forms/test_customform.py @@ -88,7 +88,6 @@ class TestEditCustomForm(TestCase, TestMixin): self.assertEqual(self.form.title_edit.text(), '', 'The title edit should be empty') self.assertEqual(self.form.credit_edit.text(), '', 'The credit edit should be empty') - def on_add_button_clicked_test(self): """ Test the on_add_button_clicked_test method / add_button button. diff --git a/tests/interfaces/openlp_plugins/custom/forms/test_customslideform.py b/tests/interfaces/openlp_plugins/custom/forms/test_customslideform.py index a2bfb1f10..261519362 100644 --- a/tests/interfaces/openlp_plugins/custom/forms/test_customslideform.py +++ b/tests/interfaces/openlp_plugins/custom/forms/test_customslideform.py @@ -92,4 +92,3 @@ class TestEditCustomSlideForm(TestCase, TestMixin): # THEN: The dialog should have focus. mocked_set_focus.assert_called_with() - diff --git a/tests/interfaces/openlp_plugins/remotes/__init__.py b/tests/interfaces/openlp_plugins/remotes/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/interfaces/openlp_plugins/remotes/__init__.py +++ b/tests/interfaces/openlp_plugins/remotes/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/interfaces/openlp_plugins/songs/__init__.py b/tests/interfaces/openlp_plugins/songs/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/interfaces/openlp_plugins/songs/__init__.py +++ b/tests/interfaces/openlp_plugins/songs/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/interfaces/openlp_plugins/songs/forms/__init__.py b/tests/interfaces/openlp_plugins/songs/forms/__init__.py index 1f4f74a33..6b241e7fc 100644 --- a/tests/interfaces/openlp_plugins/songs/forms/__init__.py +++ b/tests/interfaces/openlp_plugins/songs/forms/__init__.py @@ -25,4 +25,4 @@ # 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 # -############################################################################### \ No newline at end of file +############################################################################### diff --git a/tests/interfaces/openlp_plugins/songs/forms/test_authorsform.py b/tests/interfaces/openlp_plugins/songs/forms/test_authorsform.py index 5d965c042..2257bbc84 100644 --- a/tests/interfaces/openlp_plugins/songs/forms/test_authorsform.py +++ b/tests/interfaces/openlp_plugins/songs/forms/test_authorsform.py @@ -145,4 +145,3 @@ class TestAuthorsForm(TestCase, TestMixin): # THEN: The display_name_edit should have the correct value self.assertEqual(self.form.display_edit.text(), display_name, 'The display name should be set correctly') - diff --git a/tests/interfaces/openlp_plugins/songs/forms/test_editverseform.py b/tests/interfaces/openlp_plugins/songs/forms/test_editverseform.py index 284d850c4..178b1cd7c 100644 --- a/tests/interfaces/openlp_plugins/songs/forms/test_editverseform.py +++ b/tests/interfaces/openlp_plugins/songs/forms/test_editverseform.py @@ -120,4 +120,3 @@ class TestEditVerseForm(TestCase, TestMixin): # THEN: The verse text edit should have a Chorus:1 in it self.assertIn('---[Chorus:1]---', self.form.verse_text_edit.toPlainText(), 'The verse text edit should have a "Chorus 1" marker') - diff --git a/tests/resources/service/test.osz b/tests/resources/service/test.osz new file mode 100644 index 000000000..a289c0775 Binary files /dev/null and b/tests/resources/service/test.osz differ diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py index 22f4ad8e5..e76e095ea 100644 --- a/tests/utils/__init__.py +++ b/tests/utils/__init__.py @@ -48,4 +48,3 @@ def convert_file_service_item(test_path, name, row=0): finally: open_file.close() return first_line - diff --git a/tests/utils/test_bzr_tags.py b/tests/utils/test_bzr_tags.py new file mode 100644 index 000000000..7bb38f4ab --- /dev/null +++ b/tests/utils/test_bzr_tags.py @@ -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')