diff --git a/openlp/core/lib/projector/pjlink1.py b/openlp/core/lib/projector/pjlink1.py index 8ea08c8ea..6e8ca6f87 100644 --- a/openlp/core/lib/projector/pjlink1.py +++ b/openlp/core/lib/projector/pjlink1.py @@ -312,10 +312,10 @@ class PJLink1(QTcpSocket): read = self.readLine(self.maxSize) dontcare = self.readLine(self.maxSize) # Clean out the trailing \r\n if read is None: - log.warn('({ip}) read is None - socket error?'.format(ip=self.ip)) + log.warning('({ip}) read is None - socket error?'.format(ip=self.ip)) return elif len(read) < 8: - log.warn('({ip}) Not enough data read)'.format(ip=self.ip)) + log.warning('({ip}) Not enough data read)'.format(ip=self.ip)) return data = decode(read, 'ascii') # Possibility of extraneous data on input when reading. @@ -413,7 +413,7 @@ class PJLink1(QTcpSocket): self.projectorReceivedData.emit() return elif '=' not in data: - log.warn('({ip}) get_data(): Invalid packet received'.format(ip=self.ip)) + log.warning('({ip}) get_data(): Invalid packet received'.format(ip=self.ip)) self.send_busy = False self.projectorReceivedData.emit() return @@ -421,21 +421,21 @@ class PJLink1(QTcpSocket): try: (prefix, class_, cmd, data) = (data_split[0][0], data_split[0][1], data_split[0][2:], data_split[1]) except ValueError as e: - log.warn('({ip}) get_data(): Invalid packet - expected header + command + data'.format(ip=self.ip)) - log.warn('({ip}) get_data(): Received data: "{data}"'.format(ip=self.ip, data=data_in.strip())) + log.warning('({ip}) get_data(): Invalid packet - expected header + command + data'.format(ip=self.ip)) + log.warning('({ip}) get_data(): Received data: "{data}"'.format(ip=self.ip, data=data_in.strip())) self.change_status(E_INVALID_DATA) self.send_busy = False self.projectorReceivedData.emit() return if not (self.pjlink_class in PJLINK_VALID_CMD and cmd in PJLINK_VALID_CMD[self.pjlink_class]): - log.warn('({ip}) get_data(): Invalid packet - unknown command "{data}"'.format(ip=self.ip, data=cmd)) + log.warning('({ip}) get_data(): Invalid packet - unknown command "{data}"'.format(ip=self.ip, data=cmd)) self.send_busy = False self.projectorReceivedData.emit() return return self.process_command(cmd, data) - @pyqtSlot(int) + @pyqtSlot(QAbstractSocket.SocketError) def get_error(self, err): """ Process error from SocketError signal. @@ -472,7 +472,7 @@ class PJLink1(QTcpSocket): :param queue: Option to force add to queue rather than sending directly """ if self.state() != self.ConnectedState: - log.warn('({ip}) send_command(): Not connected - returning'.format(ip=self.ip)) + log.warning('({ip}) send_command(): Not connected - returning'.format(ip=self.ip)) self.send_queue = [] return self.projectorNetwork.emit(self.ip, S_NETWORK_SENDING) @@ -592,7 +592,7 @@ class PJLink1(QTcpSocket): if cmd in self.PJLINK1_FUNC: self.PJLINK1_FUNC[cmd](data) else: - log.warn('({ip}) Invalid command {data}'.format(ip=self.ip, data=cmd)) + log.warning('({ip}) Invalid command {data}'.format(ip=self.ip, data=cmd)) self.send_busy = False self.projectorReceivedData.emit() @@ -611,7 +611,7 @@ class PJLink1(QTcpSocket): fill = {'Hours': int(data_dict[0]), 'On': False if data_dict[1] == '0' else True} except ValueError: # In case of invalid entry - log.warn('({ip}) process_lamp(): Invalid data "{data}"'.format(ip=self.ip, data=data)) + log.warning('({ip}) process_lamp(): Invalid data "{data}"'.format(ip=self.ip, data=data)) return lamps.append(fill) data_dict.pop(0) # Remove lamp hours @@ -638,7 +638,7 @@ class PJLink1(QTcpSocket): self.send_command('INST') else: # Log unknown status response - log.warn('({ip}) Unknown power response: {data}'.format(ip=self.ip, data=data)) + log.warning('({ip}) Unknown power response: {data}'.format(ip=self.ip, data=data)) return def process_avmt(self, data): @@ -663,7 +663,7 @@ class PJLink1(QTcpSocket): shutter = True mute = True else: - log.warn('({ip}) Unknown shutter response: {data}'.format(ip=self.ip, data=data)) + log.warning('({ip}) Unknown shutter response: {data}'.format(ip=self.ip, data=data)) update_icons = shutter != self.shutter update_icons = update_icons or mute != self.mute self.shutter = shutter @@ -812,7 +812,7 @@ class PJLink1(QTcpSocket): Initiate connection to projector. """ if self.state() == self.ConnectedState: - log.warn('({ip}) connect_to_host(): Already connected - returning'.format(ip=self.ip)) + log.warning('({ip}) connect_to_host(): Already connected - returning'.format(ip=self.ip)) return self.change_status(S_CONNECTING) self.connectToHost(self.ip, self.port if type(self.port) is int else int(self.port)) @@ -824,9 +824,9 @@ class PJLink1(QTcpSocket): """ if abort or self.state() != self.ConnectedState: if abort: - log.warn('({ip}) disconnect_from_host(): Aborting connection'.format(ip=self.ip)) + log.warning('({ip}) disconnect_from_host(): Aborting connection'.format(ip=self.ip)) else: - log.warn('({ip}) disconnect_from_host(): Not connected - returning'.format(ip=self.ip)) + log.warning('({ip}) disconnect_from_host(): Not connected - returning'.format(ip=self.ip)) self.reset_information() self.disconnectFromHost() try: diff --git a/openlp/core/ui/projector/sourceselectform.py b/openlp/core/ui/projector/sourceselectform.py index 11efcdb08..f47622090 100644 --- a/openlp/core/ui/projector/sourceselectform.py +++ b/openlp/core/ui/projector/sourceselectform.py @@ -20,24 +20,21 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ - :mod: `openlp.core.ui.projector.sourceselectform` module +:mod: `openlp.core.ui.projector.sourceselectform` module - Provides the dialog window for selecting video source for projector. +Provides the dialog window for selecting video source for projector. """ import logging -log = logging.getLogger(__name__) -log.debug('editform loaded') from PyQt5 import QtCore, QtWidgets -from PyQt5.QtCore import pyqtSlot, QSize -from PyQt5.QtWidgets import QDialog, QButtonGroup, QDialogButtonBox, QFormLayout, QLineEdit, QRadioButton, \ - QStyle, QStylePainter, QStyleOptionTab, QTabBar, QTabWidget, QVBoxLayout, QWidget from openlp.core.common import translate, is_macosx from openlp.core.lib import build_icon from openlp.core.lib.projector.db import ProjectorSource from openlp.core.lib.projector.constants import PJLINK_DEFAULT_SOURCES, PJLINK_DEFAULT_CODES +log = logging.getLogger(__name__) + def source_group(inputs, source_text): """ @@ -104,8 +101,8 @@ def Build_Tab(group, source_key, default, projector, projectordb, edit=False): :param edit: If we're editing the source text """ buttonchecked = False - widget = QWidget() - layout = QFormLayout() if edit else QVBoxLayout() + widget = QtWidgets.QWidget() + layout = QtWidgets.QFormLayout() if edit else QtWidgets.QVBoxLayout() layout.setSpacing(10) widget.setLayout(layout) tempkey = list(source_key.keys())[0] # Should only be 1 key @@ -114,7 +111,7 @@ def Build_Tab(group, source_key, default, projector, projectordb, edit=False): button_count = len(sourcelist) if edit: for key in sourcelist: - item = QLineEdit() + item = QtWidgets.QLineEdit() item.setObjectName('source_key_%s' % key) source_item = projectordb.get_source_by_code(code=key, projector_id=projector.db_item.id) if source_item is None: @@ -130,7 +127,7 @@ def Build_Tab(group, source_key, default, projector, projectordb, edit=False): text = source_key[tempkey][key] else: text = source_item.text - itemwidget = QRadioButton(text) + itemwidget = QtWidgets.QRadioButton(text) itemwidget.setAutoExclusive(True) if default == key: itemwidget.setChecked(True) @@ -141,30 +138,30 @@ def Build_Tab(group, source_key, default, projector, projectordb, edit=False): return widget, button_count, buttonchecked -def set_button_tooltip(bar): +def set_button_tooltip(button_bar): """ Set the toolip for the standard buttons used :param bar: QDialogButtonBar instance to update """ - for button in bar.buttons(): - if bar.standardButton(button) == QDialogButtonBox.Cancel: + for button in button_bar.buttons(): + if button_bar.standardButton(button) == QtWidgets.QDialogButtonBox.Cancel: button.setToolTip(translate('OpenLP.SourceSelectForm', 'Ignoring current changes and return to OpenLP')) - elif bar.standardButton(button) == QDialogButtonBox.Reset: + elif button_bar.standardButton(button) == QtWidgets.QDialogButtonBox.Reset: button.setToolTip(translate('OpenLP.SourceSelectForm', 'Delete all user-defined text and revert to PJLink default text')) - elif bar.standardButton(button) == QDialogButtonBox.Discard: + elif button_bar.standardButton(button) == QtWidgets.QDialogButtonBox.Discard: button.setToolTip(translate('OpenLP.SourceSelectForm', 'Discard changes and reset to previous user-defined text')) - elif bar.standardButton(button) == QDialogButtonBox.Ok: + elif button_bar.standardButton(button) == QtWidgets.QDialogButtonBox.Ok: button.setToolTip(translate('OpenLP.SourceSelectForm', 'Save changes and return to OpenLP')) else: - log.debug('No tooltip for button {}'.format(button.text())) + log.debug('No tooltip for button %s', button.text()) -class FingerTabBarWidget(QTabBar): +class FingerTabBarWidget(QtWidgets.QTabBar): """ Realign west -orientation tabs to left-right text rather than south-north text Borrowed from @@ -177,8 +174,8 @@ class FingerTabBarWidget(QTabBar): :param width: Remove default width parameter in kwargs :param height: Remove default height parameter in kwargs """ - self.tabSize = QSize(kwargs.pop('width', 100), kwargs.pop('height', 25)) - QTabBar.__init__(self, parent, *args, **kwargs) + self.tabSize = QtWidgets.QSize(kwargs.pop('width', 100), kwargs.pop('height', 25)) + QtWidgets.QTabBar.__init__(self, parent, *args, **kwargs) def paintEvent(self, event): """ @@ -186,14 +183,14 @@ class FingerTabBarWidget(QTabBar): :param event: Repaint event signal """ - painter = QStylePainter(self) - option = QStyleOptionTab() + painter = QtWidgets.QStylePainter(self) + option = QtWidgets.QStyleOptionTab() for index in range(self.count()): self.initStyleOption(option, index) tabRect = self.tabRect(index) tabRect.moveLeft(10) - painter.drawControl(QStyle.CE_TabBarTabShape, option) + painter.drawControl(QtWidgets.QStyle.CE_TabBarTabShape, option) painter.drawText(tabRect, QtCore.Qt.AlignVCenter | QtCore.Qt.TextDontClip, self.tabText(index)) @@ -209,7 +206,7 @@ class FingerTabBarWidget(QTabBar): return self.tabSize -class FingerTabWidget(QTabWidget): +class FingerTabWidget(QtWidgets.QTabWidget): """ A QTabWidget equivalent which uses our FingerTabBarWidget @@ -220,11 +217,11 @@ class FingerTabWidget(QTabWidget): """ Initialize FingerTabWidget instance """ - QTabWidget.__init__(self, parent, *args) + QtWidgets.QTabWidget.__init__(self, parent, *args) self.setTabBar(FingerTabBarWidget(self)) -class SourceSelectTabs(QDialog): +class SourceSelectTabs(QtWidgets.QDialog): """ Class for handling selecting the source for the projector to use. Uses tabbed interface. @@ -248,18 +245,18 @@ class SourceSelectTabs(QDialog): self.setObjectName('source_select_tabs') self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png')) self.setModal(True) - self.layout = QVBoxLayout() + self.layout = QtWidgets.QVBoxLayout() self.layout.setObjectName('source_select_tabs_layout') if is_macosx(): - self.tabwidget = QTabWidget(self) + self.tabwidget = QtWidgets.QTabWidget(self) else: self.tabwidget = FingerTabWidget(self) self.tabwidget.setObjectName('source_select_tabs_tabwidget') self.tabwidget.setUsesScrollButtons(False) if is_macosx(): - self.tabwidget.setTabPosition(QTabWidget.North) + self.tabwidget.setTabPosition(QtWidgets.QTabWidget.North) else: - self.tabwidget.setTabPosition(QTabWidget.West) + self.tabwidget.setTabPosition(QtWidgets.QTabWidget.West) self.layout.addWidget(self.tabwidget) self.setLayout(self.layout) @@ -273,7 +270,7 @@ class SourceSelectTabs(QDialog): self.source_text = self.projectordb.get_source_list(projector=projector) self.source_group = source_group(projector.source_available, self.source_text) # self.source_group = {'4': {'41': 'Storage 1'}, '5': {"51": 'Network 1'}} - self.button_group = [] if self.edit else QButtonGroup() + self.button_group = [] if self.edit else QtWidgets.QButtonGroup() keys = list(self.source_group.keys()) keys.sort() if self.edit: @@ -287,10 +284,10 @@ class SourceSelectTabs(QDialog): thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key]) if buttonchecked: self.tabwidget.setCurrentIndex(thistab) - self.button_box = QDialogButtonBox(QtWidgets.QDialogButtonBox.Reset | - QtWidgets.QDialogButtonBox.Discard | - QtWidgets.QDialogButtonBox.Ok | - QtWidgets.QDialogButtonBox.Cancel) + self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Reset | + QtWidgets.QDialogButtonBox.Discard | + QtWidgets.QDialogButtonBox.Ok | + QtWidgets.QDialogButtonBox.Cancel) else: for key in keys: (tab, button_count, buttonchecked) = Build_Tab(group=self.button_group, @@ -302,15 +299,15 @@ class SourceSelectTabs(QDialog): thistab = self.tabwidget.addTab(tab, PJLINK_DEFAULT_SOURCES[key]) if buttonchecked: self.tabwidget.setCurrentIndex(thistab) - self.button_box = QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | - QtWidgets.QDialogButtonBox.Cancel) + self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | + QtWidgets.QDialogButtonBox.Cancel) self.button_box.clicked.connect(self.button_clicked) self.layout.addWidget(self.button_box) set_button_tooltip(self.button_box) selected = super(SourceSelectTabs, self).exec() return selected - @pyqtSlot(object) + @QtCore.pyqtSlot(QtWidgets.QAbstractButton) def button_clicked(self, button): """ Checks which button was clicked @@ -333,6 +330,9 @@ class SourceSelectTabs(QDialog): return 100 def delete_sources(self): + """ + Delete the source + """ msg = QtWidgets.QMessageBox() msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector')) msg.setInformativeText(translate('OpenLP.SourceSelectForm', @@ -359,20 +359,20 @@ class SourceSelectTabs(QDialog): continue item = self.projectordb.get_source_by_code(code=code, projector_id=projector.id) if item is None: - log.debug("(%s) Adding new source text %s: %s" % (projector.ip, code, text)) + log.debug("(%s) Adding new source text %s: %s", projector.ip, code, text) item = ProjectorSource(projector_id=projector.id, code=code, text=text) else: item.text = text - log.debug('(%s) Updating source code %s with text="%s"' % (projector.ip, item.code, item.text)) + log.debug('(%s) Updating source code %s with text="%s"', projector.ip, item.code, item.text) self.projectordb.add_source(item) selected = 0 else: selected = self.button_group.checkedId() - log.debug('SourceSelectTabs().accepted() Setting source to %s' % selected) + log.debug('SourceSelectTabs().accepted() Setting source to %s', selected) self.done(selected) -class SourceSelectSingle(QDialog): +class SourceSelectSingle(QtWidgets.QDialog): """ Class for handling selecting the source for the projector to use. Uses single dialog interface. @@ -393,6 +393,7 @@ class SourceSelectSingle(QDialog): title = translate('OpenLP.SourceSelectForm', 'Select Projector Source') self.setObjectName('source_select_single') self.setWindowIcon(build_icon(':/icon/openlp-log-32x32.png')) + self.setWindowTitle(title) self.setModal(True) self.edit = edit @@ -403,12 +404,12 @@ class SourceSelectSingle(QDialog): :param projector: Projector instance to build source list from """ self.projector = projector - self.layout = QFormLayout() if self.edit else QVBoxLayout() + self.layout = QtWidgets.QFormLayout() if self.edit else QtWidgets.QVBoxLayout() self.layout.setObjectName('source_select_tabs_layout') self.layout.setSpacing(10) self.setLayout(self.layout) self.setMinimumWidth(350) - self.button_group = [] if self.edit else QButtonGroup() + self.button_group = [] if self.edit else QtWidgets.QButtonGroup() self.source_text = self.projectordb.get_source_list(projector=projector) keys = list(self.source_text.keys()) keys.sort() @@ -416,7 +417,7 @@ class SourceSelectSingle(QDialog): button_list = [] if self.edit: for key in keys: - item = QLineEdit() + item = QtWidgets.QLineEdit() item.setObjectName('source_key_%s' % key) source_item = self.projectordb.get_source_by_code(code=key, projector_id=self.projector.db_item.id) if source_item is None: @@ -426,10 +427,10 @@ class SourceSelectSingle(QDialog): item.setText(source_item.text) self.layout.addRow(PJLINK_DEFAULT_CODES[key], item) self.button_group.append(item) - self.button_box = QDialogButtonBox(QtWidgets.QDialogButtonBox.Reset | - QtWidgets.QDialogButtonBox.Discard | - QtWidgets.QDialogButtonBox.Ok | - QtWidgets.QDialogButtonBox.Cancel) + self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Reset | + QtWidgets.QDialogButtonBox.Discard | + QtWidgets.QDialogButtonBox.Ok | + QtWidgets.QDialogButtonBox.Cancel) else: for key in keys: source_text = self.projectordb.get_source_by_code(code=key, projector_id=self.projector.db_item.id) @@ -439,8 +440,8 @@ class SourceSelectSingle(QDialog): self.layout.addWidget(button) self.button_group.addButton(button, int(key)) button_list.append(key) - self.button_box = QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | - QtWidgets.QDialogButtonBox.Cancel) + self.button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | + QtWidgets.QDialogButtonBox.Cancel) self.button_box.clicked.connect(self.button_clicked) self.layout.addWidget(self.button_box) self.setMinimumHeight(key_count * 25) @@ -448,7 +449,7 @@ class SourceSelectSingle(QDialog): selected = super(SourceSelectSingle, self).exec() return selected - @pyqtSlot(object) + @QtCore.pyqtSlot(QtWidgets.QAbstractButton) def button_clicked(self, button): """ Checks which button was clicked @@ -471,6 +472,9 @@ class SourceSelectSingle(QDialog): return 100 def delete_sources(self): + """ + Delete all the entries for this projector + """ msg = QtWidgets.QMessageBox() msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector')) msg.setInformativeText(translate('OpenLP.SourceSelectForm', @@ -484,7 +488,7 @@ class SourceSelectSingle(QDialog): self.projectordb.delete_all_objects(ProjectorSource, ProjectorSource.projector_id == self.projector.db_item.id) self.done(100) - @pyqtSlot() + @QtCore.pyqtSlot() def accept_me(self): """ Slot to accept 'OK' button @@ -498,14 +502,14 @@ class SourceSelectSingle(QDialog): continue item = self.projectordb.get_source_by_code(code=code, projector_id=projector.id) if item is None: - log.debug("(%s) Adding new source text %s: %s" % (projector.ip, code, text)) + log.debug('(%s) Adding new source text %s: %s', projector.ip, code, text) item = ProjectorSource(projector_id=projector.id, code=code, text=text) else: item.text = text - log.debug('(%s) Updating source code %s with text="%s"' % (projector.ip, item.code, item.text)) + log.debug('(%s) Updating source code %s with text="%s"', projector.ip, item.code, item.text) self.projectordb.add_source(item) selected = 0 else: selected = self.button_group.checkedId() - log.debug('SourceSelectDialog().accepted() Setting source to %s' % selected) + log.debug('SourceSelectDialog().accepted() Setting source to %s', selected) self.done(selected) diff --git a/tests/functional/openlp_core_common/test_registryproperties.py b/tests/functional/openlp_core_common/test_registryproperties.py index c9cf9c1c0..e38f9e851 100644 --- a/tests/functional/openlp_core_common/test_registryproperties.py +++ b/tests/functional/openlp_core_common/test_registryproperties.py @@ -25,7 +25,8 @@ Test the registry properties from unittest import TestCase from openlp.core.common import Registry, RegistryProperties -from tests.functional import MagicMock + +from tests.functional import MagicMock, patch class TestRegistryProperties(TestCase, RegistryProperties): @@ -36,7 +37,7 @@ class TestRegistryProperties(TestCase, RegistryProperties): """ Create the Register """ - Registry.create() + self.registry = Registry.create() def no_application_test(self): """ @@ -53,7 +54,30 @@ class TestRegistryProperties(TestCase, RegistryProperties): """ # GIVEN an Empty Registry application = MagicMock() + # WHEN the application is registered Registry().register('application', application) + # THEN the application should be none self.assertEqual(self.application, application, 'The application value should match') + + @patch('openlp.core.common.registryproperties.is_win') + def test_get_application_on_windows(self, mocked_is_win): + """ + Set that getting the application object on Windows happens dynamically + """ + # GIVEN an Empty Registry and we're on Windows + mocked_is_win.return_value = True + mock_application = MagicMock() + reg_props = RegistryProperties() + registry = Registry() + + # WHEN the application is accessed + with patch.object(registry, 'get') as mocked_get: + mocked_get.return_value = mock_application + actual_application = reg_props.application + + # THEN the application should be the mock object, and the correct function should have been called + self.assertEqual(mock_application, actual_application, 'The application value should match') + mocked_is_win.assert_called_with() + mocked_get.assert_called_with('application')