30
30
from PyQt5 import QtCore, QtGui, QtWidgets
32
32
from openlp.core.common.i18n import translate
33
from openlp.core.ui.icons import UiIcons
34
33
from openlp.core.common.mixins import LogMixin, RegistryProperties
35
from openlp.core.common.registry import RegistryBase
34
from openlp.core.common.registry import Registry, RegistryBase
36
35
from openlp.core.common.settings import Settings
37
36
from openlp.core.lib.ui import create_widget_action
38
37
from openlp.core.projectors import DialogSourceStyle
39
from openlp.core.projectors.constants import E_AUTHENTICATION, E_ERROR, E_NETWORK, E_NOT_CONNECTED, \
40
E_SOCKET_TIMEOUT, E_UNKNOWN_SOCKET_ERROR, S_CONNECTED, S_CONNECTING, S_COOLDOWN, S_INITIALIZE, \
41
S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP, PJLINK_PORT, STATUS_CODE, STATUS_MSG, QSOCKET_STATE
38
from openlp.core.projectors.constants import E_AUTHENTICATION, E_ERROR, E_NETWORK, E_NOT_CONNECTED, E_SOCKET_TIMEOUT,\
39
E_UNKNOWN_SOCKET_ERROR, QSOCKET_STATE, S_CONNECTED, S_CONNECTING, S_COOLDOWN, S_INITIALIZE, S_NOT_CONNECTED, S_OFF,\
40
S_ON, S_STANDBY, S_WARMUP, STATUS_CODE, STATUS_MSG
43
42
from openlp.core.projectors.db import ProjectorDB
44
43
from openlp.core.projectors.editform import ProjectorEditForm
45
44
from openlp.core.projectors.pjlink import PJLink, PJLinkUDP
46
from openlp.core.projectors.sourceselectform import SourceSelectTabs, SourceSelectSingle
45
from openlp.core.projectors.sourceselectform import SourceSelectSingle, SourceSelectTabs
46
from openlp.core.ui.icons import UiIcons
47
47
from openlp.core.widgets.toolbar import OpenLPToolbar
49
49
log = logging.getLogger(__name__)
50
50
log.debug('projectormanager loaded')
53
# Dict for matching projector status to display icon
55
S_NOT_CONNECTED: ':/projector/projector_item_disconnect.png',
56
S_CONNECTING: ':/projector/projector_item_connect.png',
57
S_CONNECTED: ':/projector/projector_off.png',
58
S_OFF: ':/projector/projector_off.png',
59
S_INITIALIZE: ':/projector/projector_off.png',
60
S_STANDBY: ':/projector/projector_off.png',
61
S_WARMUP: ':/projector/projector_warmup.png',
62
S_ON: ':/projector/projector_on.png',
63
S_COOLDOWN: ':/projector/projector_cooldown.png',
64
E_ERROR: ':/projector/projector_error.png',
65
E_NETWORK: ':/projector/projector_not_connected_error.png',
66
E_SOCKET_TIMEOUT: ':/projector/projector_not_connected_error.png',
67
E_AUTHENTICATION: ':/projector/projector_not_connected_error.png',
68
E_UNKNOWN_SOCKET_ERROR: ':/projector/projector_not_connected_error.png',
69
E_NOT_CONNECTED: ':/projector/projector_not_connected_error.png'
73
53
class UiProjectorManager(object):
75
55
UI part of the Projector Manager
121
101
self.one_toolbar.add_toolbar_action('connect_projector',
122
102
text=translate('OpenLP.ProjectorManager',
123
103
'Connect to selected projector.'),
124
icon=UiIcons().projector_connect,
104
icon=UiIcons().projector_select_connect,
125
105
tooltip=translate('OpenLP.ProjectorManager',
126
106
'Connect to selected projector.'),
127
107
triggers=self.on_connect_projector)
135
115
self.one_toolbar.add_toolbar_action('disconnect_projector',
136
116
text=translate('OpenLP.ProjectorManager',
137
117
'Disconnect from selected projectors'),
138
icon=UiIcons().projector_disconnect,
118
icon=UiIcons().projector_select_disconnect,
139
119
tooltip=translate('OpenLP.ProjectorManager',
140
120
'Disconnect from selected projector.'),
141
121
triggers=self.on_disconnect_projector)
150
130
self.one_toolbar.add_toolbar_action('poweron_projector',
151
131
text=translate('OpenLP.ProjectorManager',
152
132
'Power on selected projector'),
153
icon=UiIcons().projector_on,
133
icon=UiIcons().projector_power_on,
154
134
tooltip=translate('OpenLP.ProjectorManager',
155
135
'Power on selected projector.'),
156
136
triggers=self.on_poweron_projector)
163
143
triggers=self.on_poweron_projector)
164
144
self.one_toolbar.add_toolbar_action('poweroff_projector',
165
145
text=translate('OpenLP.ProjectorManager', 'Standby selected projector'),
166
icon=UiIcons().projector_off,
146
icon=UiIcons().projector_power_off,
167
147
tooltip=translate('OpenLP.ProjectorManager',
168
148
'Put selected projector in standby.'),
169
149
triggers=self.on_poweroff_projector)
308
288
S_INITIALIZE: UiIcons().projector_on,
309
289
S_STANDBY: UiIcons().projector_off,
310
290
S_WARMUP: UiIcons().projector_warmup,
311
S_ON: UiIcons().projector_off,
291
S_ON: UiIcons().projector_on,
312
292
S_COOLDOWN: UiIcons().projector_cooldown,
313
293
E_ERROR: UiIcons().projector_error,
314
294
E_NETWORK: UiIcons().error,
351
327
self.projector_form.editProjector.connect(self.edit_projector_from_wizard)
352
328
self.projector_list_widget.itemSelectionChanged.connect(self.update_icons)
330
def udp_listen_add(self, port):
332
Add UDP broadcast listener
334
if port in self.pjlink_udp:
335
log.warning('UDP Listener for port {port} already added - skipping'.format(port=port))
337
log.debug('Adding UDP listener on port {port}'.format(port=port))
338
self.pjlink_udp[port] = PJLinkUDP(port=port)
339
Registry().execute('udp_broadcast_add', port=port, callback=self.pjlink_udp[port].check_settings)
341
def udp_listen_delete(self, port):
343
Remove a UDP broadcast listener
345
log.debug('Checking for UDP port {port} listener deletion'.format(port=port))
346
if port not in self.pjlink_udp:
347
log.warn('UDP listener for port {port} not there - skipping delete'.format(port=port))
350
for item in self.projector_list:
351
if port == item.link.port:
354
log.warn('UDP listener for port {port} needed for other projectors - skipping delete'.format(port=port))
356
Registry().execute('udp_broadcast_remove', port=port)
357
del self.pjlink_udp[port]
358
log.debug('UDP listener for port {port} deleted'.format(port=port))
354
360
def get_settings(self):
356
362
Retrieve the saved settings
518
524
except (AttributeError, TypeError):
521
projector.poll_timer.stop()
522
projector.poll_timer.timeout.disconnect(projector.link.poll_loop)
523
except (AttributeError, TypeError):
526
projector.socket_timer.stop()
527
projector.socket_timer.timeout.disconnect(projector.link.socket_abort)
528
except (AttributeError, TypeError):
530
# Disconnect signals from projector being deleted
532
self.pjlink_udp[projector.link.port].data_received.disconnect(projector.link.get_buffer)
527
projector.link.poll_timer.stop()
528
projector.link.poll_timer.timeout.disconnect(projector.link.poll_loop)
529
except (AttributeError, TypeError):
532
projector.link.socket_timer.stop()
533
projector.link.socket_timer.timeout.disconnect(projector.link.socket_abort)
533
534
except (AttributeError, TypeError):
537
old_port = projector.link.port
536
538
# Rebuild projector list
538
540
for item in self.projector_list:
539
541
if item.link.db_item.id == projector.link.db_item.id:
542
log.debug('Removing projector "{item}"'.format(item=item.link.name))
541
544
new_list.append(item)
542
545
self.projector_list = new_list
748
752
item.link.projectorAuthentication.connect(self.authentication_error)
749
753
item.link.projectorNoAuthentication.connect(self.no_authentication_error)
750
754
item.link.projectorUpdateIcons.connect(self.update_icons)
751
# Connect UDP signal to projector instances with same port
752
if item.link.port not in self.pjlink_udp:
753
log.debug('Adding new PJLinkUDP listener fo port {port}'.format(port=item.link.port))
754
self.pjlink_udp[item.link.port] = PJLinkUDP(port=item.link.port)
755
self.pjlink_udp[item.link.port].bind(item.link.port)
756
log.debug('Connecting PJLinkUDP port {port} signal to "{item}"'.format(port=item.link.port,
757
item=item.link.name))
758
self.pjlink_udp[item.link.port].data_received.connect(item.link.get_buffer)
755
# Add UDP listener for new projector port
756
self.udp_listen_add(item.link.port)
760
757
self.projector_list.append(item)
762
759
item.link.connect_to_host()
783
780
:param projector: Projector() instance of projector with updated information
785
782
log.debug('edit_projector_from_wizard(ip={ip})'.format(ip=projector.ip))
783
old_port = self.old_projector.link.port
784
old_ip = self.old_projector.link.ip
786
785
self.old_projector.link.name = projector.name
787
786
self.old_projector.link.ip = projector.ip
788
787
self.old_projector.link.pin = None if projector.pin == '' else projector.pin
789
self.old_projector.link.port = projector.port
790
788
self.old_projector.link.location = projector.location
791
789
self.old_projector.link.notes = projector.notes
792
790
self.old_projector.widget.setText(projector.name)
791
self.old_projector.link.port = int(projector.port)
792
# Update projector list items
793
for item in self.projector_list:
794
if item.link.ip == old_ip:
795
item.link.port = int(projector.port)
796
# NOTE: This assumes (!) we are using IP addresses as keys
798
# Update UDP listeners before setting old_projector.port
799
if old_port != projector.port:
800
self.udp_listen_delete(old_port)
801
self.udp_listen_add(int(projector.port))
794
803
def _load_projectors(self):
880
891
self.get_toolbar_item('blank_projector_multiple', hidden=True)
881
892
self.get_toolbar_item('show_projector_multiple', hidden=True)
894
log.debug('update_icons(): Updating icons for connected state')
883
895
self.get_toolbar_item('view_projector', enabled=True)
884
896
self.get_toolbar_item('source_view_projector',
885
enabled=connected and power and projector.link.source_available is not None)
897
enabled=projector.link.source_available is not None and connected and power)
886
898
self.get_toolbar_item('edit_projector', hidden=True)
887
899
self.get_toolbar_item('delete_projector', hidden=True)
901
log.debug('update_icons(): Updating for not connected state')
889
902
self.get_toolbar_item('view_projector', hidden=True)
890
903
self.get_toolbar_item('source_view_projector', hidden=True)
891
904
self.get_toolbar_item('edit_projector', enabled=True)