From 645f92e7d4c7a6b445d9650400197022c06f7d3e Mon Sep 17 00:00:00 2001 From: Ken Roberts Date: Thu, 16 Oct 2014 11:08:44 -0700 Subject: [PATCH] Change projector wizard to basic edit form --- openlp/core/lib/projector/pjlink1.py | 20 +- openlp/core/ui/__init__.py | 4 +- openlp/core/ui/projector/editform.py | 262 +++++++++++++ openlp/core/ui/projector/manager.py | 21 +- openlp/core/ui/projector/wizard.py | 557 --------------------------- 5 files changed, 294 insertions(+), 570 deletions(-) create mode 100644 openlp/core/ui/projector/editform.py delete mode 100644 openlp/core/ui/projector/wizard.py diff --git a/openlp/core/lib/projector/pjlink1.py b/openlp/core/lib/projector/pjlink1.py index 6cf50cb07..b68300859 100644 --- a/openlp/core/lib/projector/pjlink1.py +++ b/openlp/core/lib/projector/pjlink1.py @@ -195,10 +195,22 @@ class PJLink1(QTcpSocket): Cleanups when thread is stopped. """ log.debug('(%s) Thread stopped' % self.ip) - self.connected.disconnect(self.check_login) - self.disconnected.disconnect(self.disconnect_from_host) - self.error.disconnect(self.get_error) - self.projectorReceivedData.disconnect(self._send_command) + try: + self.connected.disconnect(self.check_login) + except TypeError: + pass + try: + self.disconnected.disconnect(self.disconnect_from_host) + except TypeError: + pass + try: + self.error.disconnect(self.get_error) + except TypeError: + pass + try: + self.projectorReceivedData.disconnect(self._send_command) + except TypeError: + pass self.disconnect_from_host() self.deleteLater() self.i_am_running = False diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 9bece8dd9..4d9bf2c40 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -125,12 +125,12 @@ from .mediadockmanager import MediaDockManager from .servicemanager import ServiceManager from .thememanager import ThemeManager from .projector.manager import ProjectorManager -from .projector.wizard import ProjectorWizard from .projector.tab import ProjectorTab +from .projector.editform import ProjectorEditForm __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeForm', 'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm', 'FirstTimeForm', 'FirstTimeLanguageForm', 'Display', 'ServiceNoteForm', 'ThemeLayoutForm', 'FileRenameForm', 'StartTimeForm', 'MainDisplay', 'SlideController', 'DisplayController', 'GeneralTab', 'ThemesTab', 'AdvancedTab', 'PluginForm', 'FormattingTagForm', 'ShortcutListForm', 'FormattingTagController', 'SingleColumnTableWidget', - 'ProjectorManager', 'ProjectorTab', 'ProjectorWizard'] + 'ProjectorManager', 'ProjectorTab',' ProjectorEditForm'] diff --git a/openlp/core/ui/projector/editform.py b/openlp/core/ui/projector/editform.py new file mode 100644 index 000000000..b40a95cfa --- /dev/null +++ b/openlp/core/ui/projector/editform.py @@ -0,0 +1,262 @@ + +# -*- 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, Ken Roberts, 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 # +############################################################################### +""" +The :mod: projectormanager` module provides the functions for + the display/control of Projectors. +""" + +import logging +log = logging.getLogger(__name__) +log.debug('editform loaded') + +from PyQt4 import QtCore, QtGui +from PyQt4.QtCore import QObject, pyqtSlot, pyqtSignal +from PyQt4.QtGui import QDialog, QFormLayout, QPlainTextEdit, QPushButton, QVBoxLayout, \ + QLineEdit, QDialogButtonBox, QHBoxLayout, QLabel, QGridLayout + +from openlp.core.common import translate, verify_ip_address +from openlp.core.lib import build_icon +from openlp.core.lib.projector.db import Projector +from openlp.core.lib.projector.constants import PJLINK_PORT + +class Ui_ProjectorEditForm(object): + """ + The :class:`~opelp.core.lib.ui.projector.editform.Ui_ProjectorEdiForm` class defines + the user interface for the ProjectorEditForm dialog. + """ + def setupUi(self, edit_projector_dialog): + """ + Create the interface layout. + """ + edit_projector_dialog.setObjectName('edit_projector_dialog') + edit_projector_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo-32x32.png')) + edit_projector_dialog.setMinimumWidth(400) + edit_projector_dialog.setModal(True) + # Define the basic layout + self.dialog_layout = QGridLayout(edit_projector_dialog) + self.dialog_layout.setObjectName('dialog_layout') + self.dialog_layout.setSpacing(8) + self.dialog_layout.setContentsMargins(8,8,8,8) + # IP Address + self.ip_label = QLabel(edit_projector_dialog) + self.ip_label.setObjectName('projector_edit_ip_label') + self.ip_text = QLineEdit(edit_projector_dialog) + self.ip_text.setObjectName('projector_edit_ip_text') + self.dialog_layout.addWidget(self.ip_label, 0, 0) + self.dialog_layout.addWidget(self.ip_text, 0, 1) + # Port number + self.port_label = QLabel(edit_projector_dialog) + self.port_label.setObjectName('projector_edit_ip_label') + self.port_text = QLineEdit(edit_projector_dialog) + self.port_text.setObjectName('projector_edit_port_text') + self.dialog_layout.addWidget(self.port_label, 1, 0) + self.dialog_layout.addWidget(self.port_text, 1, 1) + # PIN + self.pin_label = QLabel(edit_projector_dialog) + self.pin_label.setObjectName('projector_edit_pin_label') + self.pin_text = QLineEdit(edit_projector_dialog) + self.pin_label.setObjectName('projector_edit_pin_text') + self.dialog_layout.addWidget(self.pin_label, 2, 0) + self.dialog_layout.addWidget(self.pin_text, 2, 1) + # Name + self.name_label = QLabel(edit_projector_dialog) + self.name_label.setObjectName('projector_edit_name_label') + self.name_text = QLineEdit(edit_projector_dialog) + self.name_text.setObjectName('projector_edit_name_text') + self.dialog_layout.addWidget(self.name_label, 3, 0) + self.dialog_layout.addWidget(self.name_text, 3, 1) + # Location + self.location_label = QLabel(edit_projector_dialog) + self.location_label.setObjectName('projector_edit_location_label') + self.location_text = QLineEdit(edit_projector_dialog) + self.location_text.setObjectName('projector_edit_location_text') + self.dialog_layout.addWidget(self.location_label, 4, 0) + self.dialog_layout.addWidget(self.location_text, 4, 1) + # Notes + self.notes_label = QLabel(edit_projector_dialog) + self.notes_label.setObjectName('projector_edit_notes_label') + self.notes_text = QPlainTextEdit(edit_projector_dialog) + self.notes_text.setObjectName('projector_edit_notes_text') + self.dialog_layout.addWidget(self.notes_label, 5, 0, alignment=QtCore.Qt.AlignTop) + self.dialog_layout.addWidget(self.notes_text, 5, 1) + # Time for the buttons + self.button_box = QDialogButtonBox(QDialogButtonBox.Help | + QDialogButtonBox.Save | + QDialogButtonBox.Cancel) + self.dialog_layout.addWidget(self.button_box, 8, 0, 1, 2) + + def retranslateUi(self, edit_projector_dialog): + if self.projector.port is None: + title = translate('OpenLP.ProjectorEditForm', 'Add New Projector') + self.projector.port = PJLINK_PORT + self.new_projecor = True + else: + title = translate('OpenLP.ProjectorEditForm', 'Edit Projector') + self.new_projector = False + edit_projector_dialog.setWindowTitle(title) + self.ip_label.setText(translate('OpenLP.ProjetorEditForm', 'IP Address')) + self.ip_text.setText(self.projector.ip) + self.port_label.setText(translate('OpenLP.ProjectorEditForm', 'Port Number')) + self.port_text.setText(str(self.projector.port)) + self.pin_label.setText(translate('OpenLP.ProjectorEditForm', 'PIN')) + self.pin_text.setText(self.projector.pin) + self.name_label.setText(translate('OpenLP.ProjectorEditForm', 'Name')) + self.name_text.setText(self.projector.name) + self.location_label.setText(translate('OpenLP.ProjectorEditForm', 'Location')) + self.location_text.setText(self.projector.location) + self.notes_label.setText(translate('OpenLP.ProjectorEditForm', 'Notes')) + self.notes_text.insertPlainText(self.projector.notes) + +class ProjectorEditForm(QDialog, Ui_ProjectorEditForm): + """ + Class to add or edit a projector entry in the database. + + Fields that are editable: + ip = Column(String(100)) + port = Column(String(8)) + pin = Column(String(20)) + name = Column(String(20)) + location = Column(String(30)) + notes = Column(String(200)) + """ + newProjector = pyqtSignal(str) + editProjector = pyqtSignal(object) + + def __init__(self, parent=None, projectordb=None): + super(ProjectorEditForm, self).__init__(parent=parent) + self.projectordb = projectordb + self.setupUi(self) + self.button_box.accepted.connect(self.accept_me) + self.button_box.helpRequested.connect(self.help_me) + self.button_box.rejected.connect(self.cancel_me) + + def exec_(self, projector=Projector()): + self.projector = projector + self.new_projector = False + self.retranslateUi(self) + reply = QDialog.exec_(self) + self.projector = None + return reply + + @pyqtSlot() + def accept_me(self): + """ + Validate input before accepting input. + """ + log.debug('accept_me() signal received') + if len(self.name_text.text().strip()) < 1: + QtGui.QMessageBox.warning(self, + translate('OpenLP.ProjectorEdit', 'Name Not Set'), + translate('OpenLP.ProjectorEdit', + 'You must enter a name for this entry.
' + 'Please enter a new name for this entry.')) + valid = False + return + name = self.name_text.text().strip() + record = self.projectordb.get_projector_by_name(name) + if record is not None and record.id != self.projector.id: + QtGui.QMessageBox.warning(self, + translate('OpenLP.ProjectorEdit', 'Duplicate Name'), + translate('OpenLP.ProjectorEdit', + 'There is already an entry with name "%s" in ' + 'the database as ID "%s".
' + 'Please enter a different name.' % (name, record.id))) + valid = False + return + adx = self.ip_text.text() + valid = verify_ip_address(adx) + if valid: + ip = self.projectordb.get_projector_by_ip(adx) + if ip is None: + valid = True + self.new_projector = True + elif ip.id != self.projector.id: + QtGui.QMessageBox.warning(self, + translate('OpenLP.ProjectorWizard', 'Duplicate IP Address'), + translate('OpenLP.ProjectorWizard', + 'IP address "%s"
is already in the database as ID %s.' + '

Please Enter a different IP address.' % (adx, ip.id))) + valid = False + return + else: + QtGui.QMessageBox.warning(self, + translate('OpenLP.ProjectorWizard', 'Invalid IP Address'), + translate('OpenLP.ProjectorWizard', + 'IP address "%s"
is not a valid IP address.' + '

Please enter a valid IP address.' % adx)) + valid = False + return + port = int(self.port_text.text()) + if port < 1000 or port > 32767: + QtGui.QMessageBox.warning(self, + translate('OpenLP.ProjectorWizard', 'Invalid Port Number'), + translate('OpenLP.ProjectorWizard', + 'Port numbers below 1000 are reserved for admin use only, ' + '
and port numbers above 32767 are not currently usable.' + '

Please enter a valid port number between ' + ' 1000 and 32767.' + '

Default PJLink port is %s' % PJLINK_PORT)) + valid = False + if valid: + self.projector.ip = self.ip_text.text() + self.projector.pin = self.pin_text.text() + self.projector.port = int(self.port_text.text()) + self.projector.name = self.name_text.text() + self.projector.location = self.location_text.text() + self.projector.notes = self.notes_text.toPlainText() + if self.new_projector: + saved = self.projectordb.add_projector(self.projector) + else: + saved = self.projectordb.update_projector(self.projector) + if not saved: + QtGui.QMessageBox.warning(self, + translate('OpenLP.ProjectorEditForm', 'Database Error'), + translate('OpenLP.ProjectorEditForm', + 'There was an error saving projector ' + 'information. See the log for the error')) + return saved + if self.new_projector: + self.newProjector.emit(adx) + else: + self.editProjector.emit(self.projector) + self.close() + + def help_me(self): + """ + Show a help message about the input fields. + """ + log.debug('help_me() signal received') + + def cancel_me(self): + """ + Cancel button clicked - just close. + """ + log.debug('cancel_me() signal received') + self.close() diff --git a/openlp/core/ui/projector/manager.py b/openlp/core/ui/projector/manager.py index 9330b66f3..eecf79025 100644 --- a/openlp/core/ui/projector/manager.py +++ b/openlp/core/ui/projector/manager.py @@ -45,7 +45,8 @@ from openlp.core.lib.ui import create_widget_action from openlp.core.lib.projector.constants import * from openlp.core.lib.projector.db import ProjectorDB from openlp.core.lib.projector.pjlink1 import PJLink1 -from openlp.core.ui.projector.wizard import ProjectorWizard +#from openlp.core.ui.projector.wizard import ProjectorWizard +from openlp.core.ui.projector.editform import ProjectorEditForm # Dict for matching projector status to display icon STATUS_ICONS = {S_NOT_CONNECTED: ':/projector/projector_item_disconnect.png', @@ -255,9 +256,15 @@ class ProjectorManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ProjectorMa def bootstrap_post_set_up(self): self.load_projectors() + ''' self.projector_form = ProjectorWizard(self, projectordb=self.projectordb) self.projector_form.edit_page.newProjector.connect(self.add_projector_from_wizard) self.projector_form.edit_page.editProjector.connect(self.edit_projector_from_wizard) + ''' + self.projector_form = ProjectorEditForm(self, projectordb=self.projectordb) + self.projector_form.newProjector.connect(self.add_projector_from_wizard) + self.projector_form.editProjector.connect(self.edit_projector_from_wizard) + self.projector_list_widget.itemSelectionChanged.connect(self.update_icons) def context_menu(self, point): @@ -446,28 +453,28 @@ class ProjectorManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ProjectorMa return try: projector.link.projectorNetwork.disconnect(self.update_status) - except TypeError: + except (AttributeError, TypeError): pass try: projector.link.changeStatus.disconnect(self.update_status) - except TypeError: + except (AttributeError, TypeError): pass try: projector.link.authentication_error.disconnect(self.authentication_error) - except TypeError: + except (AttributeError, TypeError): pass try: projector.link.no_authentication_error.disconnect(self.no_authentication_error) - except TypeError: + except (AttributeError, TypeError): pass try: projector.link.projectorUpdateIcons.disconnect(self.update_icons) - except TypeError: + except (AttributeError, TypeError): pass try: projector.timer.stop() projector.timer.timeout.disconnect(projector.link.poll_loop) - except TypeError: + except (AttributeError, TypeError): pass projector.thread.quit() new_list = [] diff --git a/openlp/core/ui/projector/wizard.py b/openlp/core/ui/projector/wizard.py deleted file mode 100644 index a43f8a3af..000000000 --- a/openlp/core/ui/projector/wizard.py +++ /dev/null @@ -1,557 +0,0 @@ -# -*- 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, Ken Roberts, 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 # -############################################################################### -""" -The :mod:`projector.projectorwizard` module handles the GUI Wizard for adding - new projetor entries. -""" - -import logging -log = logging.getLogger(__name__) -log.debug('projectorwizard loaded') - -from ipaddress import IPv4Address, IPv6Address, AddressValueError - -from PyQt4 import QtCore, QtGui -from PyQt4.QtCore import pyqtSlot, pyqtSignal - -from openlp.core.common import RegistryProperties, translate, is_macosx -from openlp.core.lib import build_icon - -from openlp.core.common import verify_ip_address -from openlp.core.lib.projector.db import ProjectorDB, Projector -from openlp.core.lib.projector.pjlink1 import PJLink1 -from openlp.core.lib.projector.constants import * - -PAGE_COUNT = 4 -(ConnectWelcome, - ConnectHost, - ConnectEdit, - ConnectFinish) = range(PAGE_COUNT) - -PAGE_NEXT = {ConnectWelcome: ConnectHost, - ConnectHost: ConnectEdit, - ConnectEdit: ConnectFinish, - ConnectFinish: -1} - - -class ProjectorWizard(QtGui.QWizard, RegistryProperties): - """ - Wizard for adding/editing projector entries. - """ - def __init__(self, parent, projectordb): - log.debug('__init__()') - super().__init__(parent) - self.db = projectordb - self.projector = None - self.setObjectName('projector_wizard') - self.setWindowIcon(build_icon(u':/icon/openlp-logo.svg')) - self.setModal(True) - if is_macosx(): - self.setPixmap(QtGui.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png')) - else: - self.setWizardStyle(QtGui.QWizard.ModernStyle) - self.setMinimumSize(650, 550) - self.setOption(QtGui.QWizard.NoBackButtonOnStartPage) - self.spacer = QtGui.QSpacerItem(10, 0, - QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Minimum) - self.setOption(self.HaveHelpButton, True) - self.welcome_page = ConnectWelcomePage(self, ConnectWelcome) - self.host_page = ConnectHostPage(self, ConnectHost) - self.edit_page = ConnectEditPage(self, ConnectEdit) - self.finish_page = ConnectFinishPage(self, ConnectFinish) - self.setPage(self.welcome_page.pageId, self.welcome_page) - self.setPage(self.host_page.pageId, self.host_page) - self.setPage(self.edit_page.pageId, self.edit_page) - self.setPage(self.finish_page.pageId, self.finish_page) - self.registerFields() - self.retranslateUi() - # Connect signals - self.button(QtGui.QWizard.HelpButton).clicked.connect(self.showHelp) - log.debug('ProjectorWizard() started') - - def exec_(self, projector=None): - """ - Override function to determine whether we are called to add a new - projector or edit an old projector. - - :param projector: Projector instance - :returns: None - """ - self.projector = projector - if self.projector is None: - log.debug('ProjectorWizard() Adding new projector') - self.setWindowTitle(translate('OpenLP.ProjectorWizard', - 'New Projector Wizard')) - self.setStartId(ConnectWelcome) - else: - log.debug('ProjectorWizard() Editing existing projector') - self.setWindowTitle(translate('OpenLP.ProjectorWizard', - 'Edit Projector Wizard')) - self.setStartId(ConnectEdit) - self.restart() - saved = QtGui.QWizard.exec_(self) - self.projector = None - return saved - - def registerFields(self): - """ - Register selected fields for use by all pages. - """ - self.host_page.registerField('ip_number*', self.host_page.ip_number_text) - self.edit_page.registerField('pjlink_port', self.host_page.pjlink_port_text) - self.edit_page.registerField('pjlink_pin', self.host_page.pjlink_pin_text) - self.edit_page.registerField('projector_name*', self.edit_page.name_text) - self.edit_page.registerField('projector_location', self.edit_page.location_text) - self.edit_page.registerField('projector_notes', self.edit_page.notes_text, 'plainText') - self.edit_page.registerField('projector_make', self.host_page.manufacturer_text) - self.edit_page.registerField('projector_model', self.host_page.model_text) - - @pyqtSlot() - def showHelp(self): - """ - Show the pop-up help message. - """ - page = self.currentPage() - try: - help_page = page.help_ - except: - help_page = self.no_help - QtGui.QMessageBox.information(self, self.title_help, help_page) - - def retranslateUi(self): - """ - Fixed-text strings used for translations - """ - self.title_help = translate('OpenLP.ProjectorWizard', 'Projector Wizard Help') - self.no_help = translate('OpenLP.ProjectorWizard', - 'Sorry - no help available for this page.') - self.welcome_page.title_label.setText('%s' % - translate('OpenLP.ProjectorWizard', - 'Welcome to the
Projector Wizard')) - self.welcome_page.information_label.setText(translate('OpenLP.ProjectorWizard', 'This wizard will help you to ' - 'create and edit your Projector control.

' - 'Press "Next" button below to continue.')) - self.host_page.setTitle(translate('OpenLP.ProjectorWizard', 'Host Address')) - self.host_page.setSubTitle(translate('OpenLP.ProjectorWizard', - 'Enter the IP address, port, and PIN used to conenct to the projector.')) - self.host_page.help_ = translate('OpenLP.ProjectorWizard', - 'IP Address: The IP address of the projector to connect to.
' - 'Port: The port number. Default is 4352.
' - 'PIN: If needed, enter the PIN access code for the projector.
' - '
Once the IP address has been verified as correct and not ' - 'in the database, the rest of the information can be added on the next page.') - self.host_page.ip_number_label.setText(translate('OpenLP.ProjectorWizard', 'IP Address: ')) - self.host_page.pjlink_port_label.setText(translate('OpenLP.ProjectorWizard', 'Port: ')) - self.host_page.pjlink_pin_label.setText(translate('OpenLP.ProjectorWizard', 'PIN: ')) - self.edit_page.setTitle(translate('OpenLP.ProjectorWizard', 'Add/Edit Projector Information')) - self.edit_page.setSubTitle(translate('OpenLP.ProjectorWizard', - 'Enter the information below in the left panel for the projector.')) - self.edit_page.help_ = translate('OpenLP.ProjectorWizard', - 'Please enter the following information:' - '

Port: The network port to use. Default is %s.' - '

PIN: The PJLink access PIN. Only required if ' - 'PJLink PIN is set in projector.

Name: ' - 'A unique name you want to give to this projector entry. 20 characters max. ' - '

Location: The location of the projector. 30 characters ' - 'max.

Notes: Any notes you want to add about this ' - 'projector. 200 characters max.

The "Manufacturer" and "Model" ' - 'information will only be available if the projector is connected to the ' - 'network and can be accessed while running this wizard. ' - '(Currently not implemented)' % PJLINK_PORT) - self.edit_page.ip_number_label.setText(translate('OpenLP.ProjectorWizard', 'IP Address: ')) - self.edit_page.pjlink_port_label.setText(translate('OpenLP.ProjectorWizard', 'Port: ')) - self.edit_page.pjlink_pin_label.setText(translate('OpenLP.ProjectorWizard', 'PIN: ')) - self.edit_page.name_label.setText(translate('OpenLP.ProjectorWizard', 'Name: ')) - self.edit_page.location_label.setText(translate('OpenLP.ProjectorWizard', 'Location: ')) - self.edit_page.notes_label.setText(translate('OpenLP.ProjectorWizard', 'Notes: ')) - self.edit_page.projector_make_label.setText(translate('OpenLP.ProjectorWizard', 'Manufacturer: ')) - self.edit_page.projector_model_label.setText(translate('OpenLP.ProjectorWizard', 'Model: ')) - self.finish_page.title_label.setText('%s' % - translate('OpenLP.ProjectorWizard', 'Projector Added')) - self.finish_page.information_label.setText(translate('OpenLP.ProjectorWizard', - '
Have fun with your new projector.')) - - -class ConnectBase(QtGui.QWizardPage): - """ - Base class for the projector wizard pages. - """ - def __init__(self, parent=None, page=None): - super().__init__(parent) - self.pageId = page - - def nextId(self): - """ - Returns next page to show. - """ - return PAGE_NEXT[self.pageId] - - def setVisible(self, visible): - """ - Set buttons for bottom of page. - """ - QtGui.QWizardPage.setVisible(self, visible) - if not is_macosx(): - if visible: - try: - self.myCustomButton() - except: - try: - self.wizard().setButtonLayout(self.myButtons) - except: - self.wizard().setButtonLayout([QtGui.QWizard.Stretch, - QtGui.QWizard.BackButton, - QtGui.QWizard.NextButton, - QtGui.QWizard.CancelButton]) - - -class ConnectWelcomePage(ConnectBase): - """ - Splash screen - """ - def __init__(self, parent, page): - super().__init__(parent, page) - if is_macosx(): - self.setPixmap(QtGui.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png')) - else: - self.setPixmap(QtGui.QWizard.WatermarkPixmap, - QtGui.QPixmap(':/wizards/wizard_createprojector.png')) - self.setObjectName('welcome_page') - self.myButtons = [QtGui.QWizard.Stretch, - QtGui.QWizard.NextButton] - self.layout = QtGui.QVBoxLayout(self) - self.layout.setObjectName('layout') - self.title_label = QtGui.QLabel(self) - self.title_label.setObjectName('title_label') - self.layout.addWidget(self.title_label) - self.layout.addSpacing(40) - self.information_label = QtGui.QLabel(self) - self.information_label.setWordWrap(True) - self.information_label.setObjectName('information_label') - self.layout.addWidget(self.information_label) - self.layout.addStretch() - - -class ConnectHostPage(ConnectBase): - """ - Get initial information. - """ - def __init__(self, parent, page): - super().__init__(parent, page) - self.setObjectName('host_page') - self.myButtons = [QtGui.QWizard.HelpButton, - QtGui.QWizard.Stretch, - QtGui.QWizard.NextButton, - QtGui.QWizard.CancelButton] - self.hostPageLayout = QtGui.QHBoxLayout(self) - self.hostPageLayout.setObjectName('layout') - # Projector DB information - self.localAreaBox = QtGui.QGroupBox(self) - self.localAreaBox.setObjectName('host_local_area_box') - self.localAreaForm = QtGui.QFormLayout(self.localAreaBox) - self.localAreaForm.setObjectName('host_local_area_form') - self.ip_number_label = QtGui.QLabel(self.localAreaBox) - self.ip_number_label.setObjectName('host_ip_number_label') - self.ip_number_text = QtGui.QLineEdit(self.localAreaBox) - self.ip_number_text.setObjectName('host_ip_number_text') - self.localAreaForm.addRow(self.ip_number_label, self.ip_number_text) - self.pjlink_port_label = QtGui.QLabel(self.localAreaBox) - self.pjlink_port_label.setObjectName('host_pjlink_port_label') - self.pjlink_port_text = QtGui.QLineEdit(self.localAreaBox) - self.pjlink_port_text.setMaxLength(5) - self.pjlink_port_text.setText(str(PJLINK_PORT)) - self.pjlink_port_text.setObjectName('host_pjlink_port_text') - self.localAreaForm.addRow(self.pjlink_port_label, self.pjlink_port_text) - self.pjlink_pin_label = QtGui.QLabel(self.localAreaBox) - self.pjlink_pin_label.setObjectName('host_pjlink_pin_label') - self.pjlink_pin_text = QtGui.QLineEdit(self.localAreaBox) - self.pjlink_pin_text.setObjectName('host_pjlink_pin_text') - self.localAreaForm.addRow(self.pjlink_pin_label, self.pjlink_pin_text) - self.hostPageLayout.addWidget(self.localAreaBox) - self.manufacturer_text = QtGui.QLineEdit(self) - self.manufacturer_text.setVisible(False) - self.model_text = QtGui.QLineEdit(self) - self.model_text.setVisible(False) - - def validatePage(self): - """ - Validate IP number/FQDN before continuing to next page. - """ - adx = self.wizard().field('ip_number') - port = self.wizard().field('pjlink_port') - pin = self.wizard().field('pjlink_pin') - log.debug('ip="%s" port="%s" pin="%s"' % (adx, port, pin)) - valid = verify_ip_address(adx) - if valid: - ip = self.wizard().db.get_projector_by_ip(adx) - if ip is None: - valid = True - else: - QtGui.QMessageBox.warning(self, - translate('OpenLP.ProjectorWizard', 'Duplicate IP Address'), - translate('OpenLP.ProjectorWizard', - 'IP address "%s"
is already in the database as ID %s.' - '

Please Enter a different IP address.' % (adx, ip.id))) - valid = False - else: - QtGui.QMessageBox.warning(self, - translate('OpenLP.ProjectorWizard', 'Invalid IP Address'), - translate('OpenLP.ProjectorWizard', - 'IP address "%s"
is not a valid IP address.' - '

Please enter a valid IP address.' % adx)) - valid = False - """ - TODO - Future plan to retrieve manufacture/model input source information. Not implemented yet. - new = PJLink(host=adx, port=port, pin=pin if pin.strip() != '' else None) - if new.connect(): - mfg = new.get_manufacturer() - log.debug('Setting manufacturer_text to %s' % mfg) - self.manufacturer_text.setText(mfg) - model = new.get_model() - log.debug('Setting model_text to %s' % model) - self.model_text.setText(model) - else: - if new.status_error == E_AUTHENTICATION: - QtGui.QMessageBox.warning(self, - translate('OpenLP.ProjectorWizard', 'Requires Authorization'), - translate('OpenLP.ProjectorWizard', - 'Projector requires authorization and either PIN not set ' - 'or invalid PIN set.' - '
Enter a valid PIN before hitting "NEXT"') - ) - elif new.status_error == E_NO_AUTHENTICATION: - QtGui.QMessageBox.warning(self, - translate('OpenLP.ProjectorWizard', 'No Authorization Required'), - translate('OpenLP.ProjectorWizard', - 'Projector does not require authorization and PIN set.' - '
Remove PIN entry before hitting "NEXT"') - ) - valid = False - new.disconnect() - del(new) - """ - return valid - - -class ConnectEditPage(ConnectBase): - """ - Full information page. - """ - newProjector = QtCore.pyqtSignal(str) - editProjector = QtCore.pyqtSignal(object) - - def __init__(self, parent, page): - super().__init__(parent, page) - self.setObjectName('edit_page') - self.editPageLayout = QtGui.QHBoxLayout(self) - self.editPageLayout.setObjectName('layout') - # Projector DB information - self.localAreaBox = QtGui.QGroupBox(self) - self.localAreaBox.setObjectName('edit_local_area_box') - self.localAreaForm = QtGui.QFormLayout(self.localAreaBox) - self.localAreaForm.setObjectName('edit_local_area_form') - self.ip_number_label = QtGui.QLabel(self.localAreaBox) - self.ip_number_label.setObjectName('edit_ip_number_label') - self.ip_number_text = QtGui.QLineEdit(self.localAreaBox) - self.ip_number_text.setObjectName('edit_ip_number_text') - self.localAreaForm.addRow(self.ip_number_label, self.ip_number_text) - self.pjlink_port_label = QtGui.QLabel(self.localAreaBox) - self.pjlink_port_label.setObjectName('edit_pjlink_port_label') - self.pjlink_port_text = QtGui.QLineEdit(self.localAreaBox) - self.pjlink_port_text.setMaxLength(5) - self.pjlink_port_text.setObjectName('edit_pjlink_port_text') - self.localAreaForm.addRow(self.pjlink_port_label, self.pjlink_port_text) - self.pjlink_pin_label = QtGui.QLabel(self.localAreaBox) - self.pjlink_pin_label.setObjectName('pjlink_pin_label') - self.pjlink_pin_text = QtGui.QLineEdit(self.localAreaBox) - self.pjlink_pin_text.setObjectName('pjlink_pin_text') - self.localAreaForm.addRow(self.pjlink_pin_label, self.pjlink_pin_text) - self.name_label = QtGui.QLabel(self.localAreaBox) - self.name_label.setObjectName('name_label') - self.name_text = QtGui.QLineEdit(self.localAreaBox) - self.name_text.setObjectName('name_label') - self.name_text.setMaxLength(20) - self.localAreaForm.addRow(self.name_label, self.name_text) - self.location_label = QtGui.QLabel(self.localAreaBox) - self.location_label.setObjectName('location_label') - self.location_text = QtGui.QLineEdit(self.localAreaBox) - self.location_text.setObjectName('location_text') - self.location_text.setMaxLength(30) - self.localAreaForm.addRow(self.location_label, self.location_text) - self.notes_label = QtGui.QLabel(self.localAreaBox) - self.notes_label.setObjectName('notes_label') - self.notes_text = QtGui.QPlainTextEdit(self.localAreaBox) - self.notes_text.setObjectName('notes_text') - self.localAreaForm.addRow(self.notes_label, self.notes_text) - self.editPageLayout.addWidget(self.localAreaBox) - # Projector retrieved information - self.remoteAreaBox = QtGui.QGroupBox(self) - self.remoteAreaBox.setObjectName('edit_remote_area_box') - self.remoteAreaForm = QtGui.QFormLayout(self.remoteAreaBox) - self.remoteAreaForm.setObjectName('edit_remote_area_form') - self.projector_make_label = QtGui.QLabel(self.remoteAreaBox) - self.projector_make_label.setObjectName('projector_make_label') - self.projector_make_text = QtGui.QLabel(self.remoteAreaBox) - self.projector_make_text.setObjectName('projector_make_text') - self.remoteAreaForm.addRow(self.projector_make_label, self.projector_make_text) - self.projector_model_label = QtGui.QLabel(self.remoteAreaBox) - self.projector_model_label.setObjectName('projector_model_text') - self.projector_model_text = QtGui.QLabel(self.remoteAreaBox) - self.projector_model_text.setObjectName('projector_model_text') - self.remoteAreaForm.addRow(self.projector_model_label, self.projector_model_text) - self.editPageLayout.addWidget(self.remoteAreaBox) - - def initializePage(self): - """ - Fill in the blanks for information from previous page/projector to edit. - """ - if self.wizard().projector is not None: - log.debug('ConnectEditPage.initializePage() Editing existing projector') - self.ip_number_text.setText(self.wizard().projector.ip) - self.pjlink_port_text.setText(str(self.wizard().projector.port)) - self.pjlink_pin_text.setText(self.wizard().projector.pin) - self.name_text.setText(self.wizard().projector.name) - self.location_text.setText(self.wizard().projector.location) - self.notes_text.insertPlainText(self.wizard().projector.notes) - self.myButtons = [QtGui.QWizard.HelpButton, - QtGui.QWizard.Stretch, - QtGui.QWizard.FinishButton, - QtGui.QWizard.CancelButton] - else: - log.debug('Retrieving information from host page') - self.ip_number_text.setText(self.wizard().field('ip_number')) - self.pjlink_port_text.setText(self.wizard().field('pjlink_port')) - self.pjlink_pin_text.setText(self.wizard().field('pjlink_pin')) - make = self.wizard().field('projector_make') - model = self.wizard().field('projector_model') - if make is None or make.strip() == '': - self.projector_make_text.setText(translate('OpenLP.ProjectorWizard', - 'Unavailable ')) - else: - self.projector_make_text.setText(make) - if model is None or model.strip() == '': - self.projector_model_text.setText(translate('OpenLP.ProjectorWizard', - 'Unavailable ')) - else: - self.projector_model_text.setText(model) - self.myButtons = [QtGui.QWizard.HelpButton, - QtGui.QWizard.Stretch, - QtGui.QWizard.BackButton, - QtGui.QWizard.NextButton, - QtGui.QWizard.CancelButton] - - def validatePage(self): - """ - Last verification if editiing existing entry in case of IP change. Add entry to DB. - """ - log.debug('ConnectEditPage().validatePage()') - if self.wizard().projector is not None: - ip = self.ip_number_text.text() - port = self.pjlink_port_text.text() - name = self.name_text.text() - location = self.location_text.text() - notes = self.notes_text.toPlainText() - pin = self.pjlink_pin_text.text() - log.debug('edit-page() Verifying info : ip="%s"' % ip) - valid = verify_ip_address(ip) - if not valid: - QtGui.QMessageBox.warning(self, - translate('OpenLP.ProjectorWizard', 'Invalid IP Address'), - translate('OpenLP.ProjectorWizard', - 'IP address "%s"
is not a valid IP address.' - '

Please enter a valid IP address.' % ip)) - return False - log.debug('Saving edited projector %s' % ip) - self.wizard().projector.ip = ip - self.wizard().projector.port = port - self.wizard().projector.name = name - self.wizard().projector.location = location - self.wizard().projector.notes = notes - self.wizard().projector.pin = pin - saved = self.wizard().db.update_projector(self.wizard().projector) - if not saved: - QtGui.QMessageBox.error(self, translate('OpenLP.ProjectorWizard', 'Database Error'), - translate('OpenLP.ProjectorWizard', 'There was an error saving projector ' - 'information. See the log for the error')) - return False - self.editProjector.emit(self.wizard().projector) - else: - projector = Projector(ip=self.wizard().field('ip_number'), - port=self.wizard().field('pjlink_port'), - name=self.wizard().field('projector_name'), - location=self.wizard().field('projector_location'), - notes=self.wizard().field('projector_notes'), - pin=self.wizard().field('pjlink_pin')) - log.debug('Adding new projector %s' % projector.ip) - if self.wizard().db.get_projector_by_ip(projector.ip) is None: - saved = self.wizard().db.add_projector(projector) - if not saved: - QtGui.QMessageBox.error(self, translate('OpenLP.ProjectorWizard', 'Database Error'), - translate('OpenLP.ProjectorWizard', 'There was an error saving projector ' - 'information. See the log for the error')) - return False - self.newProjector.emit('%s' % projector.ip) - return True - - def nextId(self): - """ - Returns the next page ID if new entry or end of wizard if editing entry. - """ - if self.wizard().projector is None: - return PAGE_NEXT[self.pageId] - else: - return -1 - - -class ConnectFinishPage(ConnectBase): - """ - Buh-Bye page - """ - def __init__(self, parent, page): - super().__init__(parent, page) - self.setObjectName('connect_finish_page') - if is_macosx(): - self.setPixmap(QtGui.QWizard.BackgroundPixmap, QtGui.QPixmap(':/wizards/openlp-osx-wizard.png')) - else: - self.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap(':/wizards/wizard_createprojector.png')) - self.myButtons = [QtGui.QWizard.Stretch, - QtGui.QWizard.FinishButton] - self.isFinalPage() - self.layout = QtGui.QVBoxLayout(self) - self.layout.setObjectName('layout') - self.title_label = QtGui.QLabel(self) - self.title_label.setObjectName('title_label') - self.layout.addWidget(self.title_label) - self.layout.addSpacing(40) - self.information_label = QtGui.QLabel(self) - self.information_label.setWordWrap(True) - self.information_label.setObjectName('information_label') - self.layout.addWidget(self.information_label) - self.layout.addStretch()