forked from openlp/openlp
HEAD, plus loading screens from settings
This commit is contained in:
commit
67e6806924
82
.bzrignore
82
.bzrignore
|
@ -1,46 +1,49 @@
|
|||
*.pyc
|
||||
*.*~
|
||||
\#*\#
|
||||
*eric[1-9]project
|
||||
*.ropeproject
|
||||
*.e4*
|
||||
.komodotools
|
||||
*.komodoproject
|
||||
list
|
||||
openlp.org 2.0.e4*
|
||||
documentation/build/html
|
||||
documentation/build/doctrees
|
||||
*.log*
|
||||
dist
|
||||
OpenLP.egg-info
|
||||
build
|
||||
resources/innosetup/Output
|
||||
.pylint.d
|
||||
*.qm
|
||||
openlp/core/resources.py.old
|
||||
*.qm
|
||||
resources/windows/warnOpenLP.txt
|
||||
openlp.cfg
|
||||
.idea
|
||||
openlp.pro
|
||||
.kdev4
|
||||
tests.kdev4
|
||||
*.nja
|
||||
*.orig
|
||||
__pycache__
|
||||
*.dll
|
||||
.directory
|
||||
*.kate-swp
|
||||
# Git files
|
||||
.git
|
||||
.gitignore
|
||||
# Rejected diff's
|
||||
*.rej
|
||||
*.~\?~
|
||||
.coverage
|
||||
\#*\#
|
||||
build
|
||||
.cache
|
||||
cover
|
||||
*.kdev4
|
||||
.coverage
|
||||
coverage
|
||||
.directory
|
||||
dist
|
||||
*.dll
|
||||
documentation/build/doctrees
|
||||
documentation/build/html
|
||||
*.e4*
|
||||
*eric[1-9]project
|
||||
.git
|
||||
# Git files
|
||||
.gitignore
|
||||
htmlcov
|
||||
.idea
|
||||
*.kate-swp
|
||||
*.kdev4
|
||||
.kdev4
|
||||
*.komodoproject
|
||||
.komodotools
|
||||
list
|
||||
*.log*
|
||||
*.nja
|
||||
openlp.cfg
|
||||
openlp/core/resources.py.old
|
||||
OpenLP.egg-info
|
||||
openlp.org 2.0.e4*
|
||||
openlp.pro
|
||||
openlp-test-projectordb.sqlite
|
||||
*.orig
|
||||
output
|
||||
*.pyc
|
||||
__pycache__
|
||||
.pylint.d
|
||||
.pytest_cache
|
||||
*.qm
|
||||
*.rej
|
||||
# Rejected diff's
|
||||
resources/innosetup/Output
|
||||
resources/windows/warnOpenLP.txt
|
||||
*.ropeproject
|
||||
tags
|
||||
output
|
||||
htmlcov
|
||||
|
@ -49,3 +52,4 @@ openlp-test-projectordb.sqlite
|
|||
package-lock.json
|
||||
.cache
|
||||
test
|
||||
tests.kdev4
|
||||
|
|
|
@ -115,7 +115,7 @@ def display_thumbnails(request, controller_name, log, dimensions, file_name, sli
|
|||
height = -1
|
||||
image = None
|
||||
if dimensions:
|
||||
match = re.search('(\d+)x(\d+)', dimensions)
|
||||
match = re.search(r'(\d+)x(\d+)', dimensions)
|
||||
if match:
|
||||
# let's make sure that the dimensions are within reason
|
||||
width = sorted([10, int(match.group(1)), 1000])[1]
|
||||
|
|
|
@ -39,7 +39,7 @@ log = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def _route_to_regex(route):
|
||||
"""
|
||||
r"""
|
||||
Convert a route to a regular expression
|
||||
|
||||
For example:
|
||||
|
|
|
@ -22,13 +22,14 @@
|
|||
"""
|
||||
The :mod:`~openlp.core.api.tab` module contains the settings tab for the API
|
||||
"""
|
||||
from PyQt5 import QtCore, QtGui, QtNetwork, QtWidgets
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import get_local_ip4
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import SettingsTab
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
ZERO_URL = '0.0.0.0'
|
||||
|
||||
|
@ -38,11 +39,9 @@ class ApiTab(SettingsTab):
|
|||
RemoteTab is the Remotes settings tab in the settings dialog.
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
self.icon_path = ':/plugins/plugin_remote.png'
|
||||
self.icon_path = UiIcons().remote
|
||||
advanced_translated = translate('OpenLP.AdvancedTab', 'Advanced')
|
||||
super(ApiTab, self).__init__(parent, 'api', advanced_translated)
|
||||
self.define_main_window_icon()
|
||||
self.generate_icon()
|
||||
|
||||
def setupUi(self):
|
||||
self.setObjectName('ApiTab')
|
||||
|
@ -55,7 +54,7 @@ class ApiTab(SettingsTab):
|
|||
self.address_label.setObjectName('address_label')
|
||||
self.address_edit = QtWidgets.QLineEdit(self.server_settings_group_box)
|
||||
self.address_edit.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
self.address_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'),
|
||||
self.address_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'),
|
||||
self))
|
||||
self.address_edit.setObjectName('address_edit')
|
||||
self.server_settings_layout.addRow(self.address_label, self.address_edit)
|
||||
|
@ -155,24 +154,6 @@ class ApiTab(SettingsTab):
|
|||
self.thumbnails_check_box.stateChanged.connect(self.on_thumbnails_check_box_changed)
|
||||
self.address_edit.textChanged.connect(self.set_urls)
|
||||
|
||||
def define_main_window_icon(self):
|
||||
"""
|
||||
Define an icon on the main window to show the state of the server
|
||||
:return:
|
||||
"""
|
||||
self.remote_server_icon = QtWidgets.QLabel(self.main_window.status_bar)
|
||||
size_policy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
size_policy.setHorizontalStretch(0)
|
||||
size_policy.setVerticalStretch(0)
|
||||
size_policy.setHeightForWidth(self.remote_server_icon.sizePolicy().hasHeightForWidth())
|
||||
self.remote_server_icon.setSizePolicy(size_policy)
|
||||
self.remote_server_icon.setFrameShadow(QtWidgets.QFrame.Plain)
|
||||
self.remote_server_icon.setLineWidth(1)
|
||||
self.remote_server_icon.setScaledContents(True)
|
||||
self.remote_server_icon.setFixedSize(20, 20)
|
||||
self.remote_server_icon.setObjectName('remote_server_icon')
|
||||
self.main_window.status_bar.insertPermanentWidget(2, self.remote_server_icon)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.tab_title_visible = translate('RemotePlugin.RemoteTab', 'Remote Interface')
|
||||
self.server_settings_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'Server Settings'))
|
||||
|
@ -259,7 +240,6 @@ class ApiTab(SettingsTab):
|
|||
Settings().setValue(self.settings_section + '/authentication enabled', self.user_login_group_box.isChecked())
|
||||
Settings().setValue(self.settings_section + '/user id', self.user_id.text())
|
||||
Settings().setValue(self.settings_section + '/password', self.password.text())
|
||||
self.generate_icon()
|
||||
if self.update_site_group_box.isChecked():
|
||||
self.settings_form.register_post_process('download_website')
|
||||
|
||||
|
@ -280,19 +260,3 @@ class ApiTab(SettingsTab):
|
|||
# we have a set value convert to True/False
|
||||
if check_state == QtCore.Qt.Checked:
|
||||
self.thumbnails = True
|
||||
|
||||
def generate_icon(self):
|
||||
"""
|
||||
Generate icon for main window
|
||||
"""
|
||||
self.remote_server_icon.hide()
|
||||
icon = QtGui.QImage(':/remote/network_server.png')
|
||||
icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
if Settings().value(self.settings_section + '/authentication enabled'):
|
||||
overlay = QtGui.QImage(':/remote/network_auth.png')
|
||||
overlay = overlay.scaled(60, 60, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
painter = QtGui.QPainter(icon)
|
||||
painter.drawImage(20, 0, overlay)
|
||||
painter.end()
|
||||
self.remote_server_icon.setPixmap(QtGui.QPixmap.fromImage(icon))
|
||||
self.remote_server_icon.show()
|
||||
|
|
|
@ -405,6 +405,7 @@ def main(args=None):
|
|||
if not Settings().value('core/has run wizard'):
|
||||
if not FirstTimeLanguageForm().exec():
|
||||
# if cancel then stop processing
|
||||
server.close_server()
|
||||
sys.exit()
|
||||
# i18n Set Language
|
||||
language = LanguageManager.get_language()
|
||||
|
|
|
@ -44,7 +44,7 @@ log = logging.getLogger(__name__ + '.__init__')
|
|||
|
||||
FIRST_CAMEL_REGEX = re.compile('(.)([A-Z][a-z]+)')
|
||||
SECOND_CAMEL_REGEX = re.compile('([a-z0-9])([A-Z])')
|
||||
CONTROL_CHARS = re.compile(r'[\x00-\x1F\x7F-\x9F]')
|
||||
CONTROL_CHARS = re.compile(r'[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]')
|
||||
INVALID_FILE_CHARS = re.compile(r'[\\/:\*\?"<>\|\+\[\]%]')
|
||||
IMAGES_FILTER = None
|
||||
REPLACMENT_CHARS_MAP = str.maketrans({'\u2018': '\'', '\u2019': '\'', '\u201c': '"', '\u201d': '"', '\u2026': '...',
|
||||
|
@ -64,13 +64,17 @@ def get_local_ip4():
|
|||
log.debug('Getting local IPv4 interface(es) information')
|
||||
my_ip4 = {}
|
||||
for iface in QNetworkInterface.allInterfaces():
|
||||
log.debug('Checking for isValid and flags == IsUP | IsRunning')
|
||||
if not iface.isValid() or not (iface.flags() & (QNetworkInterface.IsUp | QNetworkInterface.IsRunning)):
|
||||
continue
|
||||
log.debug('Checking address(es) protocol')
|
||||
for address in iface.addressEntries():
|
||||
ip = address.ip()
|
||||
# NOTE: Next line will skip if interface is localhost - keep for now until we decide about it later
|
||||
# if (ip.protocol() == QAbstractSocket.IPv4Protocol) and (ip != QHostAddress.LocalHost):
|
||||
log.debug('Checking for protocol == IPv4Protocol')
|
||||
if ip.protocol() == QAbstractSocket.IPv4Protocol:
|
||||
log.debug('Getting interface information')
|
||||
my_ip4[iface.name()] = {'ip': ip.toString(),
|
||||
'broadcast': address.broadcast().toString(),
|
||||
'netmask': address.netmask().toString(),
|
||||
|
@ -79,14 +83,21 @@ def get_local_ip4():
|
|||
ip.toIPv4Address()).toString()
|
||||
}
|
||||
log.debug('Adding {iface} to active list'.format(iface=iface.name()))
|
||||
if 'localhost' in my_ip4:
|
||||
log.debug('Renaming windows localhost to lo')
|
||||
my_ip4['lo'] = my_ip4['localhost']
|
||||
my_ip4.pop('localhost')
|
||||
if len(my_ip4) == 0:
|
||||
log.warning('No active IPv4 network interfaces detected')
|
||||
if len(my_ip4) == 1:
|
||||
if 'lo' in my_ip4:
|
||||
# No active interfaces - so leave localhost in there
|
||||
log.warning('No active IPv4 interfaces found except localhost')
|
||||
else:
|
||||
# Since we have a valid IP4 interface, remove localhost
|
||||
log.debug('Found at least one IPv4 interface, removing localhost')
|
||||
my_ip4.pop('lo')
|
||||
if 'lo' in my_ip4:
|
||||
log.debug('Found at least one IPv4 interface, removing localhost')
|
||||
my_ip4.pop('lo')
|
||||
|
||||
return my_ip4
|
||||
|
||||
|
@ -471,15 +482,15 @@ def get_file_encoding(file_path):
|
|||
log.exception('Error detecting file encoding')
|
||||
|
||||
|
||||
def normalize_str(irreg_str):
|
||||
def normalize_str(irregular_string):
|
||||
"""
|
||||
Normalize the supplied string. Remove unicode control chars and tidy up white space.
|
||||
|
||||
:param str irreg_str: The string to normalize.
|
||||
:param str irregular_string: The string to normalize.
|
||||
:return: The normalized string
|
||||
:rtype: str
|
||||
"""
|
||||
irreg_str = irreg_str.translate(REPLACMENT_CHARS_MAP)
|
||||
irreg_str = CONTROL_CHARS.sub('', irreg_str)
|
||||
irreg_str = NEW_LINE_REGEX.sub('\n', irreg_str)
|
||||
return WHITESPACE_REGEX.sub(' ', irreg_str)
|
||||
irregular_string = irregular_string.translate(REPLACMENT_CHARS_MAP)
|
||||
irregular_string = CONTROL_CHARS.sub('', irregular_string)
|
||||
irregular_string = NEW_LINE_REGEX.sub('\n', irregular_string)
|
||||
return WHITESPACE_REGEX.sub(' ', irregular_string)
|
||||
|
|
|
@ -32,6 +32,7 @@ import requests
|
|||
|
||||
from openlp.core.common import trace_error_handler
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import ProxyMode, Settings
|
||||
|
||||
log = logging.getLogger(__name__ + '.__init__')
|
||||
|
||||
|
@ -64,6 +65,39 @@ CONNECTION_TIMEOUT = 30
|
|||
CONNECTION_RETRIES = 2
|
||||
|
||||
|
||||
def get_proxy_settings(mode=None):
|
||||
"""
|
||||
Create a dictionary containing the proxy settings.
|
||||
|
||||
:param ProxyMode | None mode: Specify the source of the proxy settings
|
||||
:return: A dict using the format expected by the requests library.
|
||||
:rtype: dict | None
|
||||
"""
|
||||
settings = Settings()
|
||||
if mode is None:
|
||||
mode = settings.value('advanced/proxy mode')
|
||||
if mode == ProxyMode.NO_PROXY:
|
||||
return {'http': None, 'https': None}
|
||||
elif mode == ProxyMode.SYSTEM_PROXY:
|
||||
# The requests library defaults to using the proxy settings in the environment variables
|
||||
return
|
||||
elif mode == ProxyMode.MANUAL_PROXY:
|
||||
http_addr = settings.value('advanced/proxy http')
|
||||
https_addr = settings.value('advanced/proxy https')
|
||||
username = settings.value('advanced/proxy username')
|
||||
password = settings.value('advanced/proxy password')
|
||||
basic_auth = ''
|
||||
if username:
|
||||
basic_auth = '{username}:{password}@'.format(username=username, password=password)
|
||||
http_value = None
|
||||
https_value = None
|
||||
if http_addr:
|
||||
http_value = 'http://{basic_auth}{http_addr}'.format(basic_auth=basic_auth, http_addr=http_addr)
|
||||
if https_addr:
|
||||
https_value = 'https://{basic_auth}{https_addr}'.format(basic_auth=basic_auth, https_addr=https_addr)
|
||||
return {'http': http_value, 'https': https_value}
|
||||
|
||||
|
||||
def get_user_agent():
|
||||
"""
|
||||
Return a user agent customised for the platform the user is on.
|
||||
|
@ -75,14 +109,15 @@ def get_user_agent():
|
|||
return browser_list[random_index]
|
||||
|
||||
|
||||
def get_web_page(url, headers=None, update_openlp=False, proxies=None):
|
||||
def get_web_page(url, headers=None, update_openlp=False, proxy=None):
|
||||
"""
|
||||
Attempts to download the webpage at url and returns that page or None.
|
||||
|
||||
:param url: The URL to be downloaded.
|
||||
:param header: An optional HTTP header to pass in the request to the web server.
|
||||
:param update_openlp: Tells OpenLP to update itself if the page is successfully downloaded.
|
||||
Defaults to False.
|
||||
:param dict | None headers: An optional HTTP header to pass in the request to the web server.
|
||||
:param update_openlp: Tells OpenLP to update itself if the page is successfully downloaded. Defaults to False.
|
||||
:param dict | ProxyMode | None proxy: ProxyMode enum or a dictionary containing the proxy servers, with their types
|
||||
as the key e.g. {'http': 'http://proxyserver:port', 'https': 'https://proxyserver:port'}
|
||||
"""
|
||||
if not url:
|
||||
return None
|
||||
|
@ -90,11 +125,13 @@ def get_web_page(url, headers=None, update_openlp=False, proxies=None):
|
|||
headers = {}
|
||||
if 'user-agent' not in [key.lower() for key in headers.keys()]:
|
||||
headers['User-Agent'] = get_user_agent()
|
||||
if not isinstance(proxy, dict):
|
||||
proxy = get_proxy_settings(mode=proxy)
|
||||
log.debug('Downloading URL = %s' % url)
|
||||
retries = 0
|
||||
while retries < CONNECTION_RETRIES:
|
||||
try:
|
||||
response = requests.get(url, headers=headers, proxies=proxies, timeout=float(CONNECTION_TIMEOUT))
|
||||
response = requests.get(url, headers=headers, proxies=proxy, timeout=float(CONNECTION_TIMEOUT))
|
||||
log.debug('Downloaded page {url}'.format(url=response.url))
|
||||
break
|
||||
except OSError:
|
||||
|
|
|
@ -339,9 +339,10 @@ class UiStrings(object):
|
|||
"""
|
||||
if not cls.__instance__:
|
||||
cls.__instance__ = object.__new__(cls)
|
||||
cls.load(cls)
|
||||
return cls.__instance__
|
||||
|
||||
def __init__(self):
|
||||
def load(self):
|
||||
"""
|
||||
These strings should need a good reason to be retranslated elsewhere.
|
||||
Should some/more/less of these have an & attached?
|
||||
|
|
|
@ -206,7 +206,8 @@ def str_to_path(string):
|
|||
:rtype: openlp.core.common.path.Path | None
|
||||
"""
|
||||
if not isinstance(string, str):
|
||||
raise TypeError('parameter \'string\' must be of type str')
|
||||
log.error('parameter \'string\' must be of type str, got {} which is a {} instead'.format(string, type(string)))
|
||||
return None
|
||||
if string == '':
|
||||
return None
|
||||
return Path(string)
|
||||
|
|
|
@ -58,6 +58,7 @@ class Registry(object):
|
|||
registry.working_flags = {}
|
||||
# Allow the tests to remove Registry entries but not the live system
|
||||
registry.running_under_test = 'nose' in sys.argv[0]
|
||||
registry.running_under_test = 'pytest' in sys.argv[0]
|
||||
registry.initialising = True
|
||||
return registry
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import datetime
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
from enum import IntEnum
|
||||
from tempfile import gettempdir
|
||||
|
||||
from PyQt5 import QtCore, QtGui
|
||||
|
@ -38,6 +39,13 @@ log = logging.getLogger(__name__)
|
|||
|
||||
__version__ = 2
|
||||
|
||||
|
||||
class ProxyMode(IntEnum):
|
||||
NO_PROXY = 1
|
||||
SYSTEM_PROXY = 2
|
||||
MANUAL_PROXY = 3
|
||||
|
||||
|
||||
# Fix for bug #1014422.
|
||||
X11_BYPASS_DEFAULT = True
|
||||
if is_linux(): # pragma: no cover
|
||||
|
@ -62,7 +70,7 @@ def media_players_conv(string):
|
|||
return string
|
||||
|
||||
|
||||
def upgrade_monitor(number, x_position, y_position, height, width, can_override, can_display_on_monitor):
|
||||
def upgrade_screens(number, x_position, y_position, height, width, can_override, is_display_screen):
|
||||
"""
|
||||
Upgrade them monitor setting from a few single entries to a composite JSON entry
|
||||
|
||||
|
@ -70,19 +78,23 @@ def upgrade_monitor(number, x_position, y_position, height, width, can_override,
|
|||
:param int x_position: The X position
|
||||
:param int y_position: The Y position
|
||||
:param bool can_override: Are the screen positions overridden
|
||||
:param bool can_display_on_monitor: Can OpenLP display on the monitor
|
||||
:param bool is_display_screen: Is this a display screen
|
||||
:returns dict: Dictionary with the new value
|
||||
"""
|
||||
geometry_key = 'geometry'
|
||||
if can_override:
|
||||
geometry_key = 'display_geometry'
|
||||
return {
|
||||
number: {
|
||||
'displayGeometry': {
|
||||
'number': number,
|
||||
geometry_key: {
|
||||
'x': x_position,
|
||||
'y': y_position,
|
||||
'height': height,
|
||||
'width': width
|
||||
}
|
||||
},
|
||||
'canDisplayOnMonitor': can_display_on_monitor
|
||||
},
|
||||
'is_display': is_display_screen
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,6 +152,11 @@ class Settings(QtCore.QSettings):
|
|||
'advanced/print file meta data': False,
|
||||
'advanced/print notes': False,
|
||||
'advanced/print slide text': False,
|
||||
'advanced/proxy mode': ProxyMode.SYSTEM_PROXY,
|
||||
'advanced/proxy http': '',
|
||||
'advanced/proxy https': '',
|
||||
'advanced/proxy username': '',
|
||||
'advanced/proxy password': '',
|
||||
'advanced/recent file count': 4,
|
||||
'advanced/save current plugin': False,
|
||||
'advanced/slide limits': SlideLimits.End,
|
||||
|
@ -224,6 +241,7 @@ class Settings(QtCore.QSettings):
|
|||
'projector/db database': '',
|
||||
'projector/enable': True,
|
||||
'projector/connect on start': False,
|
||||
'projector/connect when LKUP received': True, # PJLink v2: Projector sends LKUP command after it powers up
|
||||
'projector/last directory import': None,
|
||||
'projector/last directory export': None,
|
||||
'projector/poll time': 20, # PJLink timeout is 30 seconds
|
||||
|
@ -287,7 +305,7 @@ class Settings(QtCore.QSettings):
|
|||
('songuasge/db database', 'songusage/db database', []),
|
||||
('presentations / Powerpoint Viewer', '', []),
|
||||
(['core/monitor', 'core/x position', 'core/y position', 'core/height', 'core/width', 'core/override',
|
||||
'core/display on monitor'], 'core/monitors', [(upgrade_monitor, [1, 0, 0, None, None, False, False])])
|
||||
'core/display on monitor'], 'core/screens', [(upgrade_screens, [1, 0, 0, None, None, False, False])])
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
|
@ -553,7 +571,7 @@ class Settings(QtCore.QSettings):
|
|||
:param value: The value to save
|
||||
:rtype: None
|
||||
"""
|
||||
if isinstance(value, Path) or (isinstance(value, list) and value and isinstance(value[0], Path)):
|
||||
if isinstance(value, (Path, dict)) or (isinstance(value, list) and value and isinstance(value[0], Path)):
|
||||
value = json.dumps(value, cls=OpenLPJsonEncoder)
|
||||
super().setValue(key, value)
|
||||
|
||||
|
@ -576,6 +594,9 @@ class Settings(QtCore.QSettings):
|
|||
# An empty list saved to the settings results in a None type being returned.
|
||||
elif isinstance(default_value, list):
|
||||
return []
|
||||
# An empty dictionary saved to the settings results in a None type being returned.
|
||||
elif isinstance(default_value, dict):
|
||||
return {}
|
||||
elif isinstance(setting, str):
|
||||
if '__Path__' in setting or setting.startswith('{'):
|
||||
return json.loads(setting, cls=OpenLPJsonDecoder)
|
||||
|
|
|
@ -115,6 +115,8 @@ class Screen(object):
|
|||
self.is_display = screen_dict['is_display']
|
||||
self.is_primary = screen_dict['is_primary']
|
||||
self.geometry = QtCore.QRect(**screen_dict['geometry'])
|
||||
if 'display_geometry' in screen_dict:
|
||||
self.display_geometry = QtCore.QRect(**screen_dict['display_geometry'])
|
||||
|
||||
|
||||
class ScreenList(object):
|
||||
|
@ -197,26 +199,26 @@ class ScreenList(object):
|
|||
|
||||
def load_screen_settings(self):
|
||||
"""
|
||||
Loads the screen size and the monitor number from the settings.
|
||||
Loads the screen size and the screen number from the settings.
|
||||
"""
|
||||
# Add the screen settings to the settings dict. This has to be done here due to cyclic dependency.
|
||||
# Do not do this anywhere else.
|
||||
screen_settings = {
|
||||
'core/monitors': '{}'
|
||||
'core/screens': '{}'
|
||||
}
|
||||
Settings.extend_default_settings(screen_settings)
|
||||
monitors = Settings().value('core/monitors')
|
||||
# for number, monitor in monitors.items():
|
||||
# if self.has_screen(number):
|
||||
# self[number].update(monitor)
|
||||
# else:
|
||||
# self.screens.append(Screen.from_dict(monitor))
|
||||
screen_settings = Settings().value('core/screens')
|
||||
for number, screen_dict in screen_settings.items():
|
||||
if self.has_screen(number):
|
||||
self[number].update(screen_dict)
|
||||
else:
|
||||
self.screens.append(Screen.from_dict(screen_dict))
|
||||
|
||||
def save_screen_settings(self):
|
||||
"""
|
||||
Saves the screen size and monitor settings
|
||||
Saves the screen size and screen settings
|
||||
"""
|
||||
Settings().setValue('core/monitors', {screen.number: screen.to_dict() for screen in self.screens})
|
||||
Settings().setValue('core/screens', {screen.number: screen.to_dict() for screen in self.screens})
|
||||
|
||||
def get_display_screen_list(self):
|
||||
"""
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
r"""
|
||||
This module is responsible for generating the HTML for :class:`~openlp.core.ui.maindisplay`. The ``build_html`` function
|
||||
is the function which has to be called from outside. The generated and returned HTML will look similar to this::
|
||||
|
||||
|
@ -415,7 +415,7 @@ from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, Vertic
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
HTML_SRC = Template("""
|
||||
HTML_SRC = Template(r"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
@ -28,6 +28,7 @@ import re
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
from openlp.core.common.path import path_to_str, str_to_path
|
||||
from openlp.core.common.registry import Registry
|
||||
|
@ -165,28 +166,25 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
|||
toolbar_actions = []
|
||||
# Import Button
|
||||
if self.has_import_icon:
|
||||
toolbar_actions.append(['Import', StringContent.Import,
|
||||
':/general/general_import.png', self.on_import_click])
|
||||
toolbar_actions.append(['Import', StringContent.Import, UiIcons().download, self.on_import_click])
|
||||
# Load Button
|
||||
if self.has_file_icon:
|
||||
toolbar_actions.append(['Load', StringContent.Load, ':/general/general_open.png', self.on_file_click])
|
||||
toolbar_actions.append(['Load', StringContent.Load, UiIcons().open, self.on_file_click])
|
||||
# New Button
|
||||
if self.has_new_icon:
|
||||
toolbar_actions.append(['New', StringContent.New, ':/general/general_new.png', self.on_new_click])
|
||||
toolbar_actions.append(['New', StringContent.New, UiIcons().new, self.on_new_click])
|
||||
# Edit Button
|
||||
if self.has_edit_icon:
|
||||
toolbar_actions.append(['Edit', StringContent.Edit, ':/general/general_edit.png', self.on_edit_click])
|
||||
toolbar_actions.append(['Edit', StringContent.Edit, UiIcons().edit, self.on_edit_click])
|
||||
# Delete Button
|
||||
if self.has_delete_icon:
|
||||
toolbar_actions.append(['Delete', StringContent.Delete,
|
||||
':/general/general_delete.png', self.on_delete_click])
|
||||
toolbar_actions.append(['Delete', StringContent.Delete, UiIcons().delete, self.on_delete_click])
|
||||
# Preview
|
||||
toolbar_actions.append(['Preview', StringContent.Preview,
|
||||
':/general/general_preview.png', self.on_preview_click])
|
||||
toolbar_actions.append(['Preview', StringContent.Preview, UiIcons().preview, self.on_preview_click])
|
||||
# Live Button
|
||||
toolbar_actions.append(['Live', StringContent.Live, ':/general/general_live.png', self.on_live_click])
|
||||
toolbar_actions.append(['Live', StringContent.Live, UiIcons().live, self.on_live_click])
|
||||
# Add to service Button
|
||||
toolbar_actions.append(['Service', StringContent.Service, ':/general/general_add.png', self.on_add_click])
|
||||
toolbar_actions.append(['Service', StringContent.Service, UiIcons().add, self.on_add_click])
|
||||
for action in toolbar_actions:
|
||||
if action[0] == StringContent.Preview:
|
||||
self.toolbar.addSeparator()
|
||||
|
@ -207,21 +205,21 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
|||
if self.has_edit_icon:
|
||||
create_widget_action(self.list_view,
|
||||
text=self.plugin.get_string(StringContent.Edit)['title'],
|
||||
icon=':/general/general_edit.png',
|
||||
icon=UiIcons().edit,
|
||||
triggers=self.on_edit_click)
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
create_widget_action(self.list_view,
|
||||
'listView{plugin}{preview}Item'.format(plugin=self.plugin.name.title(),
|
||||
preview=StringContent.Preview.title()),
|
||||
text=self.plugin.get_string(StringContent.Preview)['title'],
|
||||
icon=':/general/general_preview.png',
|
||||
icon=UiIcons().preview,
|
||||
can_shortcuts=True,
|
||||
triggers=self.on_preview_click)
|
||||
create_widget_action(self.list_view,
|
||||
'listView{plugin}{live}Item'.format(plugin=self.plugin.name.title(),
|
||||
live=StringContent.Live.title()),
|
||||
text=self.plugin.get_string(StringContent.Live)['title'],
|
||||
icon=':/general/general_live.png',
|
||||
icon=UiIcons().live,
|
||||
can_shortcuts=True,
|
||||
triggers=self.on_live_click)
|
||||
create_widget_action(self.list_view,
|
||||
|
@ -229,7 +227,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
|||
service=StringContent.Service.title()),
|
||||
can_shortcuts=True,
|
||||
text=self.plugin.get_string(StringContent.Service)['title'],
|
||||
icon=':/general/general_add.png',
|
||||
icon=UiIcons().add,
|
||||
triggers=self.on_add_click)
|
||||
if self.has_delete_icon:
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
|
@ -237,13 +235,13 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
|||
'listView{plugin}{delete}Item'.format(plugin=self.plugin.name.title(),
|
||||
delete=StringContent.Delete.title()),
|
||||
text=self.plugin.get_string(StringContent.Delete)['title'],
|
||||
icon=':/general/general_delete.png',
|
||||
icon=UiIcons().delete,
|
||||
can_shortcuts=True, triggers=self.on_delete_click)
|
||||
if self.add_to_service_item:
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
create_widget_action(self.list_view,
|
||||
text=translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'),
|
||||
icon=':/general/general_add.png',
|
||||
icon=UiIcons().add,
|
||||
triggers=self.on_add_edit_click)
|
||||
self.add_custom_context_actions()
|
||||
# Create the context menu and add all actions from the list_view.
|
||||
|
@ -621,7 +619,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
|||
:param context: The context on which this is called
|
||||
"""
|
||||
service_item = ServiceItem(self.plugin)
|
||||
service_item.add_icon(self.plugin.icon_path)
|
||||
service_item.add_icon()
|
||||
if self.generate_slide_data(service_item, item, xml_version, remote, context):
|
||||
return service_item
|
||||
else:
|
||||
|
|
|
@ -35,6 +35,7 @@ from PyQt5 import QtGui
|
|||
from openlp.core.common import md5_hash
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
from openlp.core.common.path import Path
|
||||
from openlp.core.common.settings import Settings
|
||||
|
@ -173,7 +174,7 @@ class ServiceItem(RegistryProperties):
|
|||
self.processor = None
|
||||
self.audit = ''
|
||||
self.items = []
|
||||
self.iconic_representation = None
|
||||
self.icon = UiIcons().default
|
||||
self.raw_footer = []
|
||||
self.foot_text = ''
|
||||
self.theme = None
|
||||
|
@ -231,14 +232,22 @@ class ServiceItem(RegistryProperties):
|
|||
"""
|
||||
return capability in self.capabilities
|
||||
|
||||
def add_icon(self, icon):
|
||||
def add_icon(self):
|
||||
"""
|
||||
Add an icon to the service item. This is used when displaying the service item in the service manager.
|
||||
|
||||
:param icon: A string to an icon in the resources or on disk.
|
||||
"""
|
||||
self.icon = icon
|
||||
self.iconic_representation = build_icon(icon)
|
||||
if self.name == 'songs':
|
||||
self.icon = UiIcons().music
|
||||
elif self.name == 'bibles':
|
||||
self.icon = UiIcons().bible
|
||||
elif self.name == 'presentations':
|
||||
self.icon = UiIcons().presentation
|
||||
elif self.name == 'images':
|
||||
self.icon = UiIcons().picture
|
||||
elif self.name == 'media':
|
||||
self.icon = UiIcons().video
|
||||
else:
|
||||
self.icon = UiIcons().clone
|
||||
|
||||
@property
|
||||
def rendered_slides(self):
|
||||
|
@ -392,7 +401,6 @@ class ServiceItem(RegistryProperties):
|
|||
'plugin': self.name,
|
||||
'theme': self.theme,
|
||||
'title': self.title,
|
||||
'icon': self.icon,
|
||||
'footer': self.raw_footer,
|
||||
'type': self.service_item_type,
|
||||
'audit': self.audit,
|
||||
|
@ -444,7 +452,7 @@ class ServiceItem(RegistryProperties):
|
|||
self.name = header['name']
|
||||
self.service_item_type = header['type']
|
||||
self.theme = header['theme']
|
||||
self.add_icon(header['icon'])
|
||||
self.add_icon()
|
||||
self.raw_footer = header['footer']
|
||||
self.audit = header['audit']
|
||||
self.notes = header['notes']
|
||||
|
|
|
@ -31,6 +31,7 @@ from openlp.core.common.actions import ActionList
|
|||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -161,10 +162,10 @@ def create_button(parent, name, **kwargs):
|
|||
kwargs.setdefault('text', UiStrings().Delete)
|
||||
kwargs.setdefault('tooltip', translate('OpenLP.Ui', 'Delete the selected item.'))
|
||||
elif role == 'up':
|
||||
kwargs.setdefault('icon', ':/services/service_up.png')
|
||||
kwargs.setdefault('icon', UiIcons().arrow_up)
|
||||
kwargs.setdefault('tooltip', translate('OpenLP.Ui', 'Move selection up one position.'))
|
||||
elif role == 'down':
|
||||
kwargs.setdefault('icon', ':/services/service_down.png')
|
||||
kwargs.setdefault('icon', UiIcons().arrow_down)
|
||||
kwargs.setdefault('tooltip', translate('OpenLP.Ui', 'Move selection down one position.'))
|
||||
else:
|
||||
log.warning('The role "{role}" is not defined in create_push_button().'.format(role=role))
|
||||
|
|
|
@ -154,110 +154,137 @@ PROJECTOR_STATE = [
|
|||
S_INFO
|
||||
]
|
||||
|
||||
# NOTE: Changed format to account for some commands are both class 1 and 2
|
||||
# NOTE: Changed format to account for some commands are both class 1 and 2.
|
||||
# Make sure the sequence of 'version' is lowest-to-highest.
|
||||
PJLINK_VALID_CMD = {
|
||||
'ACKN': {'version': ['2', ],
|
||||
'ACKN': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Acknowledge a PJLink SRCH command - returns MAC address.')
|
||||
},
|
||||
'AVMT': {'version': ['1', ],
|
||||
'AVMT': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Blank/unblank video and/or mute audio.')
|
||||
},
|
||||
'CLSS': {'version': ['1', ],
|
||||
'CLSS': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query projector PJLink class support.')
|
||||
},
|
||||
'ERST': {'version': ['1', '2'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query error status from projector. '
|
||||
'Returns fan/lamp/temp/cover/filter/other error status.')
|
||||
},
|
||||
'FILT': {'version': ['2', ],
|
||||
'FILT': {'version': ['2'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query number of hours on filter.')
|
||||
},
|
||||
'FREZ': {'version': ['2', ],
|
||||
'FREZ': {'version': ['2'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Freeze or unfreeze current image being projected.')
|
||||
},
|
||||
'INF1': {'version': ['1', ],
|
||||
'INF1': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query projector manufacturer name.')
|
||||
},
|
||||
'INF2': {'version': ['1', ],
|
||||
'INF2': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query projector product name.')
|
||||
},
|
||||
'INFO': {'version': ['1', ],
|
||||
'INFO': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query projector for other information set by manufacturer.')
|
||||
},
|
||||
'INNM': {'version': ['2', ],
|
||||
'INNM': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query specified input source name')
|
||||
},
|
||||
'INPT': {'version': ['1', ],
|
||||
'INPT': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Switch to specified video source.')
|
||||
},
|
||||
'INST': {'version': ['1', ],
|
||||
'INST': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query available input sources.')
|
||||
},
|
||||
'IRES': {'version:': ['2', ],
|
||||
'IRES': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query current input resolution.')
|
||||
},
|
||||
'LAMP': {'version': ['1', ],
|
||||
'LAMP': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query lamp time and on/off status. Multiple lamps supported.')
|
||||
},
|
||||
'LKUP': {'version': ['2', ],
|
||||
'LKUP': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'UDP Status - Projector is now available on network. Includes MAC address.')
|
||||
},
|
||||
'MVOL': {'version': ['2', ],
|
||||
'MVOL': {'version': ['2'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Adjust microphone volume by 1 step.')
|
||||
},
|
||||
'NAME': {'version': ['1', ],
|
||||
'NAME': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query customer-set projector name.')
|
||||
},
|
||||
'PJLINK': {'version': ['1', ],
|
||||
'PJLINK': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Initial connection with authentication/no authentication request.')
|
||||
},
|
||||
'POWR': {'version': ['1', ],
|
||||
'POWR': {'version': ['1'],
|
||||
'default': '1',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Turn lamp on or off/standby.')
|
||||
},
|
||||
'RFIL': {'version': ['2', ],
|
||||
'RFIL': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query replacement air filter model number.')
|
||||
},
|
||||
'RLMP': {'version': ['2', ],
|
||||
'RLMP': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query replacement lamp model number.')
|
||||
},
|
||||
'RRES': {'version': ['2', ],
|
||||
'RRES': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query recommended resolution.')
|
||||
},
|
||||
'SNUM': {'version': ['2', ],
|
||||
'SNUM': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query projector serial number.')
|
||||
},
|
||||
'SRCH': {'version': ['2', ],
|
||||
'SRCH': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'UDP broadcast search request for available projectors. Reply is ACKN.')
|
||||
},
|
||||
'SVER': {'version': ['2', ],
|
||||
'SVER': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Query projector software version number.')
|
||||
},
|
||||
'SVOL': {'version': ['2', ],
|
||||
'SVOL': {'version': ['2'],
|
||||
'default': '2',
|
||||
'description': translate('OpenLP.PJLinkConstants',
|
||||
'Adjust speaker volume by 1 step.')
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ from PyQt5 import QtCore, QtWidgets
|
|||
|
||||
from openlp.core.common import verify_ip_address
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.projectors.constants import PJLINK_PORT
|
||||
from openlp.core.projectors.db import Projector
|
||||
|
||||
|
@ -47,7 +47,7 @@ class Ui_ProjectorEditForm(object):
|
|||
Create the interface layout.
|
||||
"""
|
||||
edit_projector_dialog.setObjectName('edit_projector_dialog')
|
||||
edit_projector_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
edit_projector_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
edit_projector_dialog.setMinimumWidth(400)
|
||||
edit_projector_dialog.setModal(True)
|
||||
# Define the basic layout
|
||||
|
@ -58,10 +58,15 @@ class Ui_ProjectorEditForm(object):
|
|||
# IP Address
|
||||
self.ip_label = QtWidgets.QLabel(edit_projector_dialog)
|
||||
self.ip_label.setObjectName('projector_edit_ip_label')
|
||||
self.ip_text = QtWidgets.QLineEdit(edit_projector_dialog)
|
||||
self.ip_text.setObjectName('projector_edit_ip_text')
|
||||
self.ip_text_edit = QtWidgets.QLineEdit(edit_projector_dialog)
|
||||
self.ip_text_edit.setObjectName('projector_edit_ip_text')
|
||||
self.ip_text_label = QtWidgets.QLabel(edit_projector_dialog)
|
||||
self.ip_text_label.setObjectName('projector_show_ip_text')
|
||||
self.dialog_layout.addWidget(self.ip_label, 0, 0)
|
||||
self.dialog_layout.addWidget(self.ip_text, 0, 1)
|
||||
# For new projector, use edit widget
|
||||
self.dialog_layout.addWidget(self.ip_text_edit, 0, 1)
|
||||
# For edit projector, use show widget
|
||||
self.dialog_layout.addWidget(self.ip_text_label, 0, 1)
|
||||
# Port number
|
||||
self.port_label = QtWidgets.QLabel(edit_projector_dialog)
|
||||
self.port_label.setObjectName('projector_edit_ip_label')
|
||||
|
@ -111,8 +116,8 @@ class Ui_ProjectorEditForm(object):
|
|||
title = translate('OpenLP.ProjectorEditForm', 'Edit Projector')
|
||||
edit_projector_dialog.setWindowTitle(title)
|
||||
self.ip_label.setText(translate('OpenLP.ProjectorEditForm', 'IP Address'))
|
||||
self.ip_text.setText(self.projector.ip)
|
||||
self.ip_text.setFocus()
|
||||
self.ip_text_edit.setText(self.projector.ip)
|
||||
self.ip_text_label.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'))
|
||||
|
@ -131,7 +136,7 @@ class ProjectorEditForm(QtWidgets.QDialog, Ui_ProjectorEditForm):
|
|||
Class to add or edit a projector entry in the database.
|
||||
|
||||
Fields that are editable:
|
||||
ip = Column(String(100))
|
||||
ip = Column(String(100)) (Only edit for new projector)
|
||||
port = Column(String(8))
|
||||
pin = Column(String(20))
|
||||
name = Column(String(20))
|
||||
|
@ -154,9 +159,16 @@ class ProjectorEditForm(QtWidgets.QDialog, Ui_ProjectorEditForm):
|
|||
if projector is None:
|
||||
self.projector = Projector()
|
||||
self.new_projector = True
|
||||
self.ip_text_edit.setVisible(True)
|
||||
self.ip_text_edit.setFocus()
|
||||
self.ip_text_label.setVisible(False)
|
||||
else:
|
||||
self.projector = projector
|
||||
self.new_projector = False
|
||||
self.ip_text_edit.setVisible(False)
|
||||
self.ip_text_label.setVisible(True)
|
||||
# Since it's already defined, IP address is unchangeable, so focus on port number
|
||||
self.port_text.setFocus()
|
||||
self.retranslateUi(self)
|
||||
reply = QtWidgets.QDialog.exec(self)
|
||||
return reply
|
||||
|
@ -187,30 +199,32 @@ class ProjectorEditForm(QtWidgets.QDialog, Ui_ProjectorEditForm):
|
|||
record=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:
|
||||
if self.new_projector:
|
||||
# Only validate a new entry - otherwise it's been previously verified
|
||||
adx = self.ip_text_edit.text()
|
||||
valid = verify_ip_address(adx)
|
||||
if valid:
|
||||
# With a valid IP - check if it's already in database so we don't duplicate
|
||||
ip = self.projectordb.get_projector_by_ip(adx)
|
||||
if ip is None:
|
||||
valid = True
|
||||
self.new_projector = True
|
||||
elif ip.id != self.projector.id:
|
||||
QtWidgets.QMessageBox.warning(self,
|
||||
translate('OpenLP.ProjectorWizard', 'Duplicate IP Address'),
|
||||
translate('OpenLP.ProjectorWizard',
|
||||
'IP address "{ip}"<br />is already in the database '
|
||||
'as ID {data}.<br /><br />Please Enter a different '
|
||||
'IP address.'.format(ip=adx, data=ip.id)))
|
||||
return
|
||||
else:
|
||||
QtWidgets.QMessageBox.warning(self,
|
||||
translate('OpenLP.ProjectorWizard', 'Duplicate IP Address'),
|
||||
translate('OpenLP.ProjectorWizard', 'Invalid IP Address'),
|
||||
translate('OpenLP.ProjectorWizard',
|
||||
'IP address "{ip}"<br />is already in the database '
|
||||
'as ID {data}.<br /><br />Please Enter a different '
|
||||
'IP address.'.format(ip=adx, data=ip.id)))
|
||||
'IP address "{ip}"<br>is not a valid IP address.'
|
||||
'<br /><br />Please enter a valid IP address.'.format(ip=adx)))
|
||||
valid = False
|
||||
return
|
||||
else:
|
||||
QtWidgets.QMessageBox.warning(self,
|
||||
translate('OpenLP.ProjectorWizard', 'Invalid IP Address'),
|
||||
translate('OpenLP.ProjectorWizard',
|
||||
'IP address "{ip}"<br>is not a valid IP address.'
|
||||
'<br /><br />Please enter a valid IP address.'.format(ip=adx)))
|
||||
valid = False
|
||||
return
|
||||
port = int(self.port_text.text())
|
||||
if port < 1000 or port > 32767:
|
||||
QtWidgets.QMessageBox.warning(self,
|
||||
|
@ -223,7 +237,8 @@ class ProjectorEditForm(QtWidgets.QDialog, Ui_ProjectorEditForm):
|
|||
'Default PJLink port is {port}'.format(port=PJLINK_PORT)))
|
||||
valid = False
|
||||
if valid:
|
||||
self.projector.ip = self.ip_text.text()
|
||||
if self.new_projector:
|
||||
self.projector.ip = self.ip_text_edit.text()
|
||||
self.projector.pin = self.pin_text.text()
|
||||
self.projector.port = int(self.port_text.text())
|
||||
self.projector.name = self.name_text.text()
|
||||
|
|
|
@ -30,29 +30,15 @@ import logging
|
|||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
from openlp.core.common.registry import RegistryBase
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib.ui import create_widget_action
|
||||
from openlp.core.projectors import DialogSourceStyle
|
||||
from openlp.core.projectors.constants import \
|
||||
E_AUTHENTICATION, \
|
||||
E_ERROR, \
|
||||
E_NETWORK, \
|
||||
E_NOT_CONNECTED, \
|
||||
E_UNKNOWN_SOCKET_ERROR, \
|
||||
S_CONNECTED, \
|
||||
S_CONNECTING, \
|
||||
S_COOLDOWN, \
|
||||
S_INITIALIZE, \
|
||||
S_NOT_CONNECTED, \
|
||||
S_OFF, \
|
||||
S_ON, \
|
||||
S_STANDBY, \
|
||||
S_WARMUP, \
|
||||
STATUS_CODE, \
|
||||
STATUS_MSG, \
|
||||
QSOCKET_STATE
|
||||
from openlp.core.projectors.constants import E_AUTHENTICATION, E_ERROR, E_NETWORK, E_NOT_CONNECTED, \
|
||||
E_SOCKET_TIMEOUT, E_UNKNOWN_SOCKET_ERROR, S_CONNECTED, S_CONNECTING, S_COOLDOWN, S_INITIALIZE, \
|
||||
S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP, PJLINK_PORT, STATUS_CODE, STATUS_MSG, QSOCKET_STATE
|
||||
|
||||
from openlp.core.projectors.db import ProjectorDB
|
||||
from openlp.core.projectors.editform import ProjectorEditForm
|
||||
|
@ -77,6 +63,7 @@ STATUS_ICONS = {
|
|||
S_COOLDOWN: ':/projector/projector_cooldown.png',
|
||||
E_ERROR: ':/projector/projector_error.png',
|
||||
E_NETWORK: ':/projector/projector_not_connected_error.png',
|
||||
E_SOCKET_TIMEOUT: ':/projector/projector_not_connected_error.png',
|
||||
E_AUTHENTICATION: ':/projector/projector_not_connected_error.png',
|
||||
E_UNKNOWN_SOCKET_ERROR: ':/projector/projector_not_connected_error.png',
|
||||
E_NOT_CONNECTED: ':/projector/projector_not_connected_error.png'
|
||||
|
@ -103,30 +90,30 @@ class UiProjectorManager(object):
|
|||
self.one_toolbar = OpenLPToolbar(widget)
|
||||
self.one_toolbar.add_toolbar_action('new_projector',
|
||||
text=translate('OpenLP.ProjectorManager', 'Add Projector'),
|
||||
icon=':/projector/projector_new.png',
|
||||
icon=UiIcons().new,
|
||||
tooltip=translate('OpenLP.ProjectorManager', 'Add a new projector.'),
|
||||
triggers=self.on_add_projector)
|
||||
# Show edit/delete when projector not connected
|
||||
self.one_toolbar.add_toolbar_action('edit_projector',
|
||||
text=translate('OpenLP.ProjectorManager', 'Edit Projector'),
|
||||
icon=':/general/general_edit.png',
|
||||
icon=UiIcons().edit,
|
||||
tooltip=translate('OpenLP.ProjectorManager', 'Edit selected projector.'),
|
||||
triggers=self.on_edit_projector)
|
||||
self.one_toolbar.add_toolbar_action('delete_projector',
|
||||
text=translate('OpenLP.ProjectorManager', 'Delete Projector'),
|
||||
icon=':/general/general_delete.png',
|
||||
icon=UiIcons().delete,
|
||||
tooltip=translate('OpenLP.ProjectorManager', 'Delete selected projector.'),
|
||||
triggers=self.on_delete_projector)
|
||||
# Show source/view when projector connected
|
||||
self.one_toolbar.add_toolbar_action('source_view_projector',
|
||||
text=translate('OpenLP.ProjectorManager', 'Select Input Source'),
|
||||
icon=':/projector/projector_hdmi.png',
|
||||
icon=UiIcons().projector_hdmi,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Choose input source on selected projector.'),
|
||||
triggers=self.on_select_input)
|
||||
self.one_toolbar.add_toolbar_action('view_projector',
|
||||
text=translate('OpenLP.ProjectorManager', 'View Projector'),
|
||||
icon=':/system/system_about.png',
|
||||
icon=UiIcons().info,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'View selected projector information.'),
|
||||
triggers=self.on_status_projector)
|
||||
|
@ -134,28 +121,28 @@ class UiProjectorManager(object):
|
|||
self.one_toolbar.add_toolbar_action('connect_projector',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Connect to selected projector.'),
|
||||
icon=':/projector/projector_connect.png',
|
||||
icon=UiIcons().projector_connect,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Connect to selected projector.'),
|
||||
triggers=self.on_connect_projector)
|
||||
self.one_toolbar.add_toolbar_action('connect_projector_multiple',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Connect to selected projectors'),
|
||||
icon=':/projector/projector_connect_tiled.png',
|
||||
icon=UiIcons().projector_connect,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Connect to selected projectors.'),
|
||||
triggers=self.on_connect_projector)
|
||||
self.one_toolbar.add_toolbar_action('disconnect_projector',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Disconnect from selected projectors'),
|
||||
icon=':/projector/projector_disconnect.png',
|
||||
icon=UiIcons().projector_disconnect,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Disconnect from selected projector.'),
|
||||
triggers=self.on_disconnect_projector)
|
||||
self.one_toolbar.add_toolbar_action('disconnect_projector_multiple',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Disconnect from selected projector'),
|
||||
icon=':/projector/projector_disconnect_tiled.png',
|
||||
icon=UiIcons().projector_disconnect,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Disconnect from selected projectors.'),
|
||||
triggers=self.on_disconnect_projector)
|
||||
|
@ -163,26 +150,26 @@ class UiProjectorManager(object):
|
|||
self.one_toolbar.add_toolbar_action('poweron_projector',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Power on selected projector'),
|
||||
icon=':/projector/projector_power_on.png',
|
||||
icon=UiIcons().projector_on,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Power on selected projector.'),
|
||||
triggers=self.on_poweron_projector)
|
||||
self.one_toolbar.add_toolbar_action('poweron_projector_multiple',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Power on selected projector'),
|
||||
icon=':/projector/projector_power_on_tiled.png',
|
||||
icon=UiIcons().projector_on,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Power on selected projectors.'),
|
||||
triggers=self.on_poweron_projector)
|
||||
self.one_toolbar.add_toolbar_action('poweroff_projector',
|
||||
text=translate('OpenLP.ProjectorManager', 'Standby selected projector'),
|
||||
icon=':/projector/projector_power_off.png',
|
||||
icon=UiIcons().projector_off,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Put selected projector in standby.'),
|
||||
triggers=self.on_poweroff_projector)
|
||||
self.one_toolbar.add_toolbar_action('poweroff_projector_multiple',
|
||||
text=translate('OpenLP.ProjectorManager', 'Standby selected projector'),
|
||||
icon=':/projector/projector_power_off_tiled.png',
|
||||
icon=UiIcons().projector_off,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Put selected projectors in standby.'),
|
||||
triggers=self.on_poweroff_projector)
|
||||
|
@ -190,28 +177,28 @@ class UiProjectorManager(object):
|
|||
self.one_toolbar.add_toolbar_action('blank_projector',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Blank selected projector screen'),
|
||||
icon=':/projector/projector_blank.png',
|
||||
icon=UiIcons().blank,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Blank selected projector screen'),
|
||||
triggers=self.on_blank_projector)
|
||||
self.one_toolbar.add_toolbar_action('blank_projector_multiple',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Blank selected projectors screen'),
|
||||
icon=':/projector/projector_blank_tiled.png',
|
||||
icon=UiIcons().blank,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Blank selected projectors screen.'),
|
||||
triggers=self.on_blank_projector)
|
||||
self.one_toolbar.add_toolbar_action('show_projector',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Show selected projector screen'),
|
||||
icon=':/projector/projector_show.png',
|
||||
icon=UiIcons().desktop,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Show selected projector screen.'),
|
||||
triggers=self.on_show_projector)
|
||||
self.one_toolbar.add_toolbar_action('show_projector_multiple',
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Show selected projector screen'),
|
||||
icon=':/projector/projector_show_tiled.png',
|
||||
icon=UiIcons().desktop,
|
||||
tooltip=translate('OpenLP.ProjectorManager',
|
||||
'Show selected projectors screen.'),
|
||||
triggers=self.on_show_projector)
|
||||
|
@ -233,61 +220,61 @@ class UiProjectorManager(object):
|
|||
self.status_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'&View Projector Information'),
|
||||
icon=':/system/system_about.png',
|
||||
icon=UiIcons().info,
|
||||
triggers=self.on_status_projector)
|
||||
self.edit_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'&Edit Projector'),
|
||||
icon=':/projector/projector_edit.png',
|
||||
icon=UiIcons().edit,
|
||||
triggers=self.on_edit_projector)
|
||||
self.menu.addSeparator()
|
||||
self.connect_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'&Connect Projector'),
|
||||
icon=':/projector/projector_connect.png',
|
||||
icon=UiIcons().projector_connect,
|
||||
triggers=self.on_connect_projector)
|
||||
self.disconnect_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'D&isconnect Projector'),
|
||||
icon=':/projector/projector_disconnect.png',
|
||||
icon=UiIcons().projector_off,
|
||||
triggers=self.on_disconnect_projector)
|
||||
self.menu.addSeparator()
|
||||
self.poweron_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Power &On Projector'),
|
||||
icon=':/projector/projector_power_on.png',
|
||||
icon=UiIcons().projector_on,
|
||||
triggers=self.on_poweron_projector)
|
||||
self.poweroff_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Power O&ff Projector'),
|
||||
icon=':/projector/projector_power_off.png',
|
||||
icon=UiIcons().projector_off,
|
||||
triggers=self.on_poweroff_projector)
|
||||
self.menu.addSeparator()
|
||||
self.select_input_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Select &Input'),
|
||||
icon=':/projector/projector_hdmi.png',
|
||||
icon=UiIcons().projector_hdmi,
|
||||
triggers=self.on_select_input)
|
||||
self.edit_input_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'Edit Input Source'),
|
||||
icon=':/general/general_edit.png',
|
||||
icon=UiIcons().edit,
|
||||
triggers=self.on_edit_input)
|
||||
self.blank_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'&Blank Projector Screen'),
|
||||
icon=':/projector/projector_blank.png',
|
||||
icon=UiIcons().blank,
|
||||
triggers=self.on_blank_projector)
|
||||
self.show_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'&Show Projector Screen'),
|
||||
icon=':/projector/projector_show.png',
|
||||
icon=UiIcons().projector,
|
||||
triggers=self.on_show_projector)
|
||||
self.menu.addSeparator()
|
||||
self.delete_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ProjectorManager',
|
||||
'&Delete Projector'),
|
||||
icon=':/general/general_delete.png',
|
||||
icon=UiIcons().delete,
|
||||
triggers=self.on_delete_projector)
|
||||
self.update_icons()
|
||||
|
||||
|
@ -309,6 +296,27 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
self.projectordb = projectordb
|
||||
self.projector_list = []
|
||||
self.source_select_form = None
|
||||
# Dictionary of PJLinkUDP objects to listen for UDP broadcasts from PJLink 2+ projectors.
|
||||
# Key is port number that projectors use
|
||||
self.pjlink_udp = {}
|
||||
# Dict for matching projector status to display icon
|
||||
self.status_icons = {
|
||||
S_NOT_CONNECTED: UiIcons().projector_disconnect,
|
||||
S_CONNECTING: UiIcons().projector_connect,
|
||||
S_CONNECTED: UiIcons().projector_off,
|
||||
S_OFF: UiIcons().projector_off,
|
||||
S_INITIALIZE: UiIcons().projector_on,
|
||||
S_STANDBY: UiIcons().projector_off,
|
||||
S_WARMUP: UiIcons().projector_warmup,
|
||||
S_ON: UiIcons().projector_off,
|
||||
S_COOLDOWN: UiIcons().projector_cooldown,
|
||||
E_ERROR: UiIcons().projector_error,
|
||||
E_NETWORK: UiIcons().error,
|
||||
E_SOCKET_TIMEOUT: UiIcons().authentication,
|
||||
E_AUTHENTICATION: UiIcons().authentication,
|
||||
E_UNKNOWN_SOCKET_ERROR: UiIcons().error,
|
||||
E_NOT_CONNECTED: UiIcons().projector_disconnect
|
||||
}
|
||||
|
||||
def bootstrap_initialise(self):
|
||||
"""
|
||||
|
@ -322,12 +330,15 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
else:
|
||||
log.debug('Using existing ProjectorDB() instance')
|
||||
self.get_settings()
|
||||
self.pjlink_udp = PJLinkUDP(self.projector_list)
|
||||
|
||||
def bootstrap_post_set_up(self):
|
||||
"""
|
||||
Post-initialize setups.
|
||||
"""
|
||||
# Default PJLink port UDP socket
|
||||
log.debug('Creating PJLinkUDP listener for default port {port}'.format(port=PJLINK_PORT))
|
||||
self.pjlink_udp = {PJLINK_PORT: PJLinkUDP(port=PJLINK_PORT)}
|
||||
self.pjlink_udp[PJLINK_PORT].bind(PJLINK_PORT)
|
||||
# Set 1.5 second delay before loading all projectors
|
||||
if self.autostart:
|
||||
log.debug('Delaying 1.5 seconds before loading all projectors')
|
||||
|
@ -345,14 +356,10 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
Retrieve the saved settings
|
||||
"""
|
||||
log.debug('Updating ProjectorManager settings')
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
self.autostart = settings.value('connect on start')
|
||||
self.poll_time = settings.value('poll time')
|
||||
self.socket_timeout = settings.value('socket timeout')
|
||||
self.source_select_dialog_type = settings.value('source dialog type')
|
||||
settings.endGroup()
|
||||
del settings
|
||||
self.autostart = Settings().value('projector/connect on start')
|
||||
self.poll_time = Settings().value('projector/poll time')
|
||||
self.socket_timeout = Settings().value('projector/socket timeout')
|
||||
self.source_select_dialog_type = Settings().value('projector/source dialog type')
|
||||
|
||||
def context_menu(self, point):
|
||||
"""
|
||||
|
@ -373,22 +380,14 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
self.connect_action.setVisible(not visible)
|
||||
self.disconnect_action.setVisible(visible)
|
||||
self.status_action.setVisible(visible)
|
||||
if visible:
|
||||
self.select_input_action.setVisible(real_projector.link.power == S_ON)
|
||||
self.edit_input_action.setVisible(real_projector.link.power == S_ON)
|
||||
self.poweron_action.setVisible(real_projector.link.power == S_STANDBY)
|
||||
self.poweroff_action.setVisible(real_projector.link.power == S_ON)
|
||||
self.blank_action.setVisible(real_projector.link.power == S_ON and
|
||||
not real_projector.link.shutter)
|
||||
self.show_action.setVisible(real_projector.link.power == S_ON and
|
||||
real_projector.link.shutter)
|
||||
else:
|
||||
self.select_input_action.setVisible(False)
|
||||
self.edit_input_action.setVisible(False)
|
||||
self.poweron_action.setVisible(False)
|
||||
self.poweroff_action.setVisible(False)
|
||||
self.blank_action.setVisible(False)
|
||||
self.show_action.setVisible(False)
|
||||
self.select_input_action.setVisible(visible and real_projector.link.power == S_ON)
|
||||
self.edit_input_action.setVisible(visible and real_projector.link.power == S_ON)
|
||||
self.poweron_action.setVisible(visible and real_projector.link.power == S_STANDBY)
|
||||
self.poweroff_action.setVisible(visible and real_projector.link.power == S_ON)
|
||||
self.blank_action.setVisible(visible and real_projector.link.power == S_ON and
|
||||
not real_projector.link.shutter)
|
||||
self.show_action.setVisible(visible and real_projector.link.power == S_ON and
|
||||
real_projector.link.shutter)
|
||||
self.menu.projector = real_projector
|
||||
self.menu.exec(self.projector_list_widget.mapToGlobal(point))
|
||||
|
||||
|
@ -528,6 +527,13 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
projector.socket_timer.timeout.disconnect(projector.link.socket_abort)
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
# Disconnect signals from projector being deleted
|
||||
try:
|
||||
self.pjlink_udp[projector.link.port].data_received.disconnect(projector.link.get_buffer)
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
|
||||
# Rebuild projector list
|
||||
new_list = []
|
||||
for item in self.projector_list:
|
||||
if item.link.db_item.id == projector.link.db_item.id:
|
||||
|
@ -655,6 +661,21 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
data=projector.link.manufacturer)
|
||||
message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager', 'Model'),
|
||||
data=projector.link.model)
|
||||
message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager', 'PJLink Class'),
|
||||
data=projector.link.pjlink_class)
|
||||
if projector.link.pjlink_class != 1:
|
||||
message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager',
|
||||
'Software Version'),
|
||||
data=projector.link.sw_version)
|
||||
message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager',
|
||||
'Serial Number'),
|
||||
data=projector.link.serial_no)
|
||||
message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager',
|
||||
'Lamp Model Number'),
|
||||
data=projector.link.model_lamp)
|
||||
message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager',
|
||||
'Filter Model Number'),
|
||||
data=projector.link.model_filter)
|
||||
message += '<b>{title}</b>: {data}<br /><br />'.format(title=translate('OpenLP.ProjectorManager',
|
||||
'Other info'),
|
||||
data=projector.link.other_info)
|
||||
|
@ -668,20 +689,6 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
source=translate('OpenLP.ProjectorManager',
|
||||
'Current source input is'),
|
||||
selected=projector.link.source)
|
||||
if projector.link.pjlink_class == '2':
|
||||
# Information only available for PJLink Class 2 projectors
|
||||
message += '<b>{title}</b>: {data}<br /><br />'.format(title=translate('OpenLP.ProjectorManager',
|
||||
'Serial Number'),
|
||||
data=projector.serial_no)
|
||||
message += '<b>{title}</b>: {data}<br /><br />'.format(title=translate('OpenLP.ProjectorManager',
|
||||
'Software Version'),
|
||||
data=projector.sw_version)
|
||||
message += '<b>{title}</b>: {data}<br /><br />'.format(title=translate('OpenLP.ProjectorManager',
|
||||
'Lamp type'),
|
||||
data=projector.model_lamp)
|
||||
message += '<b>{title}</b>: {data}<br /><br />'.format(title=translate('OpenLP.ProjectorManager',
|
||||
'Filter type'),
|
||||
data=projector.model_filter)
|
||||
count = 1
|
||||
for item in projector.link.lamp:
|
||||
if item['On'] is None:
|
||||
|
@ -729,7 +736,7 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
"""
|
||||
item = ProjectorItem(link=self._add_projector(projector))
|
||||
item.db_item = projector
|
||||
item.icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[S_NOT_CONNECTED]))
|
||||
item.icon = QtGui.QIcon(self.status_icons[S_NOT_CONNECTED])
|
||||
widget = QtWidgets.QListWidgetItem(item.icon,
|
||||
item.link.name,
|
||||
self.projector_list_widget
|
||||
|
@ -741,6 +748,15 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
item.link.projectorAuthentication.connect(self.authentication_error)
|
||||
item.link.projectorNoAuthentication.connect(self.no_authentication_error)
|
||||
item.link.projectorUpdateIcons.connect(self.update_icons)
|
||||
# Connect UDP signal to projector instances with same port
|
||||
if item.link.port not in self.pjlink_udp:
|
||||
log.debug('Adding new PJLinkUDP listener fo port {port}'.format(port=item.link.port))
|
||||
self.pjlink_udp[item.link.port] = PJLinkUDP(port=item.link.port)
|
||||
self.pjlink_udp[item.link.port].bind(item.link.port)
|
||||
log.debug('Connecting PJLinkUDP port {port} signal to "{item}"'.format(port=item.link.port,
|
||||
item=item.link.name))
|
||||
self.pjlink_udp[item.link.port].data_received.connect(item.link.get_buffer)
|
||||
|
||||
self.projector_list.append(item)
|
||||
if start:
|
||||
item.link.connect_to_host()
|
||||
|
@ -816,7 +832,7 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
|
|||
return
|
||||
|
||||
item.status = status
|
||||
item.icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[status]))
|
||||
item.icon = self.status_icons[status]
|
||||
log.debug('({name}) Updating icon with {code}'.format(name=item.link.name, code=STATUS_CODE[status]))
|
||||
item.widget.setIcon(item.icon)
|
||||
return self.update_icons()
|
||||
|
@ -953,6 +969,10 @@ class ProjectorItem(QtCore.QObject):
|
|||
self.poll_time = None
|
||||
self.socket_timeout = None
|
||||
self.status = S_NOT_CONNECTED
|
||||
self.serial_no = None
|
||||
self.sw_version = None
|
||||
self.model_filter = None
|
||||
self.model_lamp = None
|
||||
super().__init__()
|
||||
|
||||
|
||||
|
|
|
@ -54,12 +54,12 @@ from PyQt5 import QtCore, QtNetwork
|
|||
|
||||
from openlp.core.common import qmd5_hash
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.projectors.constants import CONNECTION_ERRORS, PJLINK_CLASS, PJLINK_DEFAULT_CODES, PJLINK_ERRORS, \
|
||||
PJLINK_ERST_DATA, PJLINK_ERST_STATUS, PJLINK_MAX_PACKET, PJLINK_PREFIX, PJLINK_PORT, PJLINK_POWR_STATUS, \
|
||||
PJLINK_SUFFIX, PJLINK_VALID_CMD, PROJECTOR_STATE, STATUS_CODE, STATUS_MSG, QSOCKET_STATE, \
|
||||
E_AUTHENTICATION, E_CONNECTION_REFUSED, E_GENERAL, E_INVALID_DATA, E_NETWORK, E_NOT_CONNECTED, \
|
||||
E_SOCKET_TIMEOUT, \
|
||||
S_CONNECTED, S_CONNECTING, S_NOT_CONNECTED, S_OFF, S_OK, S_ON
|
||||
E_AUTHENTICATION, E_CONNECTION_REFUSED, E_GENERAL, E_NETWORK, E_NOT_CONNECTED, E_SOCKET_TIMEOUT, \
|
||||
S_CONNECTED, S_CONNECTING, S_NOT_CONNECTED, S_OFF, S_OK, S_ON, S_STANDBY
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log.debug('pjlink loaded')
|
||||
|
@ -79,38 +79,27 @@ class PJLinkUDP(QtNetwork.QUdpSocket):
|
|||
"""
|
||||
Socket service for PJLink UDP socket.
|
||||
"""
|
||||
def __init__(self, projector_list, port=PJLINK_PORT):
|
||||
|
||||
data_received = QtCore.pyqtSignal(QtNetwork.QHostAddress, int, str, name='udp_data') # host, port, data
|
||||
|
||||
def __init__(self, port=PJLINK_PORT):
|
||||
"""
|
||||
Socket services for PJLink UDP packets.
|
||||
|
||||
Since all UDP packets from any projector will come into the same
|
||||
port, process UDP packets here then route to the appropriate
|
||||
projector instance as needed.
|
||||
|
||||
:param port: UDP port to listen on
|
||||
"""
|
||||
# Keep track of currently defined projectors so we can route
|
||||
# inbound packets to the correct instance
|
||||
super().__init__()
|
||||
self.projector_list = projector_list
|
||||
self.port = port
|
||||
# Local defines
|
||||
self.ackn_list = {} # Replies from online projetors
|
||||
self.search_active = False
|
||||
self.search_time = 30000 # 30 seconds for allowed time
|
||||
self.search_timer = QtCore.QTimer()
|
||||
# New commands available in PJLink Class 2
|
||||
# ACKN/SRCH is processed here since it's used to find available projectors
|
||||
# Other commands are processed by the individual projector instances
|
||||
self.pjlink_udp_functions = {
|
||||
'ACKN': self.process_ackn, # Class 2, command is 'SRCH'
|
||||
'ERST': None, # Class 1/2
|
||||
'INPT': None, # Class 1/2
|
||||
'LKUP': None, # Class 2 (reply only - no cmd)
|
||||
'POWR': None, # Class 1/2
|
||||
'SRCH': self.process_srch # Class 2 (reply is ACKN)
|
||||
}
|
||||
|
||||
self.readyRead.connect(self.get_datagram)
|
||||
log.debug('(UDP) PJLinkUDP() Initialized')
|
||||
log.debug('(UDP) PJLinkUDP() Initialized for port {port}'.format(port=self.port))
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def get_datagram(self):
|
||||
|
@ -118,88 +107,24 @@ class PJLinkUDP(QtNetwork.QUdpSocket):
|
|||
Retrieve packet and basic checks
|
||||
"""
|
||||
log.debug('(UDP) get_datagram() - Receiving data')
|
||||
read = self.pendingDatagramSize()
|
||||
if read < 0:
|
||||
log.warn('(UDP) No data (-1)')
|
||||
read_size = self.pendingDatagramSize()
|
||||
if -1 == read_size:
|
||||
log.warning('(UDP) No data (-1)')
|
||||
return
|
||||
if read < 1:
|
||||
log.warn('(UDP) get_datagram() called when pending data size is 0')
|
||||
elif 0 == read_size:
|
||||
log.warning('(UDP) get_datagram() called when pending data size is 0')
|
||||
return
|
||||
data, peer_address, peer_port = self.readDatagram(self.pendingDatagramSize())
|
||||
elif read_size > PJLINK_MAX_PACKET:
|
||||
log.warning('(UDP) UDP Packet too large ({size} bytes)- ignoring'.format(size=read_size))
|
||||
return
|
||||
data_in, peer_host, peer_port = self.readDatagram(read_size)
|
||||
data = data_in.decode('utf-8') if isinstance(data_in, bytes) else data_in
|
||||
log.debug('(UDP) {size} bytes received from {adx} on port {port}'.format(size=len(data),
|
||||
adx=peer_address,
|
||||
port=peer_port))
|
||||
adx=peer_host.toString(),
|
||||
port=self.port))
|
||||
log.debug('(UDP) packet "{data}"'.format(data=data))
|
||||
if len(data) < 0:
|
||||
log.warn('(UDP) No data (-1)')
|
||||
return
|
||||
elif len(data) < 8:
|
||||
# Minimum packet is '%2CCCC='
|
||||
log.warn('(UDP) Invalid packet - not enough data')
|
||||
return
|
||||
elif data is None:
|
||||
log.warn('(UDP) No data (None)')
|
||||
return
|
||||
elif len(data) > PJLINK_MAX_PACKET:
|
||||
log.warn('(UDP) Invalid packet - length too long')
|
||||
return
|
||||
elif not data.startswith(PJLINK_PREFIX):
|
||||
log.warn('(UDP) Invalid packet - does not start with PJLINK_PREFIX')
|
||||
return
|
||||
elif data[1] != '2':
|
||||
log.warn('(UDP) Invalid packet - missing/invalid PJLink class version')
|
||||
return
|
||||
elif data[6] != '=':
|
||||
log.warn('(UDP) Invalid packet - separator missing')
|
||||
return
|
||||
# First two characters are header information we don't need at this time
|
||||
cmd, data = data[2:].split('=')
|
||||
if cmd not in self.pjlink_udp_functions:
|
||||
log.warn('(UDP) Invalid packet - not a valid PJLink UDP reply')
|
||||
return
|
||||
if self.pjlink_udp_functions[cmd] is not None:
|
||||
log.debug('(UDP) Processing {cmd} with "{data}"'.format(cmd=cmd, data=data))
|
||||
return self.pjlink_udp_functions[cmd](data=data, host=peer_address, port=peer_port)
|
||||
else:
|
||||
log.debug('(UDP) Checking projector list for ip {host} to process'.format(host=peer_address))
|
||||
for projector in self.projector_list:
|
||||
if peer_address == projector.ip:
|
||||
if cmd not in projector.pjlink_functions:
|
||||
log.error('(UDP) Could not find method to process '
|
||||
'"{cmd}" in {host}'.format(cmd=cmd, host=projector.ip))
|
||||
return
|
||||
log.debug('(UDP) Calling "{cmd}" in {host}'.format(cmd=cmd, host=projector.ip))
|
||||
return projector.pjlink_functions[cmd](data=data)
|
||||
log.warn('(UDP) Could not find projector with ip {ip} to process packet'.format(ip=peer_address))
|
||||
return
|
||||
|
||||
def process_ackn(self, data, host, port):
|
||||
"""
|
||||
Process the ACKN command.
|
||||
|
||||
:param data: Data in packet
|
||||
:param host: IP address of sending host
|
||||
:param port: Port received on
|
||||
"""
|
||||
log.debug('(UDP) Processing ACKN packet')
|
||||
if host not in self.ackn_list:
|
||||
log.debug('(UDP) Adding {host} to ACKN list'.format(host=host))
|
||||
self.ackn_list[host] = {'data': data,
|
||||
'port': port}
|
||||
else:
|
||||
log.warn('(UDP) Host {host} already replied - ignoring'.format(host=host))
|
||||
|
||||
def process_srch(self, data, host, port):
|
||||
"""
|
||||
Process the SRCH command.
|
||||
|
||||
SRCH is processed by terminals so we ignore any packet.
|
||||
|
||||
:param data: Data in packet
|
||||
:param host: IP address of sending host
|
||||
:param port: Port received on
|
||||
"""
|
||||
log.debug('(UDP) SRCH packet received - ignoring')
|
||||
log.debug('(UDP) Sending data_received signal to projectors')
|
||||
self.data_received.emit(peer_host, self.localPort(), data)
|
||||
return
|
||||
|
||||
def search_start(self):
|
||||
|
@ -207,7 +132,6 @@ class PJLinkUDP(QtNetwork.QUdpSocket):
|
|||
Start search for projectors on local network
|
||||
"""
|
||||
self.search_active = True
|
||||
self.ackn_list = {}
|
||||
# TODO: Send SRCH packet here
|
||||
self.search_timer.singleShot(self.search_time, self.search_stop)
|
||||
|
||||
|
@ -224,6 +148,8 @@ class PJLinkCommands(object):
|
|||
"""
|
||||
Process replies from PJLink projector.
|
||||
"""
|
||||
# List of IP addresses and mac addresses found via UDP search command
|
||||
ackn_list = []
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
|
@ -231,24 +157,47 @@ class PJLinkCommands(object):
|
|||
"""
|
||||
log.debug('PJlinkCommands(args={args} kwargs={kwargs})'.format(args=args, kwargs=kwargs))
|
||||
super().__init__()
|
||||
# Map PJLink command to method
|
||||
# Map PJLink command to method and include pjlink class version for this instance
|
||||
# Default initial pjlink class version is '1'
|
||||
self.pjlink_functions = {
|
||||
'AVMT': self.process_avmt,
|
||||
'CLSS': self.process_clss,
|
||||
'ERST': self.process_erst,
|
||||
'INFO': self.process_info,
|
||||
'INF1': self.process_inf1,
|
||||
'INF2': self.process_inf2,
|
||||
'INPT': self.process_inpt,
|
||||
'INST': self.process_inst,
|
||||
'LAMP': self.process_lamp,
|
||||
'NAME': self.process_name,
|
||||
'PJLINK': self.process_pjlink,
|
||||
'POWR': self.process_powr,
|
||||
'SNUM': self.process_snum,
|
||||
'SVER': self.process_sver,
|
||||
'RFIL': self.process_rfil,
|
||||
'RLMP': self.process_rlmp
|
||||
'ACKN': {"method": self.process_ackn, # Class 2 (command is SRCH)
|
||||
"version": "2"},
|
||||
'AVMT': {"method": self.process_avmt,
|
||||
"version": "1"},
|
||||
'CLSS': {"method": self.process_clss,
|
||||
"version": "1"},
|
||||
'ERST': {"method": self.process_erst,
|
||||
"version": "1"},
|
||||
'INFO': {"method": self.process_info,
|
||||
"version": "1"},
|
||||
'INF1': {"method": self.process_inf1,
|
||||
"version": "1"},
|
||||
'INF2': {"method": self.process_inf2,
|
||||
"version": "1"},
|
||||
'INPT': {"method": self.process_inpt,
|
||||
"version": "1"},
|
||||
'INST': {"method": self.process_inst,
|
||||
"version": "1"},
|
||||
'LAMP': {"method": self.process_lamp,
|
||||
"version": "1"},
|
||||
'LKUP': {"method": self.process_lkup, # Class 2 (reply only - no cmd)
|
||||
"version": "2"},
|
||||
'NAME': {"method": self.process_name,
|
||||
"version": "1"},
|
||||
'PJLINK': {"method": self.process_pjlink,
|
||||
"version": "1"},
|
||||
'POWR': {"method": self.process_powr,
|
||||
"version": "1"},
|
||||
'SNUM': {"method": self.process_snum,
|
||||
"version": "1"},
|
||||
'SRCH': {"method": self.process_srch, # Class 2 (reply is ACKN)
|
||||
"version": "2"},
|
||||
'SVER': {"method": self.process_sver,
|
||||
"version": "1"},
|
||||
'RFIL': {"method": self.process_rfil,
|
||||
"version": "1"},
|
||||
'RLMP': {"method": self.process_rlmp,
|
||||
"version": "1"}
|
||||
}
|
||||
|
||||
def reset_information(self):
|
||||
|
@ -284,9 +233,16 @@ class PJLinkCommands(object):
|
|||
if hasattr(self, 'socket_timer'):
|
||||
log.debug('({ip}): Calling socket_timer.stop()'.format(ip=self.entry.name))
|
||||
self.socket_timer.stop()
|
||||
if hasattr(self, 'status_timer'):
|
||||
log.debug('({ip}): Calling status_timer.stop()'.format(ip=self.entry.name))
|
||||
self.status_timer.stop()
|
||||
self.status_timer_checks = {}
|
||||
self.send_busy = False
|
||||
self.send_queue = []
|
||||
self.priority_queue = []
|
||||
# Reset default version in command routing dict
|
||||
for cmd in self.pjlink_functions:
|
||||
self.pjlink_functions[cmd]["version"] = PJLINK_VALID_CMD[cmd]['default']
|
||||
|
||||
def process_command(self, cmd, data):
|
||||
"""
|
||||
|
@ -320,20 +276,33 @@ class PJLinkCommands(object):
|
|||
return self.change_status(status=E_AUTHENTICATION)
|
||||
# Command checks already passed
|
||||
log.debug('({ip}) Calling function for {cmd}'.format(ip=self.entry.name, cmd=cmd))
|
||||
self.pjlink_functions[cmd](data=data)
|
||||
self.pjlink_functions[cmd]["method"](data=data)
|
||||
|
||||
def process_ackn(self, data):
|
||||
"""
|
||||
Process the ACKN command.
|
||||
|
||||
:param data: Data in packet
|
||||
"""
|
||||
# TODO: Have to rethink this one
|
||||
pass
|
||||
|
||||
def process_avmt(self, data):
|
||||
"""
|
||||
Process shutter and speaker status. See PJLink specification for format.
|
||||
Update self.mute (audio) and self.shutter (video shutter).
|
||||
10 = Shutter open, audio unchanged
|
||||
11 = Shutter closed, audio unchanged
|
||||
20 = Shutter unchanged, Audio normal
|
||||
21 = Shutter unchanged, Audio muted
|
||||
30 = Shutter closed, audio muted
|
||||
31 = Shutter open, audio normal
|
||||
30 = Shutter open, audio muted
|
||||
31 = Shutter closed, audio normal
|
||||
|
||||
:param data: Shutter and audio status
|
||||
"""
|
||||
settings = {'11': {'shutter': True, 'mute': self.mute},
|
||||
settings = {'10': {'shutter': False, 'mute': self.mute},
|
||||
'11': {'shutter': True, 'mute': self.mute},
|
||||
'20': {'shutter': self.shutter, 'mute': False},
|
||||
'21': {'shutter': self.shutter, 'mute': True},
|
||||
'30': {'shutter': False, 'mute': False},
|
||||
'31': {'shutter': True, 'mute': True}
|
||||
|
@ -348,6 +317,8 @@ class PJLinkCommands(object):
|
|||
self.shutter = shutter
|
||||
self.mute = mute
|
||||
if update_icons:
|
||||
if 'AVMT' in self.status_timer_checks:
|
||||
self.status_timer_delete('AVMT')
|
||||
self.projectorUpdateIcons.emit()
|
||||
return
|
||||
|
||||
|
@ -367,12 +338,13 @@ class PJLinkCommands(object):
|
|||
# Due to stupid projectors not following standards (Optoma, BenQ comes to mind),
|
||||
# AND the different responses that can be received, the semi-permanent way to
|
||||
# fix the class reply is to just remove all non-digit characters.
|
||||
try:
|
||||
clss = re.findall('\d', data)[0] # Should only be the first match
|
||||
except IndexError:
|
||||
chk = re.findall(r'\d', data)
|
||||
if len(chk) < 1:
|
||||
log.error('({ip}) No numbers found in class version reply "{data}" - '
|
||||
'defaulting to class "1"'.format(ip=self.entry.name, data=data))
|
||||
clss = '1'
|
||||
else:
|
||||
clss = chk[0] # Should only be the first match
|
||||
elif not data.isdigit():
|
||||
log.error('({ip}) NAN CLSS version reply "{data}" - '
|
||||
'defaulting to class "1"'.format(ip=self.entry.name, data=data))
|
||||
|
@ -383,6 +355,11 @@ class PJLinkCommands(object):
|
|||
log.debug('({ip}) Setting pjlink_class for this projector '
|
||||
'to "{data}"'.format(ip=self.entry.name,
|
||||
data=self.pjlink_class))
|
||||
# Update method class versions
|
||||
for cmd in self.pjlink_functions:
|
||||
if self.pjlink_class in PJLINK_VALID_CMD[cmd]['version']:
|
||||
self.pjlink_functions[cmd]['version'] = self.pjlink_class
|
||||
|
||||
# Since we call this one on first connect, setup polling from here
|
||||
if not self.no_poll:
|
||||
log.debug('({ip}) process_pjlink(): Starting timer'.format(ip=self.entry.name))
|
||||
|
@ -542,6 +519,16 @@ class PJLinkCommands(object):
|
|||
self.lamp = lamps
|
||||
return
|
||||
|
||||
def process_lkup(self, data):
|
||||
"""
|
||||
Process reply indicating remote is available for connection
|
||||
|
||||
:param data: Data packet from remote
|
||||
"""
|
||||
log.debug('({ip}) Processing LKUP command'.format(ip=self.entry.name))
|
||||
if Settings().value('projector/connect when LKUP received'):
|
||||
self.connect_to_host()
|
||||
|
||||
def process_name(self, data):
|
||||
"""
|
||||
Projector name set in projector.
|
||||
|
@ -615,6 +602,8 @@ class PJLinkCommands(object):
|
|||
else:
|
||||
# Log unknown status response
|
||||
log.warning('({ip}) Unknown power response: "{data}"'.format(ip=self.entry.name, data=data))
|
||||
if self.power in [S_ON, S_STANDBY, S_OFF] and 'POWR' in self.status_timer_checks:
|
||||
self.status_timer_delete(cmd='POWR')
|
||||
return
|
||||
|
||||
def process_rfil(self, data):
|
||||
|
@ -659,6 +648,17 @@ class PJLinkCommands(object):
|
|||
log.warning('({ip}) NOT saving serial number'.format(ip=self.entry.name))
|
||||
self.serial_no_received = data
|
||||
|
||||
def process_srch(self, data):
|
||||
"""
|
||||
Process the SRCH command.
|
||||
|
||||
SRCH is processed by terminals so we ignore any packet.
|
||||
|
||||
:param data: Data in packet
|
||||
"""
|
||||
log.warning("({ip}) SRCH packet detected - ignoring".format(ip=self.entry.ip))
|
||||
return
|
||||
|
||||
def process_sver(self, data):
|
||||
"""
|
||||
Software version of projector
|
||||
|
@ -707,15 +707,18 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
args=args,
|
||||
kwargs=kwargs))
|
||||
super().__init__()
|
||||
self.settings_section = 'projector'
|
||||
self.entry = projector
|
||||
self.ip = self.entry.ip
|
||||
self.qhost = QtNetwork.QHostAddress(self.ip)
|
||||
self.location = self.entry.location
|
||||
self.mac_adx = self.entry.mac_adx
|
||||
self.name = self.entry.name
|
||||
self.notes = self.entry.notes
|
||||
self.pin = self.entry.pin
|
||||
self.port = self.entry.port
|
||||
self.port = int(self.entry.port)
|
||||
self.pjlink_class = PJLINK_CLASS if self.entry.pjlink_class is None else self.entry.pjlink_class
|
||||
self.ackn_list = {} # Replies from online projectors (Class 2 option)
|
||||
self.db_update = False # Use to check if db needs to be updated prior to exiting
|
||||
# Poll time 20 seconds unless called with something else
|
||||
self.poll_time = 20000 if 'poll_time' not in kwargs else kwargs['poll_time'] * 1000
|
||||
|
@ -743,6 +746,11 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
self.socket_timer = QtCore.QTimer(self)
|
||||
self.socket_timer.setInterval(self.socket_timeout)
|
||||
self.socket_timer.timeout.connect(self.socket_abort)
|
||||
# Timer for doing status updates for commands that change state and should update faster
|
||||
self.status_timer_checks = {} # Keep track of events for the status timer
|
||||
self.status_timer = QtCore.QTimer(self)
|
||||
self.status_timer.setInterval(2000) # 2 second interval should be fast enough
|
||||
self.status_timer.timeout.connect(self.status_timer_update)
|
||||
# Socket status signals
|
||||
self.connected.connect(self.check_login)
|
||||
self.disconnected.connect(self.disconnect_from_host)
|
||||
|
@ -916,7 +924,10 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
"""
|
||||
Clean out extraneous stuff in the buffer.
|
||||
"""
|
||||
log.warning('({ip}) {message}'.format(ip=self.entry.name, message='Invalid packet' if msg is None else msg))
|
||||
log.debug('({ip}) Cleaning buffer - msg = "{message}"'.format(ip=self.entry.name, message=msg))
|
||||
if msg is None:
|
||||
msg = 'Invalid packet'
|
||||
log.warning('({ip}) {message}'.format(ip=self.entry.name, message=msg))
|
||||
self.send_busy = False
|
||||
trash_count = 0
|
||||
while self.bytesAvailable() > 0:
|
||||
|
@ -926,19 +937,21 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
count=trash_count))
|
||||
return
|
||||
|
||||
@QtCore.pyqtSlot(str, str)
|
||||
def get_buffer(self, data, ip):
|
||||
@QtCore.pyqtSlot(QtNetwork.QHostAddress, int, str, name='udp_data') # host, port, data
|
||||
def get_buffer(self, host, port, data):
|
||||
"""
|
||||
Get data from somewhere other than TCP socket
|
||||
|
||||
:param host: QHostAddress of sender
|
||||
:param port: Destination port
|
||||
:param data: Data to process. buffer must be formatted as a proper PJLink packet.
|
||||
:param ip: Destination IP for buffer.
|
||||
"""
|
||||
log.debug('({ip}) get_buffer(data="{buff}" ip="{ip_in}"'.format(ip=self.entry.name, buff=data, ip_in=ip))
|
||||
if ip is None:
|
||||
log.debug("({ip}) get_buffer() Don't know who data is for - exiting".format(ip=self.entry.name))
|
||||
return
|
||||
return self.get_data(buff=data, ip=ip)
|
||||
if (port == int(self.port)) and (host.isEqual(self.qhost)):
|
||||
log.debug('({ip}) Received data from {host}'.format(ip=self.entry.name, host=host.toString()))
|
||||
log.debug('({ip}) get_buffer(data="{buff}")'.format(ip=self.entry.name, buff=data))
|
||||
return self.get_data(buff=data)
|
||||
else:
|
||||
log.debug('({ip}) Ignoring data for {host} - not me'.format(ip=self.entry.name, host=host.toString()))
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def get_socket(self):
|
||||
|
@ -958,59 +971,73 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
log.debug('({ip}) get_socket(): No data available (-1)'.format(ip=self.entry.name))
|
||||
return self.receive_data_signal()
|
||||
self.socket_timer.stop()
|
||||
return self.get_data(buff=read, ip=self.ip)
|
||||
return self.get_data(buff=read)
|
||||
|
||||
def get_data(self, buff, ip=None):
|
||||
def get_data(self, buff, *args, **kwargs):
|
||||
"""
|
||||
Process received data
|
||||
|
||||
:param buff: Data to process.
|
||||
:param ip: (optional) Destination IP.
|
||||
"""
|
||||
# Since "self" is not available to options and the "ip" keyword is a "maybe I'll use in the future",
|
||||
# set to default here
|
||||
if ip is None:
|
||||
ip = self.ip
|
||||
log.debug('({ip}) get_data(ip="{ip_in}" buffer="{buff}"'.format(ip=self.entry.name, ip_in=ip, buff=buff))
|
||||
log.debug('({ip}) get_data(buffer="{buff}"'.format(ip=self.entry.name, buff=buff))
|
||||
ignore_class = 'ignore_class' in kwargs
|
||||
# NOTE: Class2 has changed to some values being UTF-8
|
||||
data_in = decode(buff, 'utf-8')
|
||||
if isinstance(buff, bytes):
|
||||
data_in = decode(buff, 'utf-8')
|
||||
else:
|
||||
data_in = buff
|
||||
data = data_in.strip()
|
||||
# Initial packet checks
|
||||
if (len(data) < 7):
|
||||
self._trash_buffer(msg='get_data(): Invalid packet - length')
|
||||
return self.receive_data_signal()
|
||||
elif len(data) > self.max_size:
|
||||
self._trash_buffer(msg='get_data(): Invalid packet - too long')
|
||||
self._trash_buffer(msg='get_data(): Invalid packet - too long ({length} bytes)'.format(length=len(data)))
|
||||
return self.receive_data_signal()
|
||||
elif not data.startswith(PJLINK_PREFIX):
|
||||
self._trash_buffer(msg='get_data(): Invalid packet - PJLink prefix missing')
|
||||
return self.receive_data_signal()
|
||||
elif '=' not in data:
|
||||
elif data[6] != '=' and data[8] != '=':
|
||||
# data[6] = standard command packet
|
||||
# data[8] = initial PJLink connection (after mangling)
|
||||
self._trash_buffer(msg='get_data(): Invalid reply - Does not have "="')
|
||||
return self.receive_data_signal()
|
||||
log.debug('({ip}) get_data(): Checking new data "{data}"'.format(ip=self.entry.name, data=data))
|
||||
header, data = data.split('=')
|
||||
log.debug('({ip}) get_data() header="{header}" data="{data}"'.format(ip=self.entry.name,
|
||||
header=header, data=data))
|
||||
# At this point, the header should contain:
|
||||
# "PVCCCC"
|
||||
# Where:
|
||||
# P = PJLINK_PREFIX
|
||||
# V = PJLink class or version
|
||||
# C = PJLink command
|
||||
version, cmd = header[1], header[2:].upper()
|
||||
log.debug('({ip}) get_data() version="{version}" cmd="{cmd}"'.format(ip=self.entry.name,
|
||||
version=version, cmd=cmd))
|
||||
# TODO: Below commented for now since it seems to cause issues with testing some invalid data.
|
||||
# Revisit after more refactoring is finished.
|
||||
'''
|
||||
try:
|
||||
version, cmd = header[1], header[2:].upper()
|
||||
log.debug('({ip}) get_data() version="{version}" cmd="{cmd}"'.format(ip=self.entry.name,
|
||||
version=version, cmd=cmd))
|
||||
except ValueError as e:
|
||||
self.change_status(E_INVALID_DATA)
|
||||
log.warning('({ip}) get_data(): Received data: "{data}"'.format(ip=self.entry.name, data=data_in))
|
||||
self._trash_buffer('get_data(): Expected header + command + data')
|
||||
return self.receive_data_signal()
|
||||
'''
|
||||
if cmd not in PJLINK_VALID_CMD:
|
||||
log.warning('({ip}) get_data(): Invalid packet - unknown command "{data}"'.format(ip=self.entry.name,
|
||||
data=cmd))
|
||||
self._trash_buffer(msg='get_data(): Unknown command "{data}"'.format(data=cmd))
|
||||
self._trash_buffer('get_data(): Invalid packet - unknown command "{data}"'.format(data=cmd))
|
||||
return self.receive_data_signal()
|
||||
if int(self.pjlink_class) < int(version):
|
||||
log.warning('({ip}) get_data(): Projector returned class reply higher '
|
||||
'than projector stated class'.format(ip=self.entry.name))
|
||||
elif version not in PJLINK_VALID_CMD[cmd]['version']:
|
||||
self._trash_buffer(msg='get_data() Command reply version does not match a valid command version')
|
||||
return self.receive_data_signal()
|
||||
elif int(self.pjlink_class) < int(version):
|
||||
if not ignore_class:
|
||||
log.warning('({ip}) get_data(): Projector returned class reply higher '
|
||||
'than projector stated class'.format(ip=self.entry.name))
|
||||
self.process_command(cmd, data)
|
||||
return self.receive_data_signal()
|
||||
|
||||
|
@ -1063,16 +1090,7 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
data=opts,
|
||||
salt='' if salt is None
|
||||
else ' with hash'))
|
||||
cmd_ver = PJLINK_VALID_CMD[cmd]['version']
|
||||
if self.pjlink_class in PJLINK_VALID_CMD[cmd]['version']:
|
||||
header = PJLINK_HEADER.format(linkclass=self.pjlink_class)
|
||||
elif len(cmd_ver) == 1 and (int(cmd_ver[0]) < int(self.pjlink_class)):
|
||||
# Typically a class 1 only command
|
||||
header = PJLINK_HEADER.format(linkclass=cmd_ver[0])
|
||||
else:
|
||||
# NOTE: Once we get to version 3 then think about looping
|
||||
log.error('({ip}): send_command(): PJLink class check issue? Aborting'.format(ip=self.entry.name))
|
||||
return
|
||||
header = PJLINK_HEADER.format(linkclass=self.pjlink_functions[cmd]["version"])
|
||||
out = '{salt}{header}{command} {options}{suffix}'.format(salt="" if salt is None else salt,
|
||||
header=header,
|
||||
command=cmd,
|
||||
|
@ -1098,11 +1116,18 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
"""
|
||||
Socket interface to send data. If data=None, then check queue.
|
||||
|
||||
:param data: Immediate data to send
|
||||
:param data: Immediate data to send (Optional)
|
||||
:param utf8: Send as UTF-8 string otherwise send as ASCII string
|
||||
"""
|
||||
# Funny looking data check, but it's a quick check for data=None
|
||||
log.debug('({ip}) _send_command(data="{data}")'.format(ip=self.entry.name, data=data.strip() if data else data))
|
||||
if not data and not self.priority_queue and not self.send_queue:
|
||||
log.debug('({ip}) _send_command(): Nothing to send - returning'.format(ip=self.entry.name))
|
||||
return
|
||||
log.debug('({ip}) _send_command(data="{data}")'.format(ip=self.entry.name,
|
||||
data=data.strip() if data else data))
|
||||
log.debug('({ip}) _send_command(): priority_queue: {queue}'.format(ip=self.entry.name,
|
||||
queue=self.priority_queue))
|
||||
log.debug('({ip}) _send_command(): send_queue: {queue}'.format(ip=self.entry.name,
|
||||
queue=self.send_queue))
|
||||
conn_state = STATUS_CODE[QSOCKET_STATE[self.state()]]
|
||||
log.debug('({ip}) _send_command(): Connection status: {data}'.format(ip=self.entry.name,
|
||||
data=conn_state))
|
||||
|
@ -1140,9 +1165,9 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
self.waitForBytesWritten(2000) # 2 seconds should be enough
|
||||
if sent == -1:
|
||||
# Network error?
|
||||
log.warning('({ip}) _send_command(): -1 received - disconnecting from host'.format(ip=self.entry.name))
|
||||
self.change_status(E_NETWORK,
|
||||
translate('OpenLP.PJLink', 'Error while sending data to projector'))
|
||||
log.warning('({ip}) _send_command(): -1 received - disconnecting from host'.format(ip=self.entry.name))
|
||||
self.disconnect_from_host()
|
||||
|
||||
def connect_to_host(self):
|
||||
|
@ -1155,7 +1180,7 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
return
|
||||
self.error_status = S_OK
|
||||
self.change_status(S_CONNECTING)
|
||||
self.connectToHost(self.ip, self.port if isinstance(self.port, int) else int(self.port))
|
||||
self.connectToHost(self.ip, self.port)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def disconnect_from_host(self, abort=False):
|
||||
|
@ -1168,25 +1193,27 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
self.abort()
|
||||
else:
|
||||
log.warning('({ip}) disconnect_from_host(): Not connected'.format(ip=self.entry.name))
|
||||
self.disconnectFromHost()
|
||||
try:
|
||||
self.readyRead.disconnect(self.get_socket)
|
||||
except TypeError:
|
||||
pass
|
||||
log.debug('({ip}) disconnect_from_host() '
|
||||
# Since we already know what's happening, just log it for reference.
|
||||
log.debug('({ip}) disconnect_from_host(): Issue detected with '
|
||||
'readyRead.disconnect'.format(ip=self.entry.name))
|
||||
log.debug('({ip}) disconnect_from_host(): '
|
||||
'Current status {data}'.format(ip=self.entry.name, data=self._get_status(self.status_connect)[0]))
|
||||
self.disconnectFromHost()
|
||||
if abort:
|
||||
self.change_status(E_NOT_CONNECTED)
|
||||
else:
|
||||
self.change_status(S_NOT_CONNECTED)
|
||||
self.reset_information()
|
||||
|
||||
def get_av_mute_status(self):
|
||||
def get_av_mute_status(self, priority=False):
|
||||
"""
|
||||
Send command to retrieve shutter status.
|
||||
"""
|
||||
log.debug('({ip}) Sending AVMT command'.format(ip=self.entry.name))
|
||||
return self.send_command(cmd='AVMT')
|
||||
return self.send_command(cmd='AVMT', priority=priority)
|
||||
|
||||
def get_available_inputs(self):
|
||||
"""
|
||||
|
@ -1244,12 +1271,14 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
log.debug('({ip}) Sending INFO command'.format(ip=self.entry.name))
|
||||
return self.send_command(cmd='INFO')
|
||||
|
||||
def get_power_status(self):
|
||||
def get_power_status(self, priority=False):
|
||||
"""
|
||||
Send command to retrieve power status.
|
||||
|
||||
:param priority: (OPTIONAL) Send in priority queue
|
||||
"""
|
||||
log.debug('({ip}) Sending POWR command'.format(ip=self.entry.name))
|
||||
return self.send_command(cmd='POWR')
|
||||
return self.send_command(cmd='POWR', priority=priority)
|
||||
|
||||
def set_input_source(self, src=None):
|
||||
"""
|
||||
|
@ -1273,6 +1302,7 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
"""
|
||||
log.debug('({ip}) Setting POWR to 1 (on)'.format(ip=self.entry.name))
|
||||
self.send_command(cmd='POWR', opts='1', priority=True)
|
||||
self.status_timer_add(cmd='POWR', callback=self.get_power_status)
|
||||
self.poll_loop()
|
||||
|
||||
def set_power_off(self):
|
||||
|
@ -1281,6 +1311,7 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
"""
|
||||
log.debug('({ip}) Setting POWR to 0 (standby)'.format(ip=self.entry.name))
|
||||
self.send_command(cmd='POWR', opts='0', priority=True)
|
||||
self.status_timer_add(cmd='POWR', callback=self.get_power_status)
|
||||
self.poll_loop()
|
||||
|
||||
def set_shutter_closed(self):
|
||||
|
@ -1289,6 +1320,7 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
"""
|
||||
log.debug('({ip}) Setting AVMT to 11 (shutter closed)'.format(ip=self.entry.name))
|
||||
self.send_command(cmd='AVMT', opts='11', priority=True)
|
||||
self.status_timer_add('AVMT', self.get_av_mute_status)
|
||||
self.poll_loop()
|
||||
|
||||
def set_shutter_open(self):
|
||||
|
@ -1297,8 +1329,51 @@ class PJLink(QtNetwork.QTcpSocket, PJLinkCommands):
|
|||
"""
|
||||
log.debug('({ip}) Setting AVMT to "10" (shutter open)'.format(ip=self.entry.name))
|
||||
self.send_command(cmd='AVMT', opts='10', priority=True)
|
||||
self.status_timer_add('AVMT', self.get_av_mute_status)
|
||||
self.poll_loop()
|
||||
self.projectorUpdateIcons.emit()
|
||||
|
||||
def status_timer_add(self, cmd, callback):
|
||||
"""
|
||||
Add a callback to the status timer.
|
||||
|
||||
:param cmd: PJLink command associated with callback
|
||||
:param callback: Method to call
|
||||
"""
|
||||
if cmd in self.status_timer_checks:
|
||||
log.warning('({ip}) "{cmd}" already in checks - returning'.format(ip=self.entry.name, cmd=cmd))
|
||||
return
|
||||
log.debug('({ip}) Adding "{cmd}" callback for status timer'.format(ip=self.entry.name, cmd=cmd))
|
||||
if not self.status_timer.isActive():
|
||||
self.status_timer.start()
|
||||
self.status_timer_checks[cmd] = callback
|
||||
|
||||
def status_timer_delete(self, cmd):
|
||||
"""
|
||||
Delete a callback from the status timer.
|
||||
|
||||
:param cmd: PJLink command associated with callback
|
||||
:param callback: Method to call
|
||||
"""
|
||||
if cmd not in self.status_timer_checks:
|
||||
log.warning('({ip}) "{cmd}" not listed in status timer - returning'.format(ip=self.entry.name, cmd=cmd))
|
||||
return
|
||||
log.debug('({ip}) Removing "{cmd}" from status timer'.format(ip=self.entry.name, cmd=cmd))
|
||||
self.status_timer_checks.pop(cmd)
|
||||
if not self.status_timer_checks:
|
||||
self.status_timer.stop()
|
||||
|
||||
def status_timer_update(self):
|
||||
"""
|
||||
Call methods defined in status_timer_checks for updates
|
||||
"""
|
||||
if not self.status_timer_checks:
|
||||
log.warning('({ip}) status_timer_update() called when no callbacks - '
|
||||
'Race condition?'.format(ip=self.entry.name))
|
||||
self.status_timer.stop()
|
||||
return
|
||||
for cmd, callback in self.status_timer_checks.items():
|
||||
log.debug('({ip}) Status update call for {cmd}'.format(ip=self.entry.name, cmd=cmd))
|
||||
callback(priority=True)
|
||||
|
||||
def receive_data_signal(self):
|
||||
"""
|
||||
|
|
|
@ -29,6 +29,7 @@ from PyQt5 import QtWidgets
|
|||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import SettingsTab
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.projectors import DialogSourceStyle
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -45,7 +46,7 @@ class ProjectorTab(SettingsTab):
|
|||
|
||||
:param parent: Parent widget
|
||||
"""
|
||||
self.icon_path = ':/projector/projector_manager.png'
|
||||
self.icon_path = UiIcons().projector
|
||||
projector_translated = translate('OpenLP.ProjectorTab', 'Projector')
|
||||
super(ProjectorTab, self).__init__(parent, 'Projector', projector_translated)
|
||||
|
||||
|
@ -89,6 +90,10 @@ class ProjectorTab(SettingsTab):
|
|||
self.connect_box_layout.addRow(self.dialog_type_label, self.dialog_type_combo_box)
|
||||
self.left_layout.addStretch()
|
||||
self.dialog_type_combo_box.activated.connect(self.on_dialog_type_combo_box_changed)
|
||||
# Connect on LKUP packet received (PJLink v2+ only)
|
||||
self.connect_on_linkup = QtWidgets.QCheckBox(self.connect_box)
|
||||
self.connect_on_linkup.setObjectName('connect_on_linkup')
|
||||
self.connect_box_layout.addRow(self.connect_on_linkup)
|
||||
|
||||
def retranslateUi(self):
|
||||
"""
|
||||
|
@ -109,30 +114,28 @@ class ProjectorTab(SettingsTab):
|
|||
translate('OpenLP.ProjectorTab', 'Tabbed dialog box'))
|
||||
self.dialog_type_combo_box.setItemText(DialogSourceStyle.Single,
|
||||
translate('OpenLP.ProjectorTab', 'Single dialog box'))
|
||||
self.connect_on_linkup.setText(
|
||||
translate('OpenLP.ProjectorTab', 'Connect to projector when LINKUP received (v2 only)'))
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
Load the projector settings on startup
|
||||
"""
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
self.connect_on_startup.setChecked(settings.value('connect on start'))
|
||||
self.socket_timeout_spin_box.setValue(settings.value('socket timeout'))
|
||||
self.socket_poll_spin_box.setValue(settings.value('poll time'))
|
||||
self.dialog_type_combo_box.setCurrentIndex(settings.value('source dialog type'))
|
||||
settings.endGroup()
|
||||
self.connect_on_startup.setChecked(Settings().value('projector/connect on start'))
|
||||
self.socket_timeout_spin_box.setValue(Settings().value('projector/socket timeout'))
|
||||
self.socket_poll_spin_box.setValue(Settings().value('projector/poll time'))
|
||||
self.dialog_type_combo_box.setCurrentIndex(Settings().value('projector/source dialog type'))
|
||||
self.connect_on_linkup.setChecked(Settings().value('projector/connect when LKUP received'))
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Save the projector settings
|
||||
"""
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.setValue('connect on start', self.connect_on_startup.isChecked())
|
||||
settings.setValue('socket timeout', self.socket_timeout_spin_box.value())
|
||||
settings.setValue('poll time', self.socket_poll_spin_box.value())
|
||||
settings.setValue('source dialog type', self.dialog_type_combo_box.currentIndex())
|
||||
settings.endGroup()
|
||||
Settings().setValue('projector/connect on start', self.connect_on_startup.isChecked())
|
||||
Settings().setValue('projector/socket timeout', self.socket_timeout_spin_box.value())
|
||||
Settings().setValue('projector/poll time', self.socket_poll_spin_box.value())
|
||||
Settings().setValue('projector/source dialog type', self.dialog_type_combo_box.currentIndex())
|
||||
Settings().setValue('projector/connect when LKUP received', self.connect_on_linkup.isChecked())
|
||||
|
||||
def on_dialog_type_combo_box_changed(self):
|
||||
self.dialog_type = self.dialog_type_combo_box.currentIndex()
|
||||
|
|
|
@ -53,12 +53,13 @@ class Server(QtCore.QObject, LogMixin):
|
|||
if 'OpenLP' in args:
|
||||
args.remove('OpenLP')
|
||||
# Yes, there is.
|
||||
self.out_stream = QtCore.QTextStream(self.out_socket)
|
||||
self.out_stream.setCodec('UTF-8')
|
||||
self.out_socket.write(str.encode("".join(args)))
|
||||
if not self.out_socket.waitForBytesWritten(10):
|
||||
raise Exception(str(self.out_socket.errorString()))
|
||||
self.out_socket.disconnectFromServer()
|
||||
if len(args):
|
||||
self.out_stream = QtCore.QTextStream(self.out_socket)
|
||||
self.out_stream.setCodec('UTF-8')
|
||||
self.out_socket.write(str.encode("".join(args)))
|
||||
if not self.out_socket.waitForBytesWritten(10):
|
||||
raise Exception(str(self.out_socket.errorString()))
|
||||
self.out_socket.disconnectFromServer()
|
||||
|
||||
def start_server(self):
|
||||
"""
|
||||
|
|
|
@ -123,4 +123,4 @@ __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay', 'SlideCon
|
|||
'ServiceNoteForm', 'ThemeLayoutForm', 'FileRenameForm', 'StartTimeForm', 'MainDisplay',
|
||||
'SlideController', 'DisplayController', 'GeneralTab', 'ThemesTab', 'AdvancedTab', 'PluginForm',
|
||||
'FormattingTagForm', 'ShortcutListForm', 'FormattingTagController', 'SingleColumnTableWidget',
|
||||
'ProjectorManager', 'ProjectorTab', 'ProjectorEditForm']
|
||||
'ProjectorManager', 'ProjectorTab', 'ProjectorEditForm', 'LiveController', 'PreviewController']
|
||||
|
|
|
@ -24,8 +24,8 @@ import datetime
|
|||
from PyQt5 import QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button, create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class UiAboutDialog(object):
|
||||
|
@ -40,7 +40,7 @@ class UiAboutDialog(object):
|
|||
:param about_dialog: The QDialog object to set up.
|
||||
"""
|
||||
about_dialog.setObjectName('about_dialog')
|
||||
about_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
about_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
self.about_dialog_layout = QtWidgets.QVBoxLayout(about_dialog)
|
||||
self.about_dialog_layout.setContentsMargins(8, 8, 8, 8)
|
||||
self.about_dialog_layout.setObjectName('about_dialog_layout')
|
||||
|
@ -78,7 +78,7 @@ class UiAboutDialog(object):
|
|||
self.license_tab_layout.addWidget(self.license_text_edit)
|
||||
self.about_notebook.addTab(self.license_tab, '')
|
||||
self.about_dialog_layout.addWidget(self.about_notebook)
|
||||
self.volunteer_button = create_button(None, 'volunteer_button', icon=':/system/system_volunteer.png')
|
||||
self.volunteer_button = create_button(None, 'volunteer_button', icon=UiIcons().volunteer)
|
||||
self.button_box = create_button_box(about_dialog, 'button_box', ['close'], [self.volunteer_button])
|
||||
self.about_dialog_layout.addWidget(self.button_box)
|
||||
self.retranslate_ui(about_dialog)
|
||||
|
|
|
@ -33,8 +33,10 @@ from openlp.core.common.i18n import UiStrings, format_time, translate
|
|||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import SettingsTab, build_icon
|
||||
from openlp.core.ui.style import HAS_DARK_STYLE
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.edits import PathEdit
|
||||
from openlp.core.widgets.enums import PathEditType
|
||||
from openlp.core.widgets.widgets import ProxyWidget
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -49,7 +51,7 @@ class AdvancedTab(SettingsTab):
|
|||
Initialise the settings tab
|
||||
"""
|
||||
self.data_exists = False
|
||||
self.icon_path = ':/system/system_settings.png'
|
||||
self.icon_path = UiIcons().settings
|
||||
self.autoscroll_map = [None, {'dist': -1, 'pos': 0}, {'dist': -1, 'pos': 1}, {'dist': -1, 'pos': 2},
|
||||
{'dist': 0, 'pos': 0}, {'dist': 0, 'pos': 1}, {'dist': 0, 'pos': 2},
|
||||
{'dist': 0, 'pos': 3}, {'dist': 1, 'pos': 0}, {'dist': 1, 'pos': 1},
|
||||
|
@ -76,6 +78,9 @@ class AdvancedTab(SettingsTab):
|
|||
self.media_plugin_check_box = QtWidgets.QCheckBox(self.ui_group_box)
|
||||
self.media_plugin_check_box.setObjectName('media_plugin_check_box')
|
||||
self.ui_layout.addRow(self.media_plugin_check_box)
|
||||
self.hide_mouse_check_box = QtWidgets.QCheckBox(self.ui_group_box)
|
||||
self.hide_mouse_check_box.setObjectName('hide_mouse_check_box')
|
||||
self.ui_layout.addWidget(self.hide_mouse_check_box)
|
||||
self.double_click_live_check_box = QtWidgets.QCheckBox(self.ui_group_box)
|
||||
self.double_click_live_check_box.setObjectName('double_click_live_check_box')
|
||||
self.ui_layout.addRow(self.double_click_live_check_box)
|
||||
|
@ -116,43 +121,8 @@ class AdvancedTab(SettingsTab):
|
|||
self.use_dark_style_checkbox = QtWidgets.QCheckBox(self.ui_group_box)
|
||||
self.use_dark_style_checkbox.setObjectName('use_dark_style_checkbox')
|
||||
self.ui_layout.addRow(self.use_dark_style_checkbox)
|
||||
# Data Directory
|
||||
self.data_directory_group_box = QtWidgets.QGroupBox(self.left_column)
|
||||
self.data_directory_group_box.setObjectName('data_directory_group_box')
|
||||
self.data_directory_layout = QtWidgets.QFormLayout(self.data_directory_group_box)
|
||||
self.data_directory_layout.setObjectName('data_directory_layout')
|
||||
self.data_directory_new_label = QtWidgets.QLabel(self.data_directory_group_box)
|
||||
self.data_directory_new_label.setObjectName('data_directory_current_label')
|
||||
self.data_directory_path_edit = PathEdit(self.data_directory_group_box, path_type=PathEditType.Directories,
|
||||
default_path=AppLocation.get_directory(AppLocation.DataDir))
|
||||
self.data_directory_layout.addRow(self.data_directory_new_label, self.data_directory_path_edit)
|
||||
self.new_data_directory_has_files_label = QtWidgets.QLabel(self.data_directory_group_box)
|
||||
self.new_data_directory_has_files_label.setObjectName('new_data_directory_has_files_label')
|
||||
self.new_data_directory_has_files_label.setWordWrap(True)
|
||||
self.data_directory_cancel_button = QtWidgets.QToolButton(self.data_directory_group_box)
|
||||
self.data_directory_cancel_button.setObjectName('data_directory_cancel_button')
|
||||
self.data_directory_cancel_button.setIcon(build_icon(':/general/general_delete.png'))
|
||||
self.data_directory_copy_check_layout = QtWidgets.QHBoxLayout()
|
||||
self.data_directory_copy_check_layout.setObjectName('data_directory_copy_check_layout')
|
||||
self.data_directory_copy_check_box = QtWidgets.QCheckBox(self.data_directory_group_box)
|
||||
self.data_directory_copy_check_box.setObjectName('data_directory_copy_check_box')
|
||||
self.data_directory_copy_check_layout.addWidget(self.data_directory_copy_check_box)
|
||||
self.data_directory_copy_check_layout.addStretch()
|
||||
self.data_directory_copy_check_layout.addWidget(self.data_directory_cancel_button)
|
||||
self.data_directory_layout.addRow(self.data_directory_copy_check_layout)
|
||||
self.data_directory_layout.addRow(self.new_data_directory_has_files_label)
|
||||
self.left_layout.addWidget(self.data_directory_group_box)
|
||||
# Hide mouse
|
||||
self.hide_mouse_group_box = QtWidgets.QGroupBox(self.right_column)
|
||||
self.hide_mouse_group_box.setObjectName('hide_mouse_group_box')
|
||||
self.hide_mouse_layout = QtWidgets.QVBoxLayout(self.hide_mouse_group_box)
|
||||
self.hide_mouse_layout.setObjectName('hide_mouse_layout')
|
||||
self.hide_mouse_check_box = QtWidgets.QCheckBox(self.hide_mouse_group_box)
|
||||
self.hide_mouse_check_box.setObjectName('hide_mouse_check_box')
|
||||
self.hide_mouse_layout.addWidget(self.hide_mouse_check_box)
|
||||
self.right_layout.addWidget(self.hide_mouse_group_box)
|
||||
# Service Item Slide Limits
|
||||
self.slide_group_box = QtWidgets.QGroupBox(self.right_column)
|
||||
self.slide_group_box = QtWidgets.QGroupBox(self.left_column)
|
||||
self.slide_group_box.setObjectName('slide_group_box')
|
||||
self.slide_layout = QtWidgets.QVBoxLayout(self.slide_group_box)
|
||||
self.slide_layout.setObjectName('slide_layout')
|
||||
|
@ -168,7 +138,33 @@ class AdvancedTab(SettingsTab):
|
|||
self.next_item_radio_button = QtWidgets.QRadioButton(self.slide_group_box)
|
||||
self.next_item_radio_button.setObjectName('next_item_radio_button')
|
||||
self.slide_layout.addWidget(self.next_item_radio_button)
|
||||
self.right_layout.addWidget(self.slide_group_box)
|
||||
self.left_layout.addWidget(self.slide_group_box)
|
||||
# Data Directory
|
||||
self.data_directory_group_box = QtWidgets.QGroupBox(self.left_column)
|
||||
self.data_directory_group_box.setObjectName('data_directory_group_box')
|
||||
self.data_directory_layout = QtWidgets.QFormLayout(self.data_directory_group_box)
|
||||
self.data_directory_layout.setObjectName('data_directory_layout')
|
||||
self.data_directory_new_label = QtWidgets.QLabel(self.data_directory_group_box)
|
||||
self.data_directory_new_label.setObjectName('data_directory_current_label')
|
||||
self.data_directory_path_edit = PathEdit(self.data_directory_group_box, path_type=PathEditType.Directories,
|
||||
default_path=AppLocation.get_directory(AppLocation.DataDir))
|
||||
self.data_directory_layout.addRow(self.data_directory_new_label, self.data_directory_path_edit)
|
||||
self.new_data_directory_has_files_label = QtWidgets.QLabel(self.data_directory_group_box)
|
||||
self.new_data_directory_has_files_label.setObjectName('new_data_directory_has_files_label')
|
||||
self.new_data_directory_has_files_label.setWordWrap(True)
|
||||
self.data_directory_cancel_button = QtWidgets.QToolButton(self.data_directory_group_box)
|
||||
self.data_directory_cancel_button.setObjectName('data_directory_cancel_button')
|
||||
self.data_directory_cancel_button.setIcon(UiIcons().delete)
|
||||
self.data_directory_copy_check_layout = QtWidgets.QHBoxLayout()
|
||||
self.data_directory_copy_check_layout.setObjectName('data_directory_copy_check_layout')
|
||||
self.data_directory_copy_check_box = QtWidgets.QCheckBox(self.data_directory_group_box)
|
||||
self.data_directory_copy_check_box.setObjectName('data_directory_copy_check_box')
|
||||
self.data_directory_copy_check_layout.addWidget(self.data_directory_copy_check_box)
|
||||
self.data_directory_copy_check_layout.addStretch()
|
||||
self.data_directory_copy_check_layout.addWidget(self.data_directory_cancel_button)
|
||||
self.data_directory_layout.addRow(self.data_directory_copy_check_layout)
|
||||
self.data_directory_layout.addRow(self.new_data_directory_has_files_label)
|
||||
self.left_layout.addWidget(self.data_directory_group_box)
|
||||
# Display Workarounds
|
||||
self.display_workaround_group_box = QtWidgets.QGroupBox(self.right_column)
|
||||
self.display_workaround_group_box.setObjectName('display_workaround_group_box')
|
||||
|
@ -211,7 +207,7 @@ class AdvancedTab(SettingsTab):
|
|||
self.service_name_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(r'[^/\\?*|<>\[\]":+]+'), self))
|
||||
self.service_name_revert_button = QtWidgets.QToolButton(self.service_name_group_box)
|
||||
self.service_name_revert_button.setObjectName('service_name_revert_button')
|
||||
self.service_name_revert_button.setIcon(build_icon(':/general/general_revert.png'))
|
||||
self.service_name_revert_button.setIcon(UiIcons().undo)
|
||||
self.service_name_button_layout = QtWidgets.QHBoxLayout()
|
||||
self.service_name_button_layout.setObjectName('service_name_button_layout')
|
||||
self.service_name_button_layout.addWidget(self.service_name_edit)
|
||||
|
@ -223,6 +219,9 @@ class AdvancedTab(SettingsTab):
|
|||
self.service_name_example.setObjectName('service_name_example')
|
||||
self.service_name_layout.addRow(self.service_name_example_label, self.service_name_example)
|
||||
self.right_layout.addWidget(self.service_name_group_box)
|
||||
# Proxies
|
||||
self.proxy_widget = ProxyWidget(self.right_column)
|
||||
self.right_layout.addWidget(self.proxy_widget)
|
||||
# After the last item on each side, add some spacing
|
||||
self.left_layout.addStretch()
|
||||
self.right_layout.addStretch()
|
||||
|
@ -311,7 +310,6 @@ class AdvancedTab(SettingsTab):
|
|||
translate('OpenLP.AdvancedTab',
|
||||
'Revert to the default service name "{name}".').format(name=UiStrings().DefaultServiceName))
|
||||
self.service_name_example_label.setText(translate('OpenLP.AdvancedTab', 'Example:'))
|
||||
self.hide_mouse_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Mouse Cursor'))
|
||||
self.hide_mouse_check_box.setText(translate('OpenLP.AdvancedTab', 'Hide mouse cursor when over display window'))
|
||||
self.data_directory_new_label.setText(translate('OpenLP.AdvancedTab', 'Path:'))
|
||||
self.data_directory_cancel_button.setText(translate('OpenLP.AdvancedTab', 'Cancel'))
|
||||
|
@ -334,6 +332,7 @@ class AdvancedTab(SettingsTab):
|
|||
self.wrap_slide_radio_button.setText(translate('OpenLP.GeneralTab', '&Wrap around'))
|
||||
self.next_item_radio_button.setText(translate('OpenLP.GeneralTab', '&Move to next/previous service item'))
|
||||
self.search_as_type_check_box.setText(translate('SongsPlugin.GeneralTab', 'Enable search as you type'))
|
||||
self.proxy_widget.retranslate_ui()
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
|
@ -436,6 +435,7 @@ class AdvancedTab(SettingsTab):
|
|||
if HAS_DARK_STYLE:
|
||||
settings.setValue('use_dark_style', self.use_dark_style_checkbox.isChecked())
|
||||
settings.endGroup()
|
||||
self.proxy_widget.save()
|
||||
|
||||
def on_search_as_type_check_box_changed(self, check_state):
|
||||
self.is_search_as_you_type_enabled = (check_state == QtCore.Qt.Checked)
|
||||
|
|
|
@ -26,7 +26,7 @@ The GUI widgets of the exception dialog.
|
|||
from PyQt5 import QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.lib.ui import create_button, create_button_box
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ class Ui_ExceptionDialog(object):
|
|||
Set up the UI.
|
||||
"""
|
||||
exception_dialog.setObjectName('exception_dialog')
|
||||
exception_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
exception_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
self.exception_layout = QtWidgets.QVBoxLayout(exception_dialog)
|
||||
self.exception_layout.setObjectName('exception_layout')
|
||||
self.message_layout = QtWidgets.QHBoxLayout()
|
||||
|
@ -48,7 +48,7 @@ class Ui_ExceptionDialog(object):
|
|||
self.message_layout.setContentsMargins(0, 0, 50, 0)
|
||||
self.message_layout.addSpacing(12)
|
||||
self.bug_label = QtWidgets.QLabel(exception_dialog)
|
||||
self.bug_label.setPixmap(QtGui.QPixmap(':/graphics/exception.png'))
|
||||
self.bug_label.setPixmap(UiIcons().exception.pixmap(40, 40))
|
||||
self.bug_label.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
self.bug_label.setObjectName('bug_label')
|
||||
self.message_layout.addWidget(self.bug_label)
|
||||
|
@ -72,13 +72,13 @@ class Ui_ExceptionDialog(object):
|
|||
self.exception_text_edit.setObjectName('exception_text_edit')
|
||||
self.exception_layout.addWidget(self.exception_text_edit)
|
||||
self.send_report_button = create_button(exception_dialog, 'send_report_button',
|
||||
icon=':/general/general_email.png',
|
||||
icon=UiIcons().email,
|
||||
click=self.on_send_report_button_clicked)
|
||||
self.save_report_button = create_button(exception_dialog, 'save_report_button',
|
||||
icon=':/general/general_save.png',
|
||||
icon=UiIcons().save,
|
||||
click=self.on_save_report_button_clicked)
|
||||
self.attach_tile_button = create_button(exception_dialog, 'attach_tile_button',
|
||||
icon=':/general/general_open.png',
|
||||
icon=UiIcons().open,
|
||||
click=self.on_attach_file_button_clicked)
|
||||
self.button_box = create_button_box(exception_dialog, 'button_box', ['close'],
|
||||
[self.send_report_button, self.save_report_button, self.attach_tile_button])
|
||||
|
@ -91,7 +91,7 @@ class Ui_ExceptionDialog(object):
|
|||
"""
|
||||
Translate the widgets on the fly.
|
||||
"""
|
||||
# Note that bugs mail is not clicable, but it adds the blue color and underlining and makes the test copyable.
|
||||
# Note that bugs mail is not clickable, but it adds the blue color and underlining and makes the test copyable.
|
||||
exception_dialog.setWindowTitle(translate('OpenLP.ExceptionDialog', 'Error Occurred'))
|
||||
# Explanation text, adds a small space before: If possible, write in English.
|
||||
self.description_explanation.setText(
|
||||
|
|
|
@ -25,8 +25,8 @@ The UI widgets for the rename dialog
|
|||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_FileRenameDialog(object):
|
||||
|
@ -38,7 +38,7 @@ class Ui_FileRenameDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
file_rename_dialog.setObjectName('file_rename_dialog')
|
||||
file_rename_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
file_rename_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
file_rename_dialog.resize(300, 10)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(file_rename_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -25,8 +25,8 @@ The UI widgets of the language selection dialog.
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_FirstTimeLanguageDialog(object):
|
||||
|
@ -38,7 +38,7 @@ class Ui_FirstTimeLanguageDialog(object):
|
|||
Set up the UI.
|
||||
"""
|
||||
language_dialog.setObjectName('language_dialog')
|
||||
language_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
language_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
language_dialog.resize(300, 50)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(language_dialog)
|
||||
self.dialog_layout.setContentsMargins(8, 8, 8, 8)
|
||||
|
|
|
@ -25,10 +25,10 @@ The UI widgets for the first time wizard.
|
|||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import is_macosx, clean_button_text
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import add_welcome_page
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class FirstTimePage(object):
|
||||
|
@ -57,7 +57,7 @@ class UiFirstTimeWizard(object):
|
|||
:param first_time_wizard: The wizard form
|
||||
"""
|
||||
first_time_wizard.setObjectName('first_time_wizard')
|
||||
first_time_wizard.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
first_time_wizard.setWindowIcon(UiIcons().main_icon)
|
||||
first_time_wizard.resize(550, 386)
|
||||
first_time_wizard.setModal(True)
|
||||
first_time_wizard.setOptions(QtWidgets.QWizard.IndependentPages | QtWidgets.QWizard.NoBackButtonOnStartPage |
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"users": "0041",
|
||||
"file-text": "0042",
|
||||
"search-text": "0043",
|
||||
"search-lyrcs": "0044",
|
||||
"search-CCLI": "0045",
|
||||
"hdmi": "0046",
|
||||
"video": "0047",
|
||||
"plus_sign": "0048",
|
||||
"minus_sign": "0049"
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -25,7 +25,7 @@ The UI widgets for the formatting tags window.
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ class Ui_FormattingTagDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
formatting_tag_dialog.setObjectName('formatting_tag_dialog')
|
||||
formatting_tag_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
formatting_tag_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
formatting_tag_dialog.resize(725, 548)
|
||||
self.list_data_grid_layout = QtWidgets.QVBoxLayout(formatting_tag_dialog)
|
||||
self.list_data_grid_layout.setContentsMargins(8, 8, 8, 8)
|
||||
|
@ -87,11 +87,11 @@ class Ui_FormattingTagDialog(object):
|
|||
self.list_data_grid_layout.addWidget(self.tag_table_widget)
|
||||
self.edit_button_layout = QtWidgets.QHBoxLayout()
|
||||
self.new_button = QtWidgets.QPushButton(formatting_tag_dialog)
|
||||
self.new_button.setIcon(build_icon(':/general/general_new.png'))
|
||||
self.new_button.setIcon(UiIcons().new)
|
||||
self.new_button.setObjectName('new_button')
|
||||
self.edit_button_layout.addWidget(self.new_button)
|
||||
self.delete_button = QtWidgets.QPushButton(formatting_tag_dialog)
|
||||
self.delete_button.setIcon(build_icon(':/general/general_delete.png'))
|
||||
self.delete_button.setIcon(UiIcons().delete)
|
||||
self.delete_button.setObjectName('delete_button')
|
||||
self.edit_button_layout.addWidget(self.delete_button)
|
||||
self.edit_button_layout.addStretch()
|
||||
|
@ -100,7 +100,7 @@ class Ui_FormattingTagDialog(object):
|
|||
self.save_button = self.button_box.button(QtWidgets.QDialogButtonBox.Save)
|
||||
self.save_button.setObjectName('save_button')
|
||||
self.restore_button = self.button_box.button(QtWidgets.QDialogButtonBox.RestoreDefaults)
|
||||
self.restore_button.setIcon(build_icon(':/general/general_revert.png'))
|
||||
self.restore_button.setIcon(UiIcons().undo)
|
||||
self.restore_button.setObjectName('restore_button')
|
||||
self.list_data_grid_layout.addWidget(self.button_box)
|
||||
self.retranslateUi(formatting_tag_dialog)
|
||||
|
|
|
@ -24,7 +24,7 @@ The general tab of the configuration dialog.
|
|||
"""
|
||||
import logging
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PyQt5 import QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common import get_images_filter
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
|
@ -62,60 +62,64 @@ class GeneralTab(SettingsTab):
|
|||
super(GeneralTab, self).setupUi()
|
||||
self.tab_layout.setStretch(1, 1)
|
||||
# Monitors
|
||||
self.monitor_group_box = QtWidgets.QGroupBox(self.left_column)
|
||||
self.monitor_group_box.setObjectName('monitor_group_box')
|
||||
self.monitor_layout = QtWidgets.QGridLayout(self.monitor_group_box)
|
||||
self.monitor_layout.setObjectName('monitor_layout')
|
||||
self.monitor_radio_button = QtWidgets.QRadioButton(self.monitor_group_box)
|
||||
self.monitor_radio_button.setObjectName('monitor_radio_button')
|
||||
self.monitor_layout.addWidget(self.monitor_radio_button, 0, 0, 1, 5)
|
||||
self.monitor_combo_box = QtWidgets.QComboBox(self.monitor_group_box)
|
||||
self.monitor_combo_box.setObjectName('monitor_combo_box')
|
||||
self.monitor_layout.addWidget(self.monitor_combo_box, 1, 1, 1, 4)
|
||||
self.screen_group_box = QtWidgets.QGroupBox(self.left_column)
|
||||
self.screen_group_box.setObjectName('screen_group_box')
|
||||
self.screen_layout = QtWidgets.QVBoxLayout(self.screen_group_box)
|
||||
self.screen_layout.setObjectName('screen_layout')
|
||||
self.screen_combo_box = QtWidgets.QComboBox(self.screen_group_box)
|
||||
self.screen_combo_box.setObjectName('screen_combo_box')
|
||||
self.screen_layout.addWidget(self.screen_combo_box)
|
||||
# Actual screen details
|
||||
self.screen_detail_layout = QtWidgets.QGridLayout()
|
||||
self.screen_detail_layout.setContentsMargins(0, 0, 0, 0)
|
||||
# self.screen_detail_layout.setSpacing(8)
|
||||
self.screen_detail_layout.setObjectName('screen_detail_layout')
|
||||
self.screen_use_this_checkbox = QtWidgets.QCheckBox(self.screen_group_box)
|
||||
self.screen_use_this_checkbox.setObjectName('screen_use_this_checkbox')
|
||||
self.screen_detail_layout.addWidget(self.screen_use_this_checkbox)
|
||||
# Display Position
|
||||
self.override_radio_button = QtWidgets.QRadioButton(self.monitor_group_box)
|
||||
self.override_radio_button = QtWidgets.QRadioButton(self.screen_group_box)
|
||||
self.override_radio_button.setObjectName('override_radio_button')
|
||||
self.monitor_layout.addWidget(self.override_radio_button, 2, 0, 1, 5)
|
||||
# Custom position
|
||||
self.custom_x_label = QtWidgets.QLabel(self.monitor_group_box)
|
||||
self.screen_detail_layout.addWidget(self.override_radio_button)
|
||||
self.custom_x_label = QtWidgets.QLabel(self.screen_group_box)
|
||||
self.custom_x_label.setObjectName('custom_x_label')
|
||||
self.monitor_layout.addWidget(self.custom_x_label, 3, 1)
|
||||
self.custom_X_value_edit = QtWidgets.QSpinBox(self.monitor_group_box)
|
||||
self.screen_layout.addWidget(self.custom_x_label, 3, 1)
|
||||
self.custom_X_value_edit = QtWidgets.QSpinBox(self.screen_group_box)
|
||||
self.custom_X_value_edit.setObjectName('custom_X_value_edit')
|
||||
self.custom_X_value_edit.setRange(-9999, 9999)
|
||||
self.monitor_layout.addWidget(self.custom_X_value_edit, 4, 1)
|
||||
self.custom_y_label = QtWidgets.QLabel(self.monitor_group_box)
|
||||
self.screen_layout.addWidget(self.custom_X_value_edit, 4, 1)
|
||||
self.custom_y_label = QtWidgets.QLabel(self.screen_group_box)
|
||||
self.custom_y_label.setObjectName('custom_y_label')
|
||||
self.monitor_layout.addWidget(self.custom_y_label, 3, 2)
|
||||
self.custom_Y_value_edit = QtWidgets.QSpinBox(self.monitor_group_box)
|
||||
self.screen_layout.addWidget(self.custom_y_label, 3, 2)
|
||||
self.custom_Y_value_edit = QtWidgets.QSpinBox(self.screen_group_box)
|
||||
self.custom_Y_value_edit.setObjectName('custom_Y_value_edit')
|
||||
self.custom_Y_value_edit.setRange(-9999, 9999)
|
||||
self.monitor_layout.addWidget(self.custom_Y_value_edit, 4, 2)
|
||||
self.custom_width_label = QtWidgets.QLabel(self.monitor_group_box)
|
||||
self.screen_layout.addWidget(self.custom_Y_value_edit, 4, 2)
|
||||
self.custom_width_label = QtWidgets.QLabel(self.screen_group_box)
|
||||
self.custom_width_label.setObjectName('custom_width_label')
|
||||
self.monitor_layout.addWidget(self.custom_width_label, 3, 3)
|
||||
self.custom_width_value_edit = QtWidgets.QSpinBox(self.monitor_group_box)
|
||||
self.screen_layout.addWidget(self.custom_width_label, 3, 3)
|
||||
self.custom_width_value_edit = QtWidgets.QSpinBox(self.screen_group_box)
|
||||
self.custom_width_value_edit.setObjectName('custom_width_value_edit')
|
||||
self.custom_width_value_edit.setRange(1, 9999)
|
||||
self.monitor_layout.addWidget(self.custom_width_value_edit, 4, 3)
|
||||
self.custom_height_label = QtWidgets.QLabel(self.monitor_group_box)
|
||||
self.screen_layout.addWidget(self.custom_width_value_edit, 4, 3)
|
||||
self.custom_height_label = QtWidgets.QLabel(self.screen_group_box)
|
||||
self.custom_height_label.setObjectName('custom_height_label')
|
||||
self.monitor_layout.addWidget(self.custom_height_label, 3, 4)
|
||||
self.custom_height_value_edit = QtWidgets.QSpinBox(self.monitor_group_box)
|
||||
self.screen_layout.addWidget(self.custom_height_label, 3, 4)
|
||||
self.custom_height_value_edit = QtWidgets.QSpinBox(self.screen_group_box)
|
||||
self.custom_height_value_edit.setObjectName('custom_height_value_edit')
|
||||
self.custom_height_value_edit.setRange(1, 9999)
|
||||
self.monitor_layout.addWidget(self.custom_height_value_edit, 4, 4)
|
||||
self.display_on_monitor_check = QtWidgets.QCheckBox(self.monitor_group_box)
|
||||
self.display_on_monitor_check.setObjectName('monitor_combo_box')
|
||||
self.monitor_layout.addWidget(self.display_on_monitor_check, 5, 0, 1, 5)
|
||||
self.screen_layout.addWidget(self.custom_height_value_edit, 4, 4)
|
||||
self.display_on_screen_check = QtWidgets.QCheckBox(self.screen_group_box)
|
||||
self.display_on_screen_check.setObjectName('screen_combo_box')
|
||||
self.screen_layout.addWidget(self.display_on_screen_check, 5, 0, 1, 5)
|
||||
# Set up the stretchiness of each column, so that the first column
|
||||
# less stretchy (and therefore smaller) than the others
|
||||
self.monitor_layout.setColumnStretch(0, 1)
|
||||
self.monitor_layout.setColumnStretch(1, 3)
|
||||
self.monitor_layout.setColumnStretch(2, 3)
|
||||
self.monitor_layout.setColumnStretch(3, 3)
|
||||
self.monitor_layout.setColumnStretch(4, 3)
|
||||
self.left_layout.addWidget(self.monitor_group_box)
|
||||
self.screen_layout.setColumnStretch(0, 1)
|
||||
self.screen_layout.setColumnStretch(1, 3)
|
||||
self.screen_layout.setColumnStretch(2, 3)
|
||||
self.screen_layout.setColumnStretch(3, 3)
|
||||
self.screen_layout.setColumnStretch(4, 3)
|
||||
self.left_layout.addWidget(self.screen_group_box)
|
||||
# CCLI Details
|
||||
self.ccli_group_box = QtWidgets.QGroupBox(self.left_column)
|
||||
self.ccli_group_box.setObjectName('ccli_group_box')
|
||||
|
@ -222,7 +226,7 @@ class GeneralTab(SettingsTab):
|
|||
self.custom_width_value_edit.valueChanged.connect(self.on_display_changed)
|
||||
self.custom_Y_value_edit.valueChanged.connect(self.on_display_changed)
|
||||
self.custom_X_value_edit.valueChanged.connect(self.on_display_changed)
|
||||
self.monitor_combo_box.currentIndexChanged.connect(self.on_display_changed)
|
||||
self.screen_combo_box.currentIndexChanged.connect(self.on_display_changed)
|
||||
# Reload the tab, as the screen resolution/count may have changed.
|
||||
Registry().register_function('config_screen_changed', self.load)
|
||||
# Remove for now
|
||||
|
@ -236,9 +240,10 @@ class GeneralTab(SettingsTab):
|
|||
Translate the general settings tab to the currently selected language
|
||||
"""
|
||||
self.tab_title_visible = translate('OpenLP.GeneralTab', 'General')
|
||||
self.monitor_group_box.setTitle(translate('OpenLP.GeneralTab', 'Monitors'))
|
||||
self.monitor_radio_button.setText(translate('OpenLP.GeneralTab', 'Select monitor for output display:'))
|
||||
self.display_on_monitor_check.setText(translate('OpenLP.GeneralTab', 'Display if a single screen'))
|
||||
self.screen_group_box.setTitle(translate('OpenLP.GeneralTab', 'Monitors'))
|
||||
self.screen_radio_button.setText(translate('OpenLP.GeneralTab', 'Select screen for output display:'))
|
||||
self.screen_use_this_checkbox.setText(translate('OpenLP.GeneralTab', 'Use this screen as a display'))
|
||||
self.display_on_screen_check.setText(translate('OpenLP.GeneralTab', 'Display if a single screen'))
|
||||
self.startup_group_box.setTitle(translate('OpenLP.GeneralTab', 'Application Startup'))
|
||||
self.warning_check_box.setText(translate('OpenLP.GeneralTab', 'Show blank screen warning'))
|
||||
self.auto_open_check_box.setText(translate('OpenLP.GeneralTab', 'Automatically open the previous service file'))
|
||||
|
@ -282,17 +287,17 @@ class GeneralTab(SettingsTab):
|
|||
"""
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
self.monitor_combo_box.clear()
|
||||
self.screen_combo_box.clear()
|
||||
for screen in self.screens:
|
||||
self.monitor_combo_box.addItem(str(screen), screen.number)
|
||||
monitors = settings.value('monitors')
|
||||
for number, monitor in monitors.items():
|
||||
if monitor['is_display']:
|
||||
for item_index in range(self.monitor_combo_box.count()):
|
||||
if self.monitor_combo_box.itemData(item_index) == number:
|
||||
self.monitor_combo_box.setCurrentIndex(item_index)
|
||||
self.screen_combo_box.addItem(str(screen), screen.number)
|
||||
screens = settings.value('screens')
|
||||
for number, screen in screens.items():
|
||||
if screen['is_display']:
|
||||
for item_index in range(self.screen_combo_box.count()):
|
||||
if self.screen_combo_box.itemData(item_index) == number:
|
||||
self.screen_combo_box.setCurrentIndex(item_index)
|
||||
else:
|
||||
self.monitor_combo_box.setCurrentIndex(0)
|
||||
self.screen_combo_box.setCurrentIndex(0)
|
||||
self.number_edit.setText(settings.value('ccli number'))
|
||||
self.username_edit.setText(settings.value('songselect username'))
|
||||
self.password_edit.setText(settings.value('songselect password'))
|
||||
|
@ -300,7 +305,7 @@ class GeneralTab(SettingsTab):
|
|||
self.auto_unblank_check_box.setChecked(settings.value('auto unblank'))
|
||||
self.click_live_slide_to_unblank_check_box.setChecked(settings.value('click live slide to unblank'))
|
||||
# TODO: This is going to be a more complicated setup
|
||||
# self.display_on_monitor_check.setChecked(self.screens.display)
|
||||
# self.display_on_screen_check.setChecked(self.screens.display)
|
||||
self.warning_check_box.setChecked(settings.value('blank warning'))
|
||||
self.auto_open_check_box.setChecked(settings.value('auto open'))
|
||||
self.show_splash_check_box.setChecked(settings.value('show splash'))
|
||||
|
@ -311,7 +316,7 @@ class GeneralTab(SettingsTab):
|
|||
self.check_for_updates_check_box.setChecked(settings.value('update check'))
|
||||
self.auto_preview_check_box.setChecked(settings.value('auto preview'))
|
||||
self.timeout_spin_box.setValue(settings.value('loop delay'))
|
||||
# self.monitor_radio_button.setChecked(not settings.value('override position',))
|
||||
# self.screen_radio_button.setChecked(not settings.value('override position',))
|
||||
# self.override_radio_button.setChecked(settings.value('override position'))
|
||||
# self.custom_X_value_edit.setValue(settings.value('x position'))
|
||||
# self.custom_Y_value_edit.setValue(settings.value('y position'))
|
||||
|
@ -320,7 +325,7 @@ class GeneralTab(SettingsTab):
|
|||
self.start_paused_check_box.setChecked(settings.value('audio start paused'))
|
||||
self.repeat_list_check_box.setChecked(settings.value('audio repeat list'))
|
||||
settings.endGroup()
|
||||
# self.monitor_combo_box.setDisabled(self.override_radio_button.isChecked())
|
||||
# self.screen_combo_box.setDisabled(self.override_radio_button.isChecked())
|
||||
# self.custom_X_value_edit.setEnabled(self.override_radio_button.isChecked())
|
||||
# self.custom_Y_value_edit.setEnabled(self.override_radio_button.isChecked())
|
||||
# self.custom_height_value_edit.setEnabled(self.override_radio_button.isChecked())
|
||||
|
@ -333,8 +338,8 @@ class GeneralTab(SettingsTab):
|
|||
"""
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
# settings.setValue('monitor', self.monitor_combo_box.currentIndex())
|
||||
settings.setValue('display on monitor', self.display_on_monitor_check.isChecked())
|
||||
# settings.setValue('screen', self.screen_combo_box.currentIndex())
|
||||
settings.setValue('display on screen', self.display_on_screen_check.isChecked())
|
||||
settings.setValue('blank warning', self.warning_check_box.isChecked())
|
||||
settings.setValue('auto open', self.auto_open_check_box.isChecked())
|
||||
settings.setValue('show splash', self.show_splash_check_box.isChecked())
|
||||
|
@ -369,8 +374,8 @@ class GeneralTab(SettingsTab):
|
|||
# Do not continue on start up.
|
||||
if not is_post_update:
|
||||
return
|
||||
self.screens.set_display_screen(self.monitor_combo_box.currentData())
|
||||
# self.screens.display = self.display_on_monitor_check.isChecked()
|
||||
self.screens.set_display_screen(self.screen_combo_box.currentData())
|
||||
# self.screens.display = self.display_on_screen_check.isChecked()
|
||||
# self.screens.override['size'] = QtCore.QRect(
|
||||
# self.custom_X_value_edit.value(),
|
||||
# self.custom_Y_value_edit.value(),
|
||||
|
@ -392,7 +397,7 @@ class GeneralTab(SettingsTab):
|
|||
|
||||
:param checked: The state of the check box (boolean).
|
||||
"""
|
||||
self.monitor_combo_box.setDisabled(checked)
|
||||
self.screen_combo_box.setDisabled(checked)
|
||||
self.custom_X_value_edit.setEnabled(checked)
|
||||
self.custom_Y_value_edit.setEnabled(checked)
|
||||
self.custom_height_value_edit.setEnabled(checked)
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2018 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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:`languages` module provides a list of icons.
|
||||
"""
|
||||
import logging
|
||||
import qtawesome as qta
|
||||
|
||||
from PyQt5 import QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.lib import build_icon
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UiIcons(object):
|
||||
"""
|
||||
Provide standard icons for objects to use.
|
||||
"""
|
||||
__instance__ = None
|
||||
|
||||
def __new__(cls):
|
||||
"""
|
||||
Override the default object creation method to return a single instance.
|
||||
"""
|
||||
if not cls.__instance__:
|
||||
cls.__instance__ = object.__new__(cls)
|
||||
cls.load(cls)
|
||||
return cls.__instance__
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
These are the font icons used in the code.
|
||||
"""
|
||||
font_path = AppLocation.get_directory(AppLocation.AppDir) / 'core' / 'ui' / 'fonts' / 'OpenLP.ttf'
|
||||
charmap_path = AppLocation.get_directory(AppLocation.AppDir) / 'core' / 'ui' / 'fonts' / 'openlp-charmap.json'
|
||||
qta.load_font('op', font_path, charmap_path)
|
||||
palette = QtWidgets.QApplication.palette()
|
||||
qta.set_defaults(color=palette.color(QtGui.QPalette.Active,
|
||||
QtGui.QPalette.ButtonText),
|
||||
color_disabled=palette.color(QtGui.QPalette.Disabled,
|
||||
QtGui.QPalette.ButtonText))
|
||||
icon_list = {
|
||||
'active': {'icon': 'fa.child'},
|
||||
'add': {'icon': 'fa.plus-circle'},
|
||||
'alert': {'icon': 'fa.exclamation-triangle'},
|
||||
'arrow_down': {'icon': 'fa.arrow-down'},
|
||||
'arrow_left': {'icon': 'fa.arrow-left'},
|
||||
'arrow_right': {'icon': 'fa.arrow-right'},
|
||||
'arrow_up': {'icon': 'fa.arrow-up'},
|
||||
'audio': {'icon': 'fa.file-sound-o'},
|
||||
'authentication': {'icon': 'fa.exclamation-triangle', 'attr': 'red'},
|
||||
'address': {'icon': 'fa.book'},
|
||||
'back': {'icon': 'fa.step-backward'},
|
||||
'bible': {'icon': 'fa.book'},
|
||||
'blank': {'icon': 'fa.times-circle'},
|
||||
'blank_theme': {'icon': 'fa.file-image-o'},
|
||||
'book': {'icon': 'fa.book'},
|
||||
'bottom': {'icon': 'fa.angle-double-down'},
|
||||
'box': {'icon': 'fa.briefcase'},
|
||||
'clapperboard': {'icon': 'fa.chess-board'},
|
||||
'clock': {'icon': 'fa.clock-o'},
|
||||
'clone': {'icon': 'fa.clone'},
|
||||
'close': {'icon': 'fa.times-circle-o'},
|
||||
'copy': {'icon': 'fa.copy'},
|
||||
'copyright': {'icon': 'fa.copyright'},
|
||||
'database': {'icon': 'fa.database'},
|
||||
'default': {'icon': 'fa.info-circle'},
|
||||
'desktop': {'icon': 'fa.desktop'},
|
||||
'delete': {'icon': 'fa.trash'},
|
||||
'download': {'icon': 'fa.download'},
|
||||
'edit': {'icon': 'fa.edit'},
|
||||
'email': {'icon': 'fa.envelope'},
|
||||
'error': {'icon': 'fa.exclamation', 'attr': 'red'},
|
||||
'exception': {'icon': 'fa.times-circle'},
|
||||
'exit': {'icon': 'fa.sign-out'},
|
||||
'group': {'icon': 'fa.object-group'},
|
||||
'inactive': {'icon': 'fa.child', 'attr': 'lightGray'},
|
||||
'info': {'icon': 'fa.info'},
|
||||
'light_bulb': {'icon': 'fa.lightbulb-o'},
|
||||
'live': {'icon': 'fa.eye'},
|
||||
'manual': {'icon': 'fa.graduation-cap'},
|
||||
'media': {'icon': 'fa.fax'},
|
||||
'minus': {'icon': 'fa.minus'},
|
||||
'music': {'icon': 'fa.music'},
|
||||
'new': {'icon': 'fa.file'},
|
||||
'new_group': {'icon': 'fa.folder'},
|
||||
'notes': {'icon': 'fa.sticky-note'},
|
||||
'open': {'icon': 'fa.folder-open'},
|
||||
'optical': {'icon': 'fa.file-video-o'},
|
||||
'pause': {'icon': 'fa.pause'},
|
||||
'play': {'icon': 'fa.play'},
|
||||
'player': {'icon': 'fa.tablet'},
|
||||
'plugin_list': {'icon': 'fa.puzzle-piece'},
|
||||
'plus': {'icon': 'fa.plus'},
|
||||
'presentation': {'icon': 'fa.bar-chart'},
|
||||
'preview': {'icon': 'fa.laptop'},
|
||||
'projector': {'icon': 'op.video'},
|
||||
'projector_connect': {'icon': 'fa.plug'},
|
||||
'projector_cooldown': {'icon': 'fa.video-camera', 'attr': 'blue'},
|
||||
'projector_disconnect': {'icon': 'fa.plug', 'attr': 'lightGray'},
|
||||
'projector_error': {'icon': 'fa.video-camera', 'attr': 'red'},
|
||||
'projector_hdmi': {'icon': 'op.hdmi'},
|
||||
'projector_off': {'icon': 'fa.video-camera', 'attr': 'black'},
|
||||
'projector_on': {'icon': 'fa.video-camera', 'attr': 'green'},
|
||||
'projector_warmup': {'icon': 'fa.video-camera', 'attr': 'yellow'},
|
||||
'picture': {'icon': 'fa.picture-o'},
|
||||
'print': {'icon': 'fa.print'},
|
||||
'remote': {'icon': 'fa.rss'},
|
||||
'repeat': {'icon': 'fa.repeat'},
|
||||
'save': {'icon': 'fa.save'},
|
||||
'search': {'icon': 'fa.search'},
|
||||
'search_ccli': {'icon': 'op.search-CCLI'},
|
||||
'search_comb': {'icon': 'fa.columns'},
|
||||
'search_lyrcs': {'icon': 'op.search-lyrcs'},
|
||||
'search_minus': {'icon': 'fa.search-minus'},
|
||||
'search_plus': {'icon': 'fa.search-plus'},
|
||||
'search_ref': {'icon': 'fa.institution'},
|
||||
'search_text': {'icon': 'op.search-text'},
|
||||
'settings': {'icon': 'fa.cogs'},
|
||||
'shortcuts': {'icon': 'fa.wrench'},
|
||||
'song_usage': {'icon': 'fa.line-chart'},
|
||||
'song_usage_active': {'icon': 'op.plus_sign'},
|
||||
'song_usage_inactive': {'icon': 'op.minus_sign'},
|
||||
'sort': {'icon': 'fa.sort'},
|
||||
'stop': {'icon': 'fa.stop'},
|
||||
'square': {'icon': 'fa.square'},
|
||||
'text': {'icon': 'op.file-text'},
|
||||
'time': {'icon': 'fa.history'},
|
||||
'theme': {'icon': 'fa.paint-brush'},
|
||||
'top': {'icon': 'fa.angle-double-up'},
|
||||
'undo': {'icon': 'fa.undo'},
|
||||
'upload': {'icon': 'fa.upload'},
|
||||
'user': {'icon': 'fa.user'},
|
||||
'usermo': {'icon': 'op.users'},
|
||||
'users': {'icon': 'fa.users'},
|
||||
'video': {'icon': 'fa.file-video-o'},
|
||||
'volunteer': {'icon': 'fa.group'}
|
||||
}
|
||||
self.load_icons(self, icon_list)
|
||||
|
||||
def load_icons(self, icon_list):
|
||||
"""
|
||||
Load the list of icons to be processed
|
||||
"""
|
||||
for key in icon_list:
|
||||
try:
|
||||
icon = icon_list[key]['icon']
|
||||
try:
|
||||
attr = icon_list[key]['attr']
|
||||
setattr(self, key, qta.icon(icon, color=attr))
|
||||
except KeyError:
|
||||
setattr(self, key, qta.icon(icon))
|
||||
except Exception:
|
||||
import sys
|
||||
log.error("Unexpected error: %s" % sys.exc_info())
|
||||
setattr(self, key, qta.icon('fa.plus-circle', color='red'))
|
||||
except:
|
||||
setattr(self, key, qta.icon('fa.plus-circle', color='red'))
|
||||
self.main_icon = build_icon(':/icon/openlp-logo.svg')
|
||||
|
||||
@staticmethod
|
||||
def _print_icons():
|
||||
"""
|
||||
Have ability to dump icons to see what is actually available. Can only run within an application
|
||||
:return:
|
||||
"""
|
||||
ico = qta._resource['iconic']
|
||||
fa = ico.charmap['fa']
|
||||
for ky in fa.keys():
|
||||
print(ky, fa[ky])
|
|
@ -36,12 +36,13 @@ from openlp.core.common import is_win, is_macosx, add_actions
|
|||
from openlp.core.common.actions import ActionList, CategoryOrder
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.i18n import LanguageManager, UiStrings, translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
from openlp.core.common.path import Path, copyfile, create_paths
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.display.screens import ScreenList
|
||||
from openlp.core.lib import PluginManager, ImageManager, PluginStatus, build_icon
|
||||
from openlp.core.lib import PluginManager, ImageManager, PluginStatus
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.core.projectors.manager import ProjectorManager
|
||||
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, PluginForm, ShortcutListForm, \
|
||||
|
@ -65,7 +66,7 @@ class Ui_MainWindow(object):
|
|||
Set up the user interface
|
||||
"""
|
||||
main_window.setObjectName('MainWindow')
|
||||
main_window.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
main_window.setWindowIcon(UiIcons().main_icon)
|
||||
main_window.setDockNestingEnabled(True)
|
||||
if is_macosx():
|
||||
main_window.setDocumentMode(True)
|
||||
|
@ -96,11 +97,11 @@ class Ui_MainWindow(object):
|
|||
self.recent_files_menu.setObjectName('recentFilesMenu')
|
||||
self.file_import_menu = QtWidgets.QMenu(self.file_menu)
|
||||
if not is_macosx():
|
||||
self.file_import_menu.setIcon(build_icon(u':/general/general_import.png'))
|
||||
self.file_import_menu.setIcon(UiIcons().download)
|
||||
self.file_import_menu.setObjectName('file_import_menu')
|
||||
self.file_export_menu = QtWidgets.QMenu(self.file_menu)
|
||||
if not is_macosx():
|
||||
self.file_export_menu.setIcon(build_icon(u':/general/general_export.png'))
|
||||
self.file_export_menu.setIcon(UiIcons().upload)
|
||||
self.file_export_menu.setObjectName('file_export_menu')
|
||||
# View Menu
|
||||
self.view_menu = QtWidgets.QMenu(self.menu_bar)
|
||||
|
@ -133,7 +134,7 @@ class Ui_MainWindow(object):
|
|||
self.status_bar.addPermanentWidget(self.default_theme_label)
|
||||
# Create the MediaManager
|
||||
self.media_manager_dock = OpenLPDockWidget(main_window, 'media_manager_dock',
|
||||
':/system/system_mediamanager.png')
|
||||
UiIcons().box)
|
||||
self.media_manager_dock.setStyleSheet(get_library_stylesheet())
|
||||
# Create the media toolbox
|
||||
self.media_tool_box = QtWidgets.QToolBox(self.media_manager_dock)
|
||||
|
@ -142,13 +143,13 @@ class Ui_MainWindow(object):
|
|||
main_window.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.media_manager_dock)
|
||||
# Create the service manager
|
||||
self.service_manager_dock = OpenLPDockWidget(main_window, 'service_manager_dock',
|
||||
':/system/system_servicemanager.png')
|
||||
UiIcons().live)
|
||||
self.service_manager_contents = ServiceManager(self.service_manager_dock)
|
||||
self.service_manager_dock.setWidget(self.service_manager_contents)
|
||||
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.service_manager_dock)
|
||||
# Create the theme manager
|
||||
self.theme_manager_dock = OpenLPDockWidget(main_window, 'theme_manager_dock',
|
||||
':/system/system_thememanager.png')
|
||||
UiIcons().theme)
|
||||
self.theme_manager_contents = ThemeManager(self.theme_manager_dock)
|
||||
self.theme_manager_contents.setObjectName('theme_manager_contents')
|
||||
self.theme_manager_dock.setWidget(self.theme_manager_contents)
|
||||
|
@ -156,7 +157,7 @@ class Ui_MainWindow(object):
|
|||
# Create the projector manager
|
||||
self.projector_manager_dock = OpenLPDockWidget(parent=main_window,
|
||||
name='projector_manager_dock',
|
||||
icon=':/projector/projector_manager.png')
|
||||
icon=UiIcons().projector)
|
||||
self.projector_manager_contents = ProjectorManager(self.projector_manager_dock)
|
||||
self.projector_manager_contents.setObjectName('projector_manager_contents')
|
||||
self.projector_manager_dock.setWidget(self.projector_manager_contents)
|
||||
|
@ -165,13 +166,13 @@ class Ui_MainWindow(object):
|
|||
# Create the menu items
|
||||
action_list = ActionList.get_instance()
|
||||
action_list.add_category(UiStrings().File, CategoryOrder.standard_menu)
|
||||
self.file_new_item = create_action(main_window, 'fileNewItem', icon=':/general/general_new.png',
|
||||
self.file_new_item = create_action(main_window, 'fileNewItem', icon=UiIcons().new,
|
||||
can_shortcuts=True, category=UiStrings().File,
|
||||
triggers=self.service_manager_contents.on_new_service_clicked)
|
||||
self.file_open_item = create_action(main_window, 'fileOpenItem', icon=':/general/general_open.png',
|
||||
self.file_open_item = create_action(main_window, 'fileOpenItem', icon=UiIcons().open,
|
||||
can_shortcuts=True, category=UiStrings().File,
|
||||
triggers=self.service_manager_contents.on_load_service_clicked)
|
||||
self.file_save_item = create_action(main_window, 'fileSaveItem', icon=':/general/general_save.png',
|
||||
self.file_save_item = create_action(main_window, 'fileSaveItem', icon=UiIcons().save,
|
||||
can_shortcuts=True, category=UiStrings().File,
|
||||
triggers=self.service_manager_contents.decide_save_method)
|
||||
self.file_save_as_item = create_action(main_window, 'fileSaveAsItem', can_shortcuts=True,
|
||||
|
@ -180,7 +181,7 @@ class Ui_MainWindow(object):
|
|||
self.print_service_order_item = create_action(main_window, 'printServiceItem', can_shortcuts=True,
|
||||
category=UiStrings().File,
|
||||
triggers=lambda x: PrintServiceForm().exec())
|
||||
self.file_exit_item = create_action(main_window, 'fileExitItem', icon=':/system/system_exit.png',
|
||||
self.file_exit_item = create_action(main_window, 'fileExitItem', icon=UiIcons().exit,
|
||||
can_shortcuts=True,
|
||||
category=UiStrings().File, triggers=main_window.close)
|
||||
# Give QT Extra Hint that this is the Exit Menu Item
|
||||
|
@ -199,22 +200,22 @@ class Ui_MainWindow(object):
|
|||
can_shortcuts=False)
|
||||
action_list.add_category(UiStrings().Import, CategoryOrder.standard_menu)
|
||||
self.view_projector_manager_item = create_action(main_window, 'viewProjectorManagerItem',
|
||||
icon=':/projector/projector_manager.png',
|
||||
icon=UiIcons().projector,
|
||||
checked=self.projector_manager_dock.isVisible(),
|
||||
can_shortcuts=True,
|
||||
category=UiStrings().View,
|
||||
triggers=self.toggle_projector_manager)
|
||||
self.view_media_manager_item = create_action(main_window, 'viewMediaManagerItem',
|
||||
icon=':/system/system_mediamanager.png',
|
||||
icon=UiIcons().box,
|
||||
checked=self.media_manager_dock.isVisible(),
|
||||
can_shortcuts=True,
|
||||
category=UiStrings().View, triggers=self.toggle_media_manager)
|
||||
self.view_theme_manager_item = create_action(main_window, 'viewThemeManagerItem', can_shortcuts=True,
|
||||
icon=':/system/system_thememanager.png',
|
||||
icon=UiIcons().theme,
|
||||
checked=self.theme_manager_dock.isVisible(),
|
||||
category=UiStrings().View, triggers=self.toggle_theme_manager)
|
||||
self.view_service_manager_item = create_action(main_window, 'viewServiceManagerItem', can_shortcuts=True,
|
||||
icon=':/system/system_servicemanager.png',
|
||||
icon=UiIcons().live,
|
||||
checked=self.service_manager_dock.isVisible(),
|
||||
category=UiStrings().View, triggers=self.toggle_service_manager)
|
||||
self.view_preview_panel = create_action(main_window, 'viewPreviewPanel', can_shortcuts=True,
|
||||
|
@ -238,20 +239,20 @@ class Ui_MainWindow(object):
|
|||
self.mode_default_item.setChecked(True)
|
||||
action_list.add_category(UiStrings().Tools, CategoryOrder.standard_menu)
|
||||
self.tools_add_tool_item = create_action(main_window,
|
||||
'toolsAddToolItem', icon=':/tools/tools_add.png',
|
||||
'toolsAddToolItem', icon=UiIcons().add,
|
||||
category=UiStrings().Tools, can_shortcuts=True)
|
||||
self.tools_open_data_folder = create_action(main_window,
|
||||
'toolsOpenDataFolder', icon=':/general/general_open.png',
|
||||
'toolsOpenDataFolder', icon=UiIcons().open,
|
||||
category=UiStrings().Tools, can_shortcuts=True)
|
||||
self.tools_first_time_wizard = create_action(main_window,
|
||||
'toolsFirstTimeWizard', icon=':/general/general_revert.png',
|
||||
'toolsFirstTimeWizard', icon=UiIcons().undo,
|
||||
category=UiStrings().Tools, can_shortcuts=True)
|
||||
self.update_theme_images = create_action(main_window,
|
||||
'updateThemeImages', category=UiStrings().Tools, can_shortcuts=True)
|
||||
action_list.add_category(UiStrings().Settings, CategoryOrder.standard_menu)
|
||||
self.settings_plugin_list_item = create_action(main_window,
|
||||
'settingsPluginListItem',
|
||||
icon=':/system/settings_plugin_list.png',
|
||||
icon=UiIcons().plugin_list,
|
||||
can_shortcuts=True,
|
||||
category=UiStrings().Settings,
|
||||
triggers=self.on_plugin_item_clicked)
|
||||
|
@ -267,14 +268,14 @@ class Ui_MainWindow(object):
|
|||
language_item = create_action(main_window, key, checked=qm_list[key] == saved_language)
|
||||
add_actions(self.language_group, [language_item])
|
||||
self.settings_shortcuts_item = create_action(main_window, 'settingsShortcutsItem',
|
||||
icon=':/system/system_configure_shortcuts.png',
|
||||
icon=UiIcons().shortcuts,
|
||||
category=UiStrings().Settings, can_shortcuts=True)
|
||||
# Formatting Tags were also known as display tags.
|
||||
self.formatting_tag_item = create_action(main_window, 'displayTagItem',
|
||||
icon=':/system/tag_editor.png', category=UiStrings().Settings,
|
||||
icon=UiIcons().edit, category=UiStrings().Settings,
|
||||
can_shortcuts=True)
|
||||
self.settings_configure_item = create_action(main_window, 'settingsConfigureItem',
|
||||
icon=':/system/system_settings.png', can_shortcuts=True,
|
||||
icon=UiIcons().settings, can_shortcuts=True,
|
||||
category=UiStrings().Settings)
|
||||
# Give QT Extra Hint that this is the Preferences Menu Item
|
||||
self.settings_configure_item.setMenuRole(QtWidgets.QAction.PreferencesRole)
|
||||
|
@ -283,7 +284,7 @@ class Ui_MainWindow(object):
|
|||
self.settings_export_item = create_action(main_window, 'settingsExportItem',
|
||||
category=UiStrings().Export, can_shortcuts=True)
|
||||
action_list.add_category(UiStrings().Help, CategoryOrder.standard_menu)
|
||||
self.about_item = create_action(main_window, 'aboutItem', icon=':/system/system_about.png',
|
||||
self.about_item = create_action(main_window, 'aboutItem', icon=UiIcons().info,
|
||||
can_shortcuts=True, category=UiStrings().Help,
|
||||
triggers=self.on_about_item_clicked)
|
||||
# Give QT Extra Hint that this is an About Menu Item
|
||||
|
@ -292,7 +293,7 @@ class Ui_MainWindow(object):
|
|||
self.local_help_file = AppLocation.get_directory(AppLocation.AppDir) / 'OpenLP.chm'
|
||||
elif is_macosx():
|
||||
self.local_help_file = AppLocation.get_directory(AppLocation.AppDir) / '..' / 'Resources' / 'OpenLP.help'
|
||||
self.user_manual_item = create_action(main_window, 'userManualItem', icon=':/system/system_help_contents.png',
|
||||
self.user_manual_item = create_action(main_window, 'userManualItem', icon=UiIcons().manual,
|
||||
can_shortcuts=True, category=UiStrings().Help,
|
||||
triggers=self.on_help_clicked)
|
||||
self.web_site_item = create_action(main_window, 'webSiteItem', can_shortcuts=True, category=UiStrings().Help)
|
||||
|
@ -623,7 +624,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
"""
|
||||
version_text = translate('OpenLP.MainWindow', 'Version {new} of OpenLP is now available for download (you are '
|
||||
'currently running version {current}). \n\nYou can download the latest version from '
|
||||
'http://openlp.org/.').format(new=version, current=get_version()[u'full'])
|
||||
'https://openlp.org/.').format(new=version, current=get_version()[u'full'])
|
||||
QtWidgets.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Version Updated'), version_text)
|
||||
|
||||
def show(self):
|
||||
|
@ -773,7 +774,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
Load the OpenLP website
|
||||
"""
|
||||
import webbrowser
|
||||
webbrowser.open_new('http://openlp.org/')
|
||||
webbrowser.open_new('https://openlp.org/')
|
||||
|
||||
def on_help_clicked(self):
|
||||
"""
|
||||
|
@ -784,7 +785,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(str(self.local_help_file)))
|
||||
else:
|
||||
import webbrowser
|
||||
webbrowser.open_new('http://manual.openlp.org/')
|
||||
webbrowser.open_new('https://manual.openlp.org/')
|
||||
|
||||
def on_about_item_clicked(self):
|
||||
"""
|
||||
|
@ -799,7 +800,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
|
|||
self.plugin_form.load()
|
||||
self.plugin_form.exec()
|
||||
|
||||
def on_tools_open_data_folder_clicked(self):
|
||||
@staticmethod
|
||||
def on_tools_open_data_folder_clicked():
|
||||
"""
|
||||
Open data folder
|
||||
"""
|
||||
|
|
|
@ -80,7 +80,7 @@ def get_media_players():
|
|||
"""
|
||||
log.debug('get_media_players')
|
||||
saved_players = Settings().value('media/players')
|
||||
reg_ex = QtCore.QRegExp(".*\[(.*)\].*")
|
||||
reg_ex = QtCore.QRegExp(r'.*\[(.*)\].*')
|
||||
if Settings().value('media/override player') == QtCore.Qt.Checked:
|
||||
if reg_ex.exactMatch(saved_players):
|
||||
overridden_player = '{text}'.format(text=reg_ex.cap(1))
|
||||
|
|
|
@ -38,6 +38,7 @@ from openlp.core.common.settings import Settings
|
|||
from openlp.core.lib import ItemCapabilities
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui import DisplayControllerType
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players, \
|
||||
parse_optical_path
|
||||
from openlp.core.ui.media.endpoint import media_endpoint
|
||||
|
@ -283,19 +284,19 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||
# Build a Media ToolBar
|
||||
controller.mediabar = OpenLPToolbar(controller)
|
||||
controller.mediabar.add_toolbar_action('playbackPlay', text='media_playback_play',
|
||||
icon=':/slides/media_playback_start.png',
|
||||
icon=UiIcons().play,
|
||||
tooltip=translate('OpenLP.SlideController', 'Start playing media.'),
|
||||
triggers=controller.send_to_plugins)
|
||||
controller.mediabar.add_toolbar_action('playbackPause', text='media_playback_pause',
|
||||
icon=':/slides/media_playback_pause.png',
|
||||
icon=UiIcons().pause,
|
||||
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'),
|
||||
triggers=controller.send_to_plugins)
|
||||
controller.mediabar.add_toolbar_action('playbackStop', text='media_playback_stop',
|
||||
icon=':/slides/media_playback_stop.png',
|
||||
icon=UiIcons().stop,
|
||||
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'),
|
||||
triggers=controller.send_to_plugins)
|
||||
controller.mediabar.add_toolbar_action('playbackLoop', text='media_playback_loop',
|
||||
icon=':/media/media_repeat.png', checked=False,
|
||||
icon=UiIcons().repeat, checked=False,
|
||||
tooltip=translate('OpenLP.SlideController', 'Loop playing media.'),
|
||||
triggers=controller.send_to_plugins)
|
||||
controller.position_label = QtWidgets.QLabel()
|
||||
|
|
|
@ -31,6 +31,7 @@ from openlp.core.common.registry import Registry
|
|||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import SettingsTab
|
||||
from openlp.core.lib.ui import create_button
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.ui.media import get_media_players, set_media_players
|
||||
from openlp.core.widgets.buttons import ColorButton
|
||||
|
||||
|
@ -56,7 +57,7 @@ class PlayerTab(SettingsTab):
|
|||
"""
|
||||
self.media_players = Registry().get('media_controller').media_players
|
||||
self.saved_used_players = None
|
||||
self.icon_path = ':/media/multimedia-player.png'
|
||||
self.icon_path = UiIcons().player
|
||||
player_translated = translate('OpenLP.PlayerTab', 'Players')
|
||||
super(PlayerTab, self).__init__(parent, 'Players', player_translated)
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ The UI widgets of the plugin view dialog
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_PluginViewDialog(object):
|
||||
|
@ -38,7 +38,7 @@ class Ui_PluginViewDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
plugin_view_dialog.setObjectName('plugin_view_dialog')
|
||||
plugin_view_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
plugin_view_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
plugin_view_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
self.plugin_layout = QtWidgets.QVBoxLayout(plugin_view_dialog)
|
||||
self.plugin_layout.setObjectName('plugin_layout')
|
||||
|
|
|
@ -25,7 +25,7 @@ The UI widgets of the print service dialog.
|
|||
from PyQt5 import QtCore, QtWidgets, QtPrintSupport
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.edits import SpellTextEdit
|
||||
|
||||
|
||||
|
@ -50,7 +50,7 @@ class Ui_PrintServiceDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
print_service_dialog.setObjectName('print_service_dialog')
|
||||
print_service_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
print_service_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
print_service_dialog.resize(664, 594)
|
||||
self.main_layout = QtWidgets.QVBoxLayout(print_service_dialog)
|
||||
self.main_layout.setSpacing(0)
|
||||
|
@ -59,31 +59,31 @@ class Ui_PrintServiceDialog(object):
|
|||
self.toolbar = QtWidgets.QToolBar(print_service_dialog)
|
||||
self.toolbar.setIconSize(QtCore.QSize(22, 22))
|
||||
self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
|
||||
self.print_button = self.toolbar.addAction(build_icon(':/general/general_print.png'),
|
||||
self.print_button = self.toolbar.addAction(UiIcons().print,
|
||||
translate('OpenLP.PrintServiceForm', 'Print'))
|
||||
self.options_button = QtWidgets.QToolButton(self.toolbar)
|
||||
self.options_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
|
||||
self.options_button.setIcon(build_icon(':/system/system_configure.png'))
|
||||
self.options_button.setIcon(UiIcons().settings)
|
||||
self.options_button.setCheckable(True)
|
||||
self.toolbar.addWidget(self.options_button)
|
||||
self.toolbar.addSeparator()
|
||||
self.plain_copy = self.toolbar.addAction(build_icon(':/system/system_edit_copy.png'),
|
||||
self.plain_copy = self.toolbar.addAction(UiIcons().clone,
|
||||
translate('OpenLP.PrintServiceForm', 'Copy'))
|
||||
self.html_copy = self.toolbar.addAction(build_icon(':/system/system_edit_copy.png'),
|
||||
self.html_copy = self.toolbar.addAction(UiIcons().clone,
|
||||
translate('OpenLP.PrintServiceForm', 'Copy as HTML'))
|
||||
self.toolbar.addSeparator()
|
||||
self.zoom_in_button = QtWidgets.QToolButton(self.toolbar)
|
||||
self.zoom_in_button.setIcon(build_icon(':/general/general_zoom_in.png'))
|
||||
self.zoom_in_button.setIcon(UiIcons().search_plus)
|
||||
self.zoom_in_button.setObjectName('zoom_in_button')
|
||||
self.zoom_in_button.setIconSize(QtCore.QSize(22, 22))
|
||||
self.toolbar.addWidget(self.zoom_in_button)
|
||||
self.zoom_out_button = QtWidgets.QToolButton(self.toolbar)
|
||||
self.zoom_out_button.setIcon(build_icon(':/general/general_zoom_out.png'))
|
||||
self.zoom_out_button.setIcon(UiIcons().search_minus)
|
||||
self.zoom_out_button.setObjectName('zoom_out_button')
|
||||
self.zoom_out_button.setIconSize(QtCore.QSize(22, 22))
|
||||
self.toolbar.addWidget(self.zoom_out_button)
|
||||
self.zoom_original_button = QtWidgets.QToolButton(self.toolbar)
|
||||
self.zoom_original_button.setIcon(build_icon(':/general/general_zoom_original.png'))
|
||||
self.zoom_original_button.setIcon(UiIcons().search)
|
||||
self.zoom_original_button.setObjectName('zoom_original_button')
|
||||
self.zoom_original_button.setIconSize(QtCore.QSize(22, 22))
|
||||
self.toolbar.addWidget(self.zoom_original_button)
|
||||
|
|
|
@ -33,7 +33,7 @@ from openlp.core.common.i18n import UiStrings, translate
|
|||
from openlp.core.common.mixins import RegistryProperties
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import get_text_file_string
|
||||
from openlp.core.lib import get_text_file_string, image_to_byte
|
||||
from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize
|
||||
|
||||
DEFAULT_CSS = """/*
|
||||
|
@ -184,7 +184,7 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
|
|||
custom_css = DEFAULT_CSS
|
||||
self._add_element('style', custom_css, html_data.head, attribute=('type', 'text/css'))
|
||||
self._add_element('body', parent=html_data)
|
||||
self._add_element('h1', html.escape(self.title_line_edit.text()), html_data.body, classId='serviceTitle')
|
||||
self._add_element('h1', html.escape(self.title_line_edit.text()), html_data.body, class_id='serviceTitle')
|
||||
for index, item in enumerate(self.service_manager.service_items):
|
||||
self._add_preview_item(html_data.body, item['service_item'], index)
|
||||
if not self.show_chords_check_box.isChecked():
|
||||
|
@ -195,10 +195,10 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
|
|||
spacing_span.drop_tree()
|
||||
# Add the custom service notes:
|
||||
if self.footer_text_edit.toPlainText():
|
||||
div = self._add_element('div', parent=html_data.body, classId='customNotes')
|
||||
div = self._add_element('div', parent=html_data.body, class_id='customNotes')
|
||||
self._add_element(
|
||||
'span', translate('OpenLP.ServiceManager', 'Custom Service Notes: '), div, classId='customNotesTitle')
|
||||
self._add_element('span', html.escape(self.footer_text_edit.toPlainText()), div, classId='customNotesText')
|
||||
'span', translate('OpenLP.ServiceManager', 'Custom Service Notes: '), div, class_id='customNotesTitle')
|
||||
self._add_element('span', html.escape(self.footer_text_edit.toPlainText()), div, class_id='customNotesText')
|
||||
self.document.setHtml(lxml.html.tostring(html_data).decode())
|
||||
self.preview_widget.updatePreview()
|
||||
|
||||
|
@ -206,10 +206,11 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
|
|||
"""
|
||||
Add a preview item
|
||||
"""
|
||||
div = self._add_element('div', classId='item', parent=body)
|
||||
div = self._add_element('div', class_id='item', parent=body)
|
||||
# Add the title of the service item.
|
||||
item_title = self._add_element('h2', parent=div, classId='itemTitle')
|
||||
self._add_element('img', parent=item_title, attribute=('src', item.icon))
|
||||
item_title = self._add_element('h2', parent=div, class_id='itemTitle')
|
||||
img = image_to_byte(item.icon.pixmap(20, 20).toImage())
|
||||
self._add_element('img', parent=item_title, attribute=('src', 'data:image/png;base64, ' + img))
|
||||
self._add_element('span', ' ' + html.escape(item.get_display_title()), item_title)
|
||||
if self.slide_text_check_box.isChecked():
|
||||
# Add the text of the service item.
|
||||
|
@ -218,7 +219,7 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
|
|||
verse_html = None
|
||||
for slide in item.get_frames():
|
||||
if not verse_def or verse_def != slide['verseTag'] or verse_html == slide['printing_html']:
|
||||
text_div = self._add_element('div', parent=div, classId='itemText')
|
||||
text_div = self._add_element('div', parent=div, class_id='itemText')
|
||||
elif 'chordspacing' not in slide['printing_html']:
|
||||
self._add_element('br', parent=text_div)
|
||||
self._add_element('span', slide['printing_html'], text_div)
|
||||
|
@ -229,7 +230,7 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
|
|||
div.set('class', 'item newPage')
|
||||
# Add the image names of the service item.
|
||||
elif item.is_image():
|
||||
ol = self._add_element('ol', parent=div, classId='imageList')
|
||||
ol = self._add_element('ol', parent=div, class_id='imageList')
|
||||
for slide in range(len(item.get_frames())):
|
||||
self._add_element('li', item.get_frame_title(slide), ol)
|
||||
# add footer
|
||||
|
@ -237,24 +238,24 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
|
|||
foot_text = foot_text.partition('<br>')[2]
|
||||
if foot_text:
|
||||
foot_text = html.escape(foot_text.replace('<br>', '\n'))
|
||||
self._add_element('div', foot_text.replace('\n', '<br>'), parent=div, classId='itemFooter')
|
||||
self._add_element('div', foot_text.replace('\n', '<br>'), parent=div, class_id='itemFooter')
|
||||
# Add service items' notes.
|
||||
if self.notes_check_box.isChecked():
|
||||
if item.notes:
|
||||
p = self._add_element('div', classId='itemNotes', parent=div)
|
||||
self._add_element('span', translate('OpenLP.ServiceManager', 'Notes: '), p, classId='itemNotesTitle')
|
||||
self._add_element('span', html.escape(item.notes).replace('\n', '<br>'), p, classId='itemNotesText')
|
||||
p = self._add_element('div', class_id='itemNotes', parent=div)
|
||||
self._add_element('span', translate('OpenLP.ServiceManager', 'Notes: '), p, class_id='itemNotesTitle')
|
||||
self._add_element('span', html.escape(item.notes).replace('\n', '<br>'), p, class_id='itemNotesText')
|
||||
# Add play length of media files.
|
||||
if item.is_media() and self.meta_data_check_box.isChecked():
|
||||
tme = item.media_length
|
||||
if item.end_time > 0:
|
||||
tme = item.end_time - item.start_time
|
||||
title = self._add_element('div', classId='media', parent=div)
|
||||
title = self._add_element('div', class_id='media', parent=div)
|
||||
self._add_element(
|
||||
'span', translate('OpenLP.ServiceManager', 'Playing time: '), title, classId='mediaTitle')
|
||||
self._add_element('span', str(datetime.timedelta(seconds=tme)), title, classId='mediaText')
|
||||
'span', translate('OpenLP.ServiceManager', 'Playing time: '), title, class_id='mediaTitle')
|
||||
self._add_element('span', str(datetime.timedelta(seconds=tme)), title, class_id='mediaText')
|
||||
|
||||
def _add_element(self, tag, text=None, parent=None, classId=None, attribute=None):
|
||||
def _add_element(self, tag, text=None, parent=None, class_id=None, attribute=None):
|
||||
"""
|
||||
Creates a html element. If ``text`` is given, the element's text will set and if a ``parent`` is given,
|
||||
the element is appended.
|
||||
|
@ -262,7 +263,7 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
|
|||
:param tag: The html tag, e. g. ``'span'``. Defaults to ``None``.
|
||||
:param text: The text for the tag. Defaults to ``None``.
|
||||
:param parent: The parent element. Defaults to ``None``.
|
||||
:param classId: Value for the class attribute
|
||||
:param class_id: Value for the class attribute
|
||||
:param attribute: Tuple name/value pair to add as an optional attribute
|
||||
"""
|
||||
if text is not None:
|
||||
|
@ -271,8 +272,8 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
|
|||
element = lxml.html.Element(tag)
|
||||
if parent is not None:
|
||||
parent.append(element)
|
||||
if classId is not None:
|
||||
element.set('class', classId)
|
||||
if class_id is not None:
|
||||
element.set('class', class_id)
|
||||
if attribute is not None:
|
||||
element.set(attribute[0], attribute[1])
|
||||
return element
|
||||
|
|
|
@ -25,8 +25,8 @@ The UI widgets for the service item edit dialog
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box, create_button
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_ServiceItemEditDialog(object):
|
||||
|
@ -38,7 +38,7 @@ class Ui_ServiceItemEditDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
serviceItemEditDialog.setObjectName('serviceItemEditDialog')
|
||||
serviceItemEditDialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
serviceItemEditDialog.setWindowIcon(UiIcons().main_icon)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(serviceItemEditDialog)
|
||||
self.dialog_layout.setContentsMargins(8, 8, 8, 8)
|
||||
self.dialog_layout.setSpacing(8)
|
||||
|
|
|
@ -37,6 +37,7 @@ from openlp.core.common import ThemeLevel, delete_file
|
|||
from openlp.core.common.actions import ActionList, CategoryOrder
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.i18n import UiStrings, format_time, translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
from openlp.core.common.path import Path, str_to_path
|
||||
|
@ -137,14 +138,14 @@ class Ui_ServiceManager(object):
|
|||
self.layout.setContentsMargins(0, 0, 0, 0)
|
||||
# Create the top toolbar
|
||||
self.toolbar = OpenLPToolbar(self)
|
||||
self.toolbar.add_toolbar_action('newService', text=UiStrings().NewService, icon=':/general/general_new.png',
|
||||
self.toolbar.add_toolbar_action('newService', text=UiStrings().NewService, icon=UiIcons().new,
|
||||
tooltip=UiStrings().CreateService, triggers=self.on_new_service_clicked)
|
||||
self.toolbar.add_toolbar_action('openService', text=UiStrings().OpenService,
|
||||
icon=':/general/general_open.png',
|
||||
icon=UiIcons().open,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Load an existing service.'),
|
||||
triggers=self.on_load_service_clicked)
|
||||
self.toolbar.add_toolbar_action('saveService', text=UiStrings().SaveService,
|
||||
icon=':/general/general_save.png',
|
||||
icon=UiIcons().save,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Save this service.'),
|
||||
triggers=self.decide_save_method)
|
||||
self.toolbar.addSeparator()
|
||||
|
@ -178,45 +179,45 @@ class Ui_ServiceManager(object):
|
|||
action_list.add_category(UiStrings().Service, CategoryOrder.standard_toolbar)
|
||||
self.move_top_action = self.order_toolbar.add_toolbar_action(
|
||||
'moveTop',
|
||||
text=translate('OpenLP.ServiceManager', 'Move to &top'), icon=':/services/service_top.png',
|
||||
text=translate('OpenLP.ServiceManager', 'Move to &top'), icon=UiIcons().top,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Move item to the top of the service.'),
|
||||
can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_top)
|
||||
self.move_up_action = self.order_toolbar.add_toolbar_action(
|
||||
'moveUp',
|
||||
text=translate('OpenLP.ServiceManager', 'Move &up'), icon=':/services/service_up.png',
|
||||
text=translate('OpenLP.ServiceManager', 'Move &up'), icon=UiIcons().arrow_up,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Move item up one position in the service.'),
|
||||
can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_up)
|
||||
self.move_down_action = self.order_toolbar.add_toolbar_action(
|
||||
'moveDown',
|
||||
text=translate('OpenLP.ServiceManager', 'Move &down'), icon=':/services/service_down.png',
|
||||
text=translate('OpenLP.ServiceManager', 'Move &down'), icon=UiIcons().arrow_down,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Move item down one position in the service.'),
|
||||
can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_down)
|
||||
self.move_bottom_action = self.order_toolbar.add_toolbar_action(
|
||||
'moveBottom',
|
||||
text=translate('OpenLP.ServiceManager', 'Move to &bottom'), icon=':/services/service_bottom.png',
|
||||
text=translate('OpenLP.ServiceManager', 'Move to &bottom'), icon=UiIcons().bottom,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Move item to the end of the service.'),
|
||||
can_shortcuts=True, category=UiStrings().Service, triggers=self.on_service_end)
|
||||
self.order_toolbar.addSeparator()
|
||||
self.delete_action = self.order_toolbar.add_toolbar_action(
|
||||
'delete', can_shortcuts=True,
|
||||
text=translate('OpenLP.ServiceManager', '&Delete From Service'), icon=':/general/general_delete.png',
|
||||
text=translate('OpenLP.ServiceManager', '&Delete From Service'), icon=UiIcons().delete,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Delete the selected item from the service.'),
|
||||
triggers=self.on_delete_from_service)
|
||||
self.order_toolbar.addSeparator()
|
||||
self.expand_action = self.order_toolbar.add_toolbar_action(
|
||||
'expand', can_shortcuts=True,
|
||||
text=translate('OpenLP.ServiceManager', '&Expand all'), icon=':/services/service_expand_all.png',
|
||||
text=translate('OpenLP.ServiceManager', '&Expand all'), icon=UiIcons().plus,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Expand all the service items.'),
|
||||
category=UiStrings().Service, triggers=self.on_expand_all)
|
||||
self.collapse_action = self.order_toolbar.add_toolbar_action(
|
||||
'collapse', can_shortcuts=True,
|
||||
text=translate('OpenLP.ServiceManager', '&Collapse all'), icon=':/services/service_collapse_all.png',
|
||||
text=translate('OpenLP.ServiceManager', '&Collapse all'), icon=UiIcons().minus,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Collapse all the service items.'),
|
||||
category=UiStrings().Service, triggers=self.on_collapse_all)
|
||||
self.order_toolbar.addSeparator()
|
||||
self.make_live_action = self.order_toolbar.add_toolbar_action(
|
||||
'make_live', can_shortcuts=True,
|
||||
text=translate('OpenLP.ServiceManager', 'Go Live'), icon=':/general/general_live.png',
|
||||
text=translate('OpenLP.ServiceManager', 'Go Live'), icon=UiIcons().live,
|
||||
tooltip=translate('OpenLP.ServiceManager', 'Send the selected item to Live.'),
|
||||
category=UiStrings().Service,
|
||||
triggers=self.on_make_live_action_triggered)
|
||||
|
@ -233,33 +234,33 @@ class Ui_ServiceManager(object):
|
|||
# build the drag and drop context menu
|
||||
self.dnd_menu = QtWidgets.QMenu()
|
||||
self.new_action = self.dnd_menu.addAction(translate('OpenLP.ServiceManager', '&Add New Item'))
|
||||
self.new_action.setIcon(build_icon(':/general/general_edit.png'))
|
||||
self.new_action.setIcon(UiIcons().edit)
|
||||
self.add_to_action = self.dnd_menu.addAction(translate('OpenLP.ServiceManager', '&Add to Selected Item'))
|
||||
self.add_to_action.setIcon(build_icon(':/general/general_edit.png'))
|
||||
self.add_to_action.setIcon(UiIcons().edit)
|
||||
# build the context menu
|
||||
self.menu = QtWidgets.QMenu()
|
||||
self.edit_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Edit Item'),
|
||||
icon=':/general/general_edit.png', triggers=self.remote_edit)
|
||||
icon=UiIcons().edit, triggers=self.remote_edit)
|
||||
self.rename_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Rename...'),
|
||||
icon=':/general/general_edit.png',
|
||||
icon=UiIcons().edit,
|
||||
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',
|
||||
icon=UiIcons().edit,
|
||||
triggers=self.on_service_item_edit_form)
|
||||
self.notes_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Notes'),
|
||||
icon=':/services/service_notes.png',
|
||||
icon=UiIcons().notes,
|
||||
triggers=self.on_service_item_note_form)
|
||||
self.time_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', '&Start Time'),
|
||||
icon=':/media/media_time.png', triggers=self.on_start_time_form)
|
||||
icon=UiIcons().time, triggers=self.on_start_time_form)
|
||||
self.auto_start_action = create_widget_action(self.menu, text='',
|
||||
icon=':/media/auto-start_active.png',
|
||||
icon=UiIcons().active,
|
||||
triggers=self.on_auto_start)
|
||||
# Add already existing delete action to the menu.
|
||||
self.menu.addAction(self.delete_action)
|
||||
self.create_custom_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ServiceManager', 'Create New &Custom '
|
||||
'Slide'),
|
||||
icon=':/general/general_edit.png',
|
||||
icon=UiIcons().clone,
|
||||
triggers=self.create_custom)
|
||||
self.menu.addSeparator()
|
||||
# Add AutoPlay menu actions
|
||||
|
@ -284,7 +285,7 @@ class Ui_ServiceManager(object):
|
|||
triggers=self.on_timed_slide_interval)
|
||||
self.menu.addSeparator()
|
||||
self.preview_action = create_widget_action(self.menu, text=translate('OpenLP.ServiceManager', 'Show &Preview'),
|
||||
icon=':/general/general_preview.png', triggers=self.make_preview)
|
||||
icon=UiIcons().preview, triggers=self.make_preview)
|
||||
# Add already existing make live action to the menu.
|
||||
self.menu.addAction(self.make_live_action)
|
||||
self.menu.addSeparator()
|
||||
|
@ -314,8 +315,6 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
|
|||
Sets up the service manager, toolbars, list view, et al.
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.active = build_icon(':/media/auto-start_active.png')
|
||||
self.inactive = build_icon(':/media/auto-start_inactive.png')
|
||||
self.service_items = []
|
||||
self.suffixes = []
|
||||
self.drop_position = -1
|
||||
|
@ -800,11 +799,12 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
|
|||
self.time_action.setVisible(True)
|
||||
if service_item['service_item'].is_capable(ItemCapabilities.CanAutoStartForLive):
|
||||
self.auto_start_action.setVisible(True)
|
||||
self.auto_start_action.setIcon(self.inactive)
|
||||
self.auto_start_action.setText(translate('OpenLP.ServiceManager', '&Auto Start - inactive'))
|
||||
if service_item['service_item'].will_auto_start:
|
||||
self.auto_start_action.setText(translate('OpenLP.ServiceManager', '&Auto Start - active'))
|
||||
self.auto_start_action.setIcon(self.active)
|
||||
self.auto_start_action.setIcon(UiIcons().active)
|
||||
else:
|
||||
self.auto_start_action.setIcon(UiIcons().inactive)
|
||||
self.auto_start_action.setText(translate('OpenLP.ServiceManager', '&Auto Start - inactive'))
|
||||
if service_item['service_item'].is_text():
|
||||
for plugin in self.plugin_manager.plugins:
|
||||
if plugin.name == 'custom' and plugin.status == PluginStatus.Active:
|
||||
|
@ -1169,27 +1169,27 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
|
|||
tree_widget_item = QtWidgets.QTreeWidgetItem(self.service_manager_list)
|
||||
if service_item_from_item.is_valid:
|
||||
if service_item_from_item.notes:
|
||||
icon = QtGui.QImage(service_item_from_item.icon)
|
||||
icon = service_item_from_item.icon.pixmap(80, 80).toImage()
|
||||
icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
overlay = QtGui.QImage(':/services/service_item_notes.png')
|
||||
overlay = overlay.scaled(80, 80, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
overlay = UiIcons().notes.pixmap(40, 40).toImage()
|
||||
overlay = overlay.scaled(40, 40, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
painter = QtGui.QPainter(icon)
|
||||
painter.drawImage(0, 0, overlay)
|
||||
painter.end()
|
||||
tree_widget_item.setIcon(0, build_icon(icon))
|
||||
elif service_item_from_item.temporary_edit:
|
||||
icon = QtGui.QImage(service_item_from_item.icon)
|
||||
icon = service_item_from_item.icon.pixmap(80, 80).toImage()
|
||||
icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
overlay = QtGui.QImage(':/general/general_export.png')
|
||||
overlay = QtGui.QImage(UiIcons().upload)
|
||||
overlay = overlay.scaled(40, 40, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
painter = QtGui.QPainter(icon)
|
||||
painter.drawImage(40, 0, overlay)
|
||||
painter.end()
|
||||
tree_widget_item.setIcon(0, build_icon(icon))
|
||||
else:
|
||||
tree_widget_item.setIcon(0, service_item_from_item.iconic_representation)
|
||||
tree_widget_item.setIcon(0, service_item_from_item.icon)
|
||||
else:
|
||||
tree_widget_item.setIcon(0, build_icon(':/general/general_delete.png'))
|
||||
tree_widget_item.setIcon(0, UiIcons().delete)
|
||||
tree_widget_item.setText(0, service_item_from_item.get_display_title())
|
||||
tips = []
|
||||
if service_item_from_item.temporary_edit:
|
||||
|
|
|
@ -25,8 +25,8 @@ The UI widgets of the settings dialog.
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_SettingsDialog(object):
|
||||
|
@ -38,7 +38,7 @@ class Ui_SettingsDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
settings_dialog.setObjectName('settings_dialog')
|
||||
settings_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
settings_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
settings_dialog.resize(920, 625)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(settings_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -25,8 +25,8 @@ The list of shortcuts within a dialog.
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class CaptureShortcutButton(QtWidgets.QPushButton):
|
||||
|
@ -72,7 +72,7 @@ class Ui_ShortcutListDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
shortcutListDialog.setObjectName('shortcutListDialog')
|
||||
shortcutListDialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
shortcutListDialog.setWindowIcon(UiIcons().main_icon)
|
||||
shortcutListDialog.resize(500, 438)
|
||||
self.shortcut_list_layout = QtWidgets.QVBoxLayout(shortcutListDialog)
|
||||
self.shortcut_list_layout.setObjectName('shortcut_list_layout')
|
||||
|
@ -101,23 +101,23 @@ class Ui_ShortcutListDialog(object):
|
|||
self.primary_push_button = CaptureShortcutButton(shortcutListDialog)
|
||||
self.primary_push_button.setObjectName('primary_push_button')
|
||||
self.primary_push_button.setMinimumSize(QtCore.QSize(84, 0))
|
||||
self.primary_push_button.setIcon(build_icon(':/system/system_configure_shortcuts.png'))
|
||||
self.primary_push_button.setIcon(UiIcons.shortcuts)
|
||||
self.primary_layout.addWidget(self.primary_push_button)
|
||||
self.clear_primary_button = QtWidgets.QToolButton(shortcutListDialog)
|
||||
self.clear_primary_button.setObjectName('clear_primary_button')
|
||||
self.clear_primary_button.setMinimumSize(QtCore.QSize(0, 16))
|
||||
self.clear_primary_button.setIcon(build_icon(':/system/clear_shortcut.png'))
|
||||
self.clear_primary_button.setIcon(UiIcons().settings)
|
||||
self.primary_layout.addWidget(self.clear_primary_button)
|
||||
self.details_layout.addLayout(self.primary_layout, 1, 1, 1, 1)
|
||||
self.alternate_layout = QtWidgets.QHBoxLayout()
|
||||
self.alternate_layout.setObjectName('alternate_layout')
|
||||
self.alternate_push_button = CaptureShortcutButton(shortcutListDialog)
|
||||
self.alternate_push_button.setObjectName('alternate_push_button')
|
||||
self.alternate_push_button.setIcon(build_icon(':/system/system_configure_shortcuts.png'))
|
||||
self.alternate_push_button.setIcon(UiIcons().settings)
|
||||
self.alternate_layout.addWidget(self.alternate_push_button)
|
||||
self.clear_alternate_button = QtWidgets.QToolButton(shortcutListDialog)
|
||||
self.clear_alternate_button.setObjectName('clear_alternate_button')
|
||||
self.clear_alternate_button.setIcon(build_icon(':/system/clear_shortcut.png'))
|
||||
self.clear_alternate_button.setIcon(UiIcons().settings)
|
||||
self.alternate_layout.addWidget(self.clear_alternate_button)
|
||||
self.details_layout.addLayout(self.alternate_layout, 1, 2, 1, 1)
|
||||
self.primary_label = QtWidgets.QLabel(shortcutListDialog)
|
||||
|
|
|
@ -38,6 +38,7 @@ from openlp.core.display.screens import ScreenList
|
|||
from openlp.core.lib import ItemCapabilities, ImageSource, ServiceItemAction, build_icon
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.core.ui import HideMode, DisplayControllerType
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.display.window import DisplayWindow
|
||||
from openlp.core.widgets.layouts import AspectRatioLayout
|
||||
from openlp.core.widgets.toolbar import OpenLPToolbar
|
||||
|
@ -211,14 +212,14 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
self.toolbar.setSizePolicy(size_toolbar_policy)
|
||||
self.previous_item = create_action(self, 'previousItem_' + self.type_prefix,
|
||||
text=translate('OpenLP.SlideController', 'Previous Slide'),
|
||||
icon=':/slides/slide_previous.png',
|
||||
icon=UiIcons().arrow_left,
|
||||
tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
|
||||
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.on_slide_selected_previous)
|
||||
self.toolbar.addAction(self.previous_item)
|
||||
self.next_item = create_action(self, 'nextItem_' + self.type_prefix,
|
||||
text=translate('OpenLP.SlideController', 'Next Slide'),
|
||||
icon=':/slides/slide_next.png',
|
||||
icon=UiIcons().arrow_right,
|
||||
tooltip=translate('OpenLP.SlideController', 'Move to next.'),
|
||||
can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.on_slide_selected_next_action)
|
||||
|
@ -234,28 +235,28 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
self.hide_menu.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup)
|
||||
self.hide_menu.setMenu(QtWidgets.QMenu(translate('OpenLP.SlideController', 'Hide'), self.toolbar))
|
||||
self.toolbar.add_toolbar_widget(self.hide_menu)
|
||||
self.toolbar.add_toolbar_action('goPreview', icon=':/general/general_live.png',
|
||||
self.toolbar.add_toolbar_action('goPreview', icon=UiIcons().live,
|
||||
tooltip=translate('OpenLP.SlideController', 'Move to preview.'),
|
||||
triggers=self.on_go_preview)
|
||||
# The order of the blank to modes in Shortcuts list comes from here.
|
||||
self.desktop_screen_enable = create_action(self, 'desktopScreenEnable',
|
||||
text=translate('OpenLP.SlideController', 'Show Desktop'),
|
||||
icon=':/slides/slide_desktop.png', can_shortcuts=True,
|
||||
icon=UiIcons().desktop, can_shortcuts=True,
|
||||
context=QtCore.Qt.WidgetWithChildrenShortcut,
|
||||
category=self.category, triggers=self.on_hide_display_enable)
|
||||
self.desktop_screen = create_action(self, 'desktopScreen',
|
||||
text=translate('OpenLP.SlideController', 'Toggle Desktop'),
|
||||
icon=':/slides/slide_desktop.png',
|
||||
icon=UiIcons().desktop,
|
||||
checked=False, can_shortcuts=True, category=self.category,
|
||||
triggers=self.on_hide_display)
|
||||
self.theme_screen = create_action(self, 'themeScreen',
|
||||
text=translate('OpenLP.SlideController', 'Toggle Blank to Theme'),
|
||||
icon=':/slides/slide_theme.png',
|
||||
icon=UiIcons().blank_theme,
|
||||
checked=False, can_shortcuts=True, category=self.category,
|
||||
triggers=self.on_theme_display)
|
||||
self.blank_screen = create_action(self, 'blankScreen',
|
||||
text=translate('OpenLP.SlideController', 'Toggle Blank Screen'),
|
||||
icon=':/slides/slide_blank.png',
|
||||
icon=UiIcons().blank,
|
||||
checked=False, can_shortcuts=True, category=self.category,
|
||||
triggers=self.on_blank_display)
|
||||
self.hide_menu.setDefaultAction(self.blank_screen)
|
||||
|
@ -286,10 +287,10 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
self.toolbar))
|
||||
self.toolbar.add_toolbar_widget(self.play_slides_menu)
|
||||
self.play_slides_loop = create_action(self, 'playSlidesLoop', text=UiStrings().PlaySlidesInLoop,
|
||||
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
|
||||
icon=UiIcons().clock, checked=False, can_shortcuts=True,
|
||||
category=self.category, triggers=self.on_play_slides_loop)
|
||||
self.play_slides_once = create_action(self, 'playSlidesOnce', text=UiStrings().PlaySlidesToEnd,
|
||||
icon=':/media/media_time.png', checked=False, can_shortcuts=True,
|
||||
icon=UiIcons().clock, checked=False, can_shortcuts=True,
|
||||
category=self.category, triggers=self.on_play_slides_once)
|
||||
if Settings().value(self.main_window.advanced_settings_section + '/slide limits') == SlideLimits.Wrap:
|
||||
self.play_slides_menu.setDefaultAction(self.play_slides_loop)
|
||||
|
@ -306,18 +307,18 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
self.receive_spin_delay()
|
||||
self.toolbar.add_toolbar_widget(self.delay_spin_box)
|
||||
else:
|
||||
self.toolbar.add_toolbar_action('goLive', icon=':/general/general_live.png',
|
||||
self.toolbar.add_toolbar_action('goLive', icon=UiIcons().live,
|
||||
tooltip=translate('OpenLP.SlideController', 'Move to live.'),
|
||||
triggers=self.on_go_live)
|
||||
self.toolbar.add_toolbar_action('addToService', icon=':/general/general_add.png',
|
||||
self.toolbar.add_toolbar_action('addToService', icon=UiIcons().add,
|
||||
tooltip=translate('OpenLP.SlideController', 'Add to Service.'),
|
||||
triggers=self.on_preview_add_to_service)
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.add_toolbar_action('editSong', icon=':/general/general_edit.png',
|
||||
self.toolbar.add_toolbar_action('editSong', icon=UiIcons().edit,
|
||||
tooltip=translate('OpenLP.SlideController',
|
||||
'Edit and reload song preview.'),
|
||||
triggers=self.on_edit_song)
|
||||
self.toolbar.add_toolbar_action('clear', icon=':/general/general_delete.png',
|
||||
self.toolbar.add_toolbar_action('clear', icon=UiIcons().delete,
|
||||
tooltip=translate('OpenLP.SlideController',
|
||||
'Clear'),
|
||||
triggers=self.on_clear)
|
||||
|
@ -336,7 +337,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
# FIXME: object name should be changed. But this requires that we migrate the shortcut.
|
||||
self.audio_pause_item = self.toolbar.add_toolbar_action(
|
||||
'audioPauseItem',
|
||||
icon=':/slides/media_playback_pause.png', text=translate('OpenLP.SlideController', 'Pause Audio'),
|
||||
icon=UiIcons().pause, text=translate('OpenLP.SlideController', 'Pause Audio'),
|
||||
tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
|
||||
checked=False, visible=False, category=self.category, context=QtCore.Qt.WindowShortcut,
|
||||
can_shortcuts=True, triggers=self.set_audio_pause_clicked)
|
||||
|
@ -345,7 +346,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
self.audio_pause_item.setParent(self.toolbar)
|
||||
self.toolbar.widgetForAction(self.audio_pause_item).setPopupMode(QtWidgets.QToolButton.MenuButtonPopup)
|
||||
self.next_track_item = create_action(self, 'nextTrackItem', text=UiStrings().NextTrack,
|
||||
icon=':/slides/media_playback_next.png',
|
||||
icon=UiIcons().arrow_right,
|
||||
tooltip=translate('OpenLP.SlideController',
|
||||
'Go to next audio track.'),
|
||||
category=self.category,
|
||||
|
@ -680,10 +681,10 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
self.toolbar.set_widget_visible('song_menu', False)
|
||||
# Reset the button
|
||||
self.play_slides_once.setChecked(False)
|
||||
self.play_slides_once.setIcon(build_icon(':/media/media_time.png'))
|
||||
self.play_slides_once.setIcon(UiIcons().clock)
|
||||
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
|
||||
self.play_slides_loop.setChecked(False)
|
||||
self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
|
||||
self.play_slides_loop.setIcon(UiIcons().clock)
|
||||
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
||||
if item.is_text():
|
||||
if (Settings().value(self.main_window.songs_settings_section + '/display songbar') and
|
||||
|
@ -1096,7 +1097,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
# done by the thread holding the lock. If it is a "start" slide, we must wait for the lock, but only for 0.2
|
||||
# seconds, since we don't want to cause a deadlock
|
||||
timeout = 0.2 if start else -1
|
||||
if not self.slide_selected_lock.acquire(start, timeout):
|
||||
if not self.slide_selected_lock.acquire(start, timeout): # pylint: disable=too-many-function-args
|
||||
if start:
|
||||
self.log_debug('Could not get lock in slide_selected after waiting %f, skip to avoid deadlock.'
|
||||
% timeout)
|
||||
|
@ -1286,16 +1287,16 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
self.play_slides_loop.setChecked(checked)
|
||||
self.log_debug('on_play_slides_loop {text}'.format(text=checked))
|
||||
if checked:
|
||||
self.play_slides_loop.setIcon(build_icon(':/media/media_stop.png'))
|
||||
self.play_slides_loop.setIcon(UiIcons().stop)
|
||||
self.play_slides_loop.setText(UiStrings().StopPlaySlidesInLoop)
|
||||
self.play_slides_once.setIcon(build_icon(':/media/media_time.png'))
|
||||
self.play_slides_once.setIcon(UiIcons().clock)
|
||||
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
|
||||
self.play_slides_menu.setDefaultAction(self.play_slides_loop)
|
||||
self.play_slides_once.setChecked(False)
|
||||
if Settings().value('core/click live slide to unblank'):
|
||||
Registry().execute('slidecontroller_live_unblank')
|
||||
else:
|
||||
self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
|
||||
self.play_slides_loop.setIcon(UiIcons().clock)
|
||||
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
||||
self.on_toggle_loop()
|
||||
|
||||
|
@ -1311,16 +1312,16 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||
self.play_slides_once.setChecked(checked)
|
||||
self.log_debug('on_play_slides_once {text}'.format(text=checked))
|
||||
if checked:
|
||||
self.play_slides_once.setIcon(build_icon(':/media/media_stop.png'))
|
||||
self.play_slides_once.setIcon(UiIcons().stop)
|
||||
self.play_slides_once.setText(UiStrings().StopPlaySlidesToEnd)
|
||||
self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
|
||||
self.play_slides_loop.setIcon(UiIcons().clock)
|
||||
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
||||
self.play_slides_menu.setDefaultAction(self.play_slides_once)
|
||||
self.play_slides_loop.setChecked(False)
|
||||
if Settings().value('core/click live slide to unblank'):
|
||||
Registry().execute('slidecontroller_live_unblank')
|
||||
else:
|
||||
self.play_slides_once.setIcon(build_icon(':/media/media_time'))
|
||||
self.play_slides_once.setIcon(UiIcons().clock)
|
||||
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
|
||||
self.on_toggle_loop()
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ The UI widgets for the time dialog
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_StartTimeDialog(object):
|
||||
|
@ -38,7 +38,7 @@ class Ui_StartTimeDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
StartTimeDialog.setObjectName('StartTimeDialog')
|
||||
StartTimeDialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
StartTimeDialog.setWindowIcon(UiIcons().main_icon)
|
||||
StartTimeDialog.resize(350, 10)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(StartTimeDialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -25,8 +25,8 @@ The layout of the theme
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_ThemeLayoutDialog(object):
|
||||
|
@ -38,7 +38,7 @@ class Ui_ThemeLayoutDialog(object):
|
|||
Set up the UI
|
||||
"""
|
||||
themeLayoutDialog.setObjectName('themeLayoutDialogDialog')
|
||||
themeLayoutDialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
themeLayoutDialog.setWindowIcon(UiIcons().main_icon)
|
||||
self.preview_layout = QtWidgets.QVBoxLayout(themeLayoutDialog)
|
||||
self.preview_layout.setObjectName('preview_layout')
|
||||
self.preview_area = QtWidgets.QWidget(themeLayoutDialog)
|
||||
|
|
|
@ -31,6 +31,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|||
from openlp.core.common import delete_file
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.i18n import UiStrings, translate, get_locale_key
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
from openlp.core.common.path import Path, copyfile, create_paths, path_to_str
|
||||
from openlp.core.common.registry import Registry, RegistryBase
|
||||
|
@ -61,30 +62,30 @@ class Ui_ThemeManager(object):
|
|||
self.toolbar = OpenLPToolbar(widget)
|
||||
self.toolbar.setObjectName('toolbar')
|
||||
self.toolbar.add_toolbar_action('newTheme',
|
||||
text=UiStrings().NewTheme, icon=':/themes/theme_new.png',
|
||||
text=UiStrings().NewTheme, icon=UiIcons().new,
|
||||
tooltip=translate('OpenLP.ThemeManager', 'Create a new theme.'),
|
||||
triggers=self.on_add_theme)
|
||||
self.toolbar.add_toolbar_action('editTheme',
|
||||
text=translate('OpenLP.ThemeManager', 'Edit Theme'),
|
||||
icon=':/themes/theme_edit.png',
|
||||
icon=UiIcons().edit,
|
||||
tooltip=translate('OpenLP.ThemeManager', 'Edit a theme.'),
|
||||
triggers=self.on_edit_theme)
|
||||
self.delete_toolbar_action = self.toolbar.add_toolbar_action('delete_theme',
|
||||
text=translate('OpenLP.ThemeManager',
|
||||
'Delete Theme'),
|
||||
icon=':/general/general_delete.png',
|
||||
icon=UiIcons().delete,
|
||||
tooltip=translate('OpenLP.ThemeManager',
|
||||
'Delete a theme.'),
|
||||
triggers=self.on_delete_theme)
|
||||
self.toolbar.addSeparator()
|
||||
self.toolbar.add_toolbar_action('importTheme',
|
||||
text=translate('OpenLP.ThemeManager', 'Import Theme'),
|
||||
icon=':/general/general_import.png',
|
||||
icon=UiIcons().download,
|
||||
tooltip=translate('OpenLP.ThemeManager', 'Import a theme.'),
|
||||
triggers=self.on_import_theme)
|
||||
self.toolbar.add_toolbar_action('exportTheme',
|
||||
text=translate('OpenLP.ThemeManager', 'Export Theme'),
|
||||
icon=':/general/general_export.png',
|
||||
icon=UiIcons().upload,
|
||||
tooltip=translate('OpenLP.ThemeManager', 'Export a theme.'),
|
||||
triggers=self.on_export_theme)
|
||||
self.layout.addWidget(self.toolbar)
|
||||
|
@ -102,24 +103,24 @@ class Ui_ThemeManager(object):
|
|||
self.menu = QtWidgets.QMenu()
|
||||
self.edit_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Edit Theme'),
|
||||
icon=':/themes/theme_edit.png', triggers=self.on_edit_theme)
|
||||
icon=UiIcons().edit, triggers=self.on_edit_theme)
|
||||
self.copy_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Copy Theme'),
|
||||
icon=':/themes/theme_edit.png', triggers=self.on_copy_theme)
|
||||
icon=UiIcons().copy, triggers=self.on_copy_theme)
|
||||
self.rename_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Rename Theme'),
|
||||
icon=':/themes/theme_edit.png', triggers=self.on_rename_theme)
|
||||
icon=UiIcons().edit, triggers=self.on_rename_theme)
|
||||
self.delete_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Delete Theme'),
|
||||
icon=':/general/general_delete.png', triggers=self.on_delete_theme)
|
||||
icon=UiIcons().delete, triggers=self.on_delete_theme)
|
||||
self.menu.addSeparator()
|
||||
self.global_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', 'Set As &Global Default'),
|
||||
icon=':/general/general_export.png',
|
||||
icon=UiIcons().default,
|
||||
triggers=self.change_global_from_screen)
|
||||
self.export_action = create_widget_action(self.menu,
|
||||
text=translate('OpenLP.ThemeManager', '&Export Theme'),
|
||||
icon=':/general/general_export.png', triggers=self.on_export_theme)
|
||||
icon=UiIcons().upload, triggers=self.on_export_theme)
|
||||
# Signals
|
||||
self.theme_list_widget.doubleClicked.connect(self.change_global_from_screen)
|
||||
self.theme_list_widget.currentItemChanged.connect(self.check_list_state)
|
||||
|
|
|
@ -30,6 +30,7 @@ from openlp.core.common.registry import Registry
|
|||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import SettingsTab
|
||||
from openlp.core.lib.ui import find_and_set_in_combo_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class ThemesTab(SettingsTab):
|
||||
|
@ -40,7 +41,7 @@ class ThemesTab(SettingsTab):
|
|||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.icon_path = ':/themes/theme_new.png'
|
||||
self.icon_path = UiIcons().theme
|
||||
theme_translated = translate('OpenLP.ThemesTab', 'Themes')
|
||||
super(ThemesTab, self).__init__(parent, 'Themes', theme_translated)
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|||
|
||||
from openlp.core.common import is_macosx
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGradientType
|
||||
from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.buttons import ColorButton
|
||||
from openlp.core.widgets.edits import PathEdit
|
||||
|
||||
|
@ -42,7 +42,7 @@ class Ui_ThemeWizard(object):
|
|||
Set up the UI
|
||||
"""
|
||||
theme_wizard.setObjectName('OpenLP.ThemeWizard')
|
||||
theme_wizard.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
theme_wizard.setWindowIcon(UiIcons().main_icon)
|
||||
theme_wizard.setModal(True)
|
||||
theme_wizard.setOptions(QtWidgets.QWizard.IndependentPages |
|
||||
QtWidgets.QWizard.NoBackButtonOnStartPage | QtWidgets.QWizard.HaveCustomButton1)
|
||||
|
|
|
@ -103,7 +103,8 @@ class VersionWorker(ThreadWorker):
|
|||
while retries < 3:
|
||||
try:
|
||||
response = requests.get(download_url, headers=headers)
|
||||
remote_version = response.text.strip()
|
||||
if response.status_code == 200:
|
||||
remote_version = response.text.strip()
|
||||
log.debug('New version found: %s', remote_version)
|
||||
break
|
||||
except OSError:
|
||||
|
@ -155,7 +156,7 @@ def get_version():
|
|||
full_version = file_path.read_text().rstrip()
|
||||
except OSError:
|
||||
log.exception('Error in version file.')
|
||||
full_version = '0.0.0-bzr000'
|
||||
full_version = '0.0.0'
|
||||
bits = full_version.split('-')
|
||||
APPLICATION_VERSION = {
|
||||
'full': full_version,
|
||||
|
|
|
@ -49,7 +49,7 @@ class ColorButton(QtWidgets.QPushButton):
|
|||
"""
|
||||
Sets the _color variable and the background color.
|
||||
|
||||
:param color: String representation of a hexidecimal color
|
||||
:param color: String representation of a hexadecimal color
|
||||
"""
|
||||
self._color = color
|
||||
self.setStyleSheet('background-color: %s' % color)
|
||||
|
@ -59,7 +59,7 @@ class ColorButton(QtWidgets.QPushButton):
|
|||
"""
|
||||
Property method to return the color variable
|
||||
|
||||
:return: String representation of a hexidecimal color
|
||||
:return: String representation of a hexadecimal color
|
||||
"""
|
||||
return self._color
|
||||
|
||||
|
@ -68,7 +68,7 @@ class ColorButton(QtWidgets.QPushButton):
|
|||
"""
|
||||
Property setter to change the instance color
|
||||
|
||||
:param color: String representation of a hexidecimal color
|
||||
:param color: String representation of a hexadecimal color
|
||||
"""
|
||||
self.change_color(color)
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ from openlp.core.common.path import Path, path_to_str, str_to_path
|
|||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import FormattingTags, build_icon
|
||||
from openlp.core.lib.ui import create_widget_action, create_action
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.dialogs import FileDialog
|
||||
from openlp.core.widgets.enums import PathEditType
|
||||
|
||||
|
@ -62,7 +63,7 @@ class SearchEdit(QtWidgets.QLineEdit):
|
|||
self.settings_section = settings_section
|
||||
self._current_search_type = -1
|
||||
self.clear_button = QtWidgets.QToolButton(self)
|
||||
self.clear_button.setIcon(build_icon(':/system/clear_shortcut.png'))
|
||||
self.clear_button.setIcon(UiIcons().shortcuts)
|
||||
self.clear_button.setCursor(QtCore.Qt.ArrowCursor)
|
||||
self.clear_button.setStyleSheet('QToolButton { border: none; padding: 0px; }')
|
||||
self.clear_button.resize(18, 18)
|
||||
|
@ -150,7 +151,7 @@ class SearchEdit(QtWidgets.QLineEdit):
|
|||
action.placeholder_text = placeholder
|
||||
if not hasattr(self, 'menu_button'):
|
||||
self.menu_button = QtWidgets.QToolButton(self)
|
||||
self.menu_button.setIcon(build_icon(':/system/clear_shortcut.png'))
|
||||
self.menu_button.setIcon(UiIcons().shortcuts)
|
||||
self.menu_button.setCursor(QtCore.Qt.ArrowCursor)
|
||||
self.menu_button.setPopupMode(QtWidgets.QToolButton.InstantPopup)
|
||||
self.menu_button.setStyleSheet('QToolButton { border: none; padding: 0px 10px 0px 0px; }')
|
||||
|
@ -229,10 +230,10 @@ class PathEdit(QtWidgets.QWidget):
|
|||
self.line_edit = QtWidgets.QLineEdit(self)
|
||||
widget_layout.addWidget(self.line_edit)
|
||||
self.browse_button = QtWidgets.QToolButton(self)
|
||||
self.browse_button.setIcon(build_icon(':/general/general_open.png'))
|
||||
self.browse_button.setIcon(UiIcons().open)
|
||||
widget_layout.addWidget(self.browse_button)
|
||||
self.revert_button = QtWidgets.QToolButton(self)
|
||||
self.revert_button.setIcon(build_icon(':/general/general_revert.png'))
|
||||
self.revert_button.setIcon(UiIcons().undo)
|
||||
self.revert_button.setVisible(show_revert)
|
||||
widget_layout.addWidget(self.revert_button)
|
||||
self.setLayout(widget_layout)
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2018 OpenLP Developers #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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:`~openlp.core.widgets.widgets` module contains custom widgets used in OpenLP
|
||||
"""
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.settings import ProxyMode, Settings
|
||||
|
||||
|
||||
class ProxyWidget(QtWidgets.QGroupBox):
|
||||
"""
|
||||
A proxy settings widget that implements loading and saving its settings.
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Initialise the widget.
|
||||
|
||||
:param QtWidgets.QWidget | None parent: The widgets parent
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self._setup()
|
||||
|
||||
def _setup(self):
|
||||
"""
|
||||
A setup method seperate from __init__ to allow easier testing
|
||||
"""
|
||||
self.setup_ui()
|
||||
self.load()
|
||||
|
||||
def setup_ui(self):
|
||||
"""
|
||||
Create the widget layout and sub widgets
|
||||
"""
|
||||
self.layout = QtWidgets.QFormLayout(self)
|
||||
self.radio_group = QtWidgets.QButtonGroup(self)
|
||||
self.no_proxy_radio = QtWidgets.QRadioButton('', self)
|
||||
self.radio_group.addButton(self.no_proxy_radio, ProxyMode.NO_PROXY)
|
||||
self.layout.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.no_proxy_radio)
|
||||
self.use_sysem_proxy_radio = QtWidgets.QRadioButton('', self)
|
||||
self.radio_group.addButton(self.use_sysem_proxy_radio, ProxyMode.SYSTEM_PROXY)
|
||||
self.layout.setWidget(1, QtWidgets.QFormLayout.SpanningRole, self.use_sysem_proxy_radio)
|
||||
self.manual_proxy_radio = QtWidgets.QRadioButton('', self)
|
||||
self.radio_group.addButton(self.manual_proxy_radio, ProxyMode.MANUAL_PROXY)
|
||||
self.layout.setWidget(2, QtWidgets.QFormLayout.SpanningRole, self.manual_proxy_radio)
|
||||
self.http_edit = QtWidgets.QLineEdit(self)
|
||||
self.layout.addRow('HTTP:', self.http_edit)
|
||||
self.https_edit = QtWidgets.QLineEdit(self)
|
||||
self.layout.addRow('HTTPS:', self.https_edit)
|
||||
self.username_edit = QtWidgets.QLineEdit(self)
|
||||
self.layout.addRow('Username:', self.username_edit)
|
||||
self.password_edit = QtWidgets.QLineEdit(self)
|
||||
self.password_edit.setEchoMode(QtWidgets.QLineEdit.Password)
|
||||
self.layout.addRow('Password:', self.password_edit)
|
||||
# Signal / Slots
|
||||
self.radio_group.buttonToggled.connect(self.on_radio_group_button_toggled)
|
||||
|
||||
def on_radio_group_button_toggled(self, button, checked):
|
||||
"""
|
||||
Handles the toggled signal on the radio buttons. The signal is emitted twice if a radio butting being toggled on
|
||||
causes another radio button in the group to be toggled off.
|
||||
|
||||
En/Disables the `Manual Proxy` line edits depending on the currently selected radio button
|
||||
|
||||
:param QtWidgets.QRadioButton button: The button that has toggled
|
||||
:param bool checked: The buttons new state
|
||||
"""
|
||||
id = self.radio_group.id(button) # The work around (see above comment)
|
||||
enable_manual_edits = id == ProxyMode.MANUAL_PROXY and checked
|
||||
self.http_edit.setEnabled(enable_manual_edits)
|
||||
self.https_edit.setEnabled(enable_manual_edits)
|
||||
self.username_edit.setEnabled(enable_manual_edits)
|
||||
self.password_edit.setEnabled(enable_manual_edits)
|
||||
|
||||
def retranslate_ui(self):
|
||||
"""
|
||||
Translate the Ui
|
||||
"""
|
||||
self.setTitle(translate('OpenLP.ProxyWidget', 'Proxy Server Settings'))
|
||||
self.no_proxy_radio.setText(translate('OpenLP.ProxyWidget', 'No prox&y'))
|
||||
self.use_sysem_proxy_radio.setText(translate('OpenLP.ProxyWidget', '&Use system proxy'))
|
||||
self.manual_proxy_radio.setText(translate('OpenLP.ProxyWidget', '&Manual proxy configuration'))
|
||||
proxy_example = translate('OpenLP.ProxyWidget', 'e.g. proxy_server_address:port_no')
|
||||
self.layout.labelForField(self.http_edit).setText(translate('OpenLP.ProxyWidget', 'HTTP:'))
|
||||
self.http_edit.setPlaceholderText(proxy_example)
|
||||
self.layout.labelForField(self.https_edit).setText(translate('OpenLP.ProxyWidget', 'HTTPS:'))
|
||||
self.https_edit.setPlaceholderText(proxy_example)
|
||||
self.layout.labelForField(self.username_edit).setText(translate('OpenLP.ProxyWidget', 'Username:'))
|
||||
self.layout.labelForField(self.password_edit).setText(translate('OpenLP.ProxyWidget', 'Password:'))
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
Load the data from the settings to the widget.
|
||||
"""
|
||||
settings = Settings()
|
||||
checked_radio = self.radio_group.button(settings.value('advanced/proxy mode'))
|
||||
checked_radio.setChecked(True)
|
||||
self.http_edit.setText(settings.value('advanced/proxy http'))
|
||||
self.https_edit.setText(settings.value('advanced/proxy https'))
|
||||
self.username_edit.setText(settings.value('advanced/proxy username'))
|
||||
self.password_edit.setText(settings.value('advanced/proxy password'))
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Save the widget data to the settings
|
||||
"""
|
||||
settings = Settings() # TODO: Migrate from old system
|
||||
settings.setValue('advanced/proxy mode', self.radio_group.checkedId())
|
||||
settings.setValue('advanced/proxy http', self.http_edit.text())
|
||||
settings.setValue('advanced/proxy https', self.https_edit.text())
|
||||
settings.setValue('advanced/proxy username', self.username_edit.text())
|
||||
settings.setValue('advanced/proxy password', self.password_edit.text())
|
|
@ -28,6 +28,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|||
|
||||
from openlp.core.common import is_macosx
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
|
@ -105,8 +106,8 @@ class OpenLPWizard(QtWidgets.QWizard, RegistryProperties):
|
|||
self.with_progress_page = add_progress_page
|
||||
self.setFixedWidth(640)
|
||||
self.setObjectName(name)
|
||||
self.open_icon = build_icon(':/general/general_open.png')
|
||||
self.delete_icon = build_icon(':/general/general_delete.png')
|
||||
self.open_icon = UiIcons().open
|
||||
self.delete_icon = UiIcons().delete
|
||||
self.finish_button = self.button(QtWidgets.QWizard.FinishButton)
|
||||
self.cancel_button = self.button(QtWidgets.QWizard.CancelButton)
|
||||
self.setupUi(image)
|
||||
|
@ -123,7 +124,7 @@ class OpenLPWizard(QtWidgets.QWizard, RegistryProperties):
|
|||
Set up the wizard UI.
|
||||
:param image: path to start up image
|
||||
"""
|
||||
self.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
self.setWindowIcon(UiIcons().main_icon)
|
||||
self.setModal(True)
|
||||
self.setOptions(QtWidgets.QWizard.IndependentPages |
|
||||
QtWidgets.QWizard.NoBackButtonOnStartPage | QtWidgets.QWizard.NoBackButtonOnLastPage)
|
||||
|
@ -192,12 +193,12 @@ class OpenLPWizard(QtWidgets.QWizard, RegistryProperties):
|
|||
self.error_copy_to_button = QtWidgets.QPushButton(self.progress_page)
|
||||
self.error_copy_to_button.setObjectName('error_copy_to_button')
|
||||
self.error_copy_to_button.setHidden(True)
|
||||
self.error_copy_to_button.setIcon(build_icon(':/system/system_edit_copy.png'))
|
||||
self.error_copy_to_button.setIcon(UiIcons().copy)
|
||||
self.error_button_layout.addWidget(self.error_copy_to_button)
|
||||
self.error_save_to_button = QtWidgets.QPushButton(self.progress_page)
|
||||
self.error_save_to_button.setObjectName('error_save_to_button')
|
||||
self.error_save_to_button.setHidden(True)
|
||||
self.error_save_to_button.setIcon(build_icon(':/general/general_save.png'))
|
||||
self.error_save_to_button.setIcon(UiIcons().save)
|
||||
self.error_button_layout.addWidget(self.error_save_to_button)
|
||||
self.progress_layout.addLayout(self.error_button_layout)
|
||||
self.addPage(self.progress_page)
|
||||
|
|
|
@ -28,11 +28,12 @@ from openlp.core.api.http import register_endpoint
|
|||
from openlp.core.common.actions import ActionList
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon
|
||||
from openlp.core.lib import Plugin, StringContent
|
||||
from openlp.core.lib.db import Manager
|
||||
from openlp.core.lib.theme import VerticalType
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.core.ui import AlertLocation
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.plugins.alerts.endpoint import api_alerts_endpoint, alerts_endpoint
|
||||
from openlp.plugins.alerts.forms import AlertForm
|
||||
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
|
||||
|
@ -138,8 +139,8 @@ class AlertsPlugin(Plugin):
|
|||
"""
|
||||
super(AlertsPlugin, self).__init__('alerts', __default_settings__, settings_tab_class=AlertsTab)
|
||||
self.weight = -3
|
||||
self.icon_path = ':/plugins/plugin_alerts.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.icon_path = UiIcons().alert
|
||||
self.icon = self.icon_path
|
||||
AlertsManager(self)
|
||||
self.manager = Manager('alerts', init_schema)
|
||||
self.alert_form = AlertForm(self)
|
||||
|
@ -155,7 +156,7 @@ class AlertsPlugin(Plugin):
|
|||
log.info('add tools menu')
|
||||
self.tools_alert_item = create_action(tools_menu, 'toolsAlertItem',
|
||||
text=translate('AlertsPlugin', '&Alert'),
|
||||
icon=':/plugins/plugin_alerts.png',
|
||||
icon=UiIcons().alert,
|
||||
statustip=translate('AlertsPlugin', 'Show an alert message.'),
|
||||
visible=False, can_shortcuts=True, triggers=self.on_alerts_trigger)
|
||||
self.main_window.tools_menu.addAction(self.tools_alert_item)
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.lib.ui import create_button, create_button_box
|
||||
|
||||
|
||||
|
@ -39,7 +39,7 @@ class Ui_AlertDialog(object):
|
|||
"""
|
||||
alert_dialog.setObjectName('alert_dialog')
|
||||
alert_dialog.resize(400, 300)
|
||||
alert_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
alert_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
self.alert_dialog_layout = QtWidgets.QGridLayout(alert_dialog)
|
||||
self.alert_dialog_layout.setObjectName('alert_dialog_layout')
|
||||
self.alert_text_layout = QtWidgets.QFormLayout()
|
||||
|
@ -64,12 +64,12 @@ class Ui_AlertDialog(object):
|
|||
self.manage_button_layout = QtWidgets.QVBoxLayout()
|
||||
self.manage_button_layout.setObjectName('manage_button_layout')
|
||||
self.new_button = QtWidgets.QPushButton(alert_dialog)
|
||||
self.new_button.setIcon(build_icon(':/general/general_new.png'))
|
||||
self.new_button.setIcon(UiIcons().new)
|
||||
self.new_button.setObjectName('new_button')
|
||||
self.manage_button_layout.addWidget(self.new_button)
|
||||
self.save_button = QtWidgets.QPushButton(alert_dialog)
|
||||
self.save_button.setEnabled(False)
|
||||
self.save_button.setIcon(build_icon(':/general/general_save.png'))
|
||||
self.save_button.setIcon(UiIcons().save)
|
||||
self.save_button.setObjectName('save_button')
|
||||
self.manage_button_layout.addWidget(self.save_button)
|
||||
self.delete_button = create_button(alert_dialog, 'delete_button', role='delete', enabled=False,
|
||||
|
@ -77,9 +77,8 @@ class Ui_AlertDialog(object):
|
|||
self.manage_button_layout.addWidget(self.delete_button)
|
||||
self.manage_button_layout.addStretch()
|
||||
self.alert_dialog_layout.addLayout(self.manage_button_layout, 1, 1)
|
||||
display_icon = build_icon(':/general/general_live.png')
|
||||
self.display_button = create_button(alert_dialog, 'display_button', icon=display_icon, enabled=False)
|
||||
self.display_close_button = create_button(alert_dialog, 'display_close_button', icon=display_icon,
|
||||
self.display_button = create_button(alert_dialog, 'display_button', icon=UiIcons().live, enabled=False)
|
||||
self.display_close_button = create_button(alert_dialog, 'display_close_button', icon=UiIcons().live,
|
||||
enabled=False)
|
||||
self.button_box = create_button_box(alert_dialog, 'button_box', ['close'],
|
||||
[self.display_button, self.display_close_button])
|
||||
|
|
|
@ -25,6 +25,7 @@ import logging
|
|||
from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common.actions import ActionList
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.plugins.bibles.endpoint import api_bibles_endpoint, bibles_endpoint
|
||||
|
@ -74,8 +75,8 @@ class BiblePlugin(Plugin):
|
|||
def __init__(self):
|
||||
super(BiblePlugin, self).__init__('bibles', __default_settings__, BibleMediaItem, BiblesTab)
|
||||
self.weight = -9
|
||||
self.icon_path = ':/plugins/plugin_bibles.png'
|
||||
self.icon = build_icon(self.icon_path)
|
||||
self.icon_path = UiIcons().bible
|
||||
self.icon = UiIcons().bible
|
||||
self.manager = BibleManager(self)
|
||||
register_endpoint(bibles_endpoint)
|
||||
register_endpoint(api_bibles_endpoint)
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_BookNameDialog(object):
|
||||
def setupUi(self, book_name_dialog):
|
||||
book_name_dialog.setObjectName('book_name_dialog')
|
||||
book_name_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
book_name_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
book_name_dialog.resize(400, 271)
|
||||
self.book_name_layout = QtWidgets.QVBoxLayout(book_name_dialog)
|
||||
self.book_name_layout.setSpacing(8)
|
||||
|
|
|
@ -23,16 +23,16 @@
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.plugins.bibles.lib import LanguageSelection, BibleStrings
|
||||
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_EditBibleDialog(object):
|
||||
def setupUi(self, edit_bible_dialog):
|
||||
edit_bible_dialog.setObjectName('edit_bible_dialog')
|
||||
edit_bible_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
edit_bible_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
edit_bible_dialog.resize(520, 400)
|
||||
edit_bible_dialog.setModal(True)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(edit_bible_dialog)
|
||||
|
|
|
@ -183,7 +183,7 @@ class EditBibleForm(QtWidgets.QDialog, Ui_EditBibleDialog, RegistryProperties):
|
|||
"""
|
||||
Validate a book.
|
||||
"""
|
||||
book_regex = re.compile('[\d]*[^\d]+$')
|
||||
book_regex = re.compile(r'[\d]*[^\d]+$')
|
||||
if not new_book_name:
|
||||
self.book_name_edit[abbreviation].setFocus()
|
||||
critical_error_message_box(
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_LanguageDialog(object):
|
||||
def setupUi(self, language_dialog):
|
||||
language_dialog.setObjectName('language_dialog')
|
||||
language_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
language_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
language_dialog.resize(400, 165)
|
||||
self.language_layout = QtWidgets.QVBoxLayout(language_dialog)
|
||||
self.language_layout.setSpacing(8)
|
||||
|
|
|
@ -217,7 +217,7 @@ def update_reference_separators():
|
|||
# add various Unicode alternatives
|
||||
source_string = source_string.replace('-', '(?:[-\u00AD\u2010\u2011\u2012\u2014\u2014\u2212\uFE63\uFF0D])')
|
||||
source_string = source_string.replace(',', '(?:[,\u201A])')
|
||||
REFERENCE_SEPARATORS['sep_{role}'.format(role=role)] = '\s*(?:{source})\s*'.format(source=source_string)
|
||||
REFERENCE_SEPARATORS['sep_{role}'.format(role=role)] = r'\s*(?:{source})\s*'.format(source=source_string)
|
||||
REFERENCE_SEPARATORS['sep_{role}_default'.format(role=role)] = default_separators[index]
|
||||
# verse range match: (<chapter>:)?<verse>(-((<chapter>:)?<verse>|end)?)?
|
||||
range_regex = '(?:(?P<from_chapter>[0-9]+){sep_v})?' \
|
||||
|
@ -255,7 +255,7 @@ def get_reference_match(match_type):
|
|||
|
||||
|
||||
def parse_reference(reference, bible, language_selection, book_ref_id=False):
|
||||
"""
|
||||
r"""
|
||||
This is the next generation über-awesome function that takes a person's typed in string and converts it to a list
|
||||
of references to be queried from the Bible database files.
|
||||
|
||||
|
|
|
@ -31,7 +31,8 @@ from openlp.core.common.registry import Registry
|
|||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext
|
||||
from openlp.core.lib.ui import set_case_insensitive_completer, create_horizontal_adjusting_combo_box, \
|
||||
critical_error_message_box, find_and_set_in_combo_box, build_icon
|
||||
critical_error_message_box, find_and_set_in_combo_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.edits import SearchEdit
|
||||
from openlp.plugins.bibles.forms.bibleimportform import BibleImportForm
|
||||
from openlp.plugins.bibles.forms.editbibleform import EditBibleForm
|
||||
|
@ -41,7 +42,7 @@ from openlp.plugins.bibles.lib import DisplayStyle, LayoutStyle, VerseReferenceL
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
VALID_TEXT_SEARCH = re.compile('\w\w\w')
|
||||
VALID_TEXT_SEARCH = re.compile(r'\w\w\w')
|
||||
|
||||
|
||||
def get_reference_separators():
|
||||
|
@ -104,9 +105,9 @@ class BibleMediaItem(MediaManagerItem):
|
|||
:param args: Positional arguments to pass to the super method. (tuple)
|
||||
:param kwargs: Keyword arguments to pass to the super method. (dict)
|
||||
"""
|
||||
self.clear_icon = build_icon(':/bibles/bibles_search_clear.png')
|
||||
self.save_results_icon = build_icon(':/bibles/bibles_save_results.png')
|
||||
self.sort_icon = build_icon(':/bibles/bibles_book_sort.png')
|
||||
self.clear_icon = UiIcons().square
|
||||
self.save_results_icon = UiIcons.save
|
||||
self.sort_icon = UiIcons().sort
|
||||
self.bible = None
|
||||
self.second_bible = None
|
||||
self.saved_results = []
|
||||
|
@ -314,13 +315,13 @@ class BibleMediaItem(MediaManagerItem):
|
|||
self.plugin.manager.media = self
|
||||
self.populate_bible_combo_boxes()
|
||||
self.search_edit.set_search_types([
|
||||
(BibleSearch.Combined, ':/bibles/bibles_search_combined.png',
|
||||
(BibleSearch.Combined, UiIcons().search_comb,
|
||||
translate('BiblesPlugin.MediaItem', 'Text or Reference'),
|
||||
translate('BiblesPlugin.MediaItem', 'Text or Reference...')),
|
||||
(BibleSearch.Reference, ':/bibles/bibles_search_reference.png',
|
||||
(BibleSearch.Reference, UiIcons().search_ref,
|
||||
translate('BiblesPlugin.MediaItem', 'Scripture Reference'),
|
||||
translate('BiblesPlugin.MediaItem', 'Search Scripture Reference...')),
|
||||
(BibleSearch.Text, ':/bibles/bibles_search_text.png',
|
||||
(BibleSearch.Text, UiIcons().text,
|
||||
translate('BiblesPlugin.MediaItem', 'Text Search'),
|
||||
translate('BiblesPlugin.MediaItem', 'Search Text...'))
|
||||
])
|
||||
|
|
|
@ -28,6 +28,7 @@ import logging
|
|||
|
||||
from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon
|
||||
from openlp.core.lib.db import Manager
|
||||
from openlp.plugins.custom.endpoint import api_custom_endpoint, custom_endpoint
|
||||
|
@ -62,7 +63,7 @@ class CustomPlugin(Plugin):
|
|||
super(CustomPlugin, self).__init__('custom', __default_settings__, CustomMediaItem, CustomTab)
|
||||
self.weight = -5
|
||||
self.db_manager = Manager('custom', init_schema)
|
||||
self.icon_path = ':/plugins/plugin_custom.png'
|
||||
self.icon_path = UiIcons().clone
|
||||
self.icon = build_icon(self.icon_path)
|
||||
register_endpoint(custom_endpoint)
|
||||
register_endpoint(api_custom_endpoint)
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box, create_button
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_CustomEditDialog(object):
|
||||
|
@ -33,7 +33,7 @@ class Ui_CustomEditDialog(object):
|
|||
:param custom_edit_dialog: The Dialog
|
||||
"""
|
||||
custom_edit_dialog.setObjectName('custom_edit_dialog')
|
||||
custom_edit_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
custom_edit_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
custom_edit_dialog.resize(450, 350)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(custom_edit_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -23,23 +23,22 @@
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button, create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.edits import SpellTextEdit
|
||||
|
||||
|
||||
class Ui_CustomSlideEditDialog(object):
|
||||
def setupUi(self, custom_slide_edit_dialog):
|
||||
custom_slide_edit_dialog.setObjectName('custom_slide_edit_dialog')
|
||||
custom_slide_edit_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
custom_slide_edit_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
custom_slide_edit_dialog.resize(350, 300)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(custom_slide_edit_dialog)
|
||||
self.slide_text_edit = SpellTextEdit(self)
|
||||
self.slide_text_edit.setObjectName('slide_text_edit')
|
||||
self.dialog_layout.addWidget(self.slide_text_edit)
|
||||
self.split_button = create_button(custom_slide_edit_dialog, 'splitButton', icon=':/general/general_add.png')
|
||||
self.insert_button = create_button(custom_slide_edit_dialog, 'insertButton',
|
||||
icon=':/general/general_add.png')
|
||||
self.split_button = create_button(custom_slide_edit_dialog, 'splitButton', icon=UiIcons().add)
|
||||
self.insert_button = create_button(custom_slide_edit_dialog, 'insertButton', icon=UiIcons().add)
|
||||
self.button_box = create_button_box(custom_slide_edit_dialog, 'button_box', ['cancel', 'save'],
|
||||
[self.split_button, self.insert_button])
|
||||
self.dialog_layout.addWidget(self.button_box)
|
||||
|
|
|
@ -31,6 +31,7 @@ from openlp.core.common.settings import Settings
|
|||
from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext, PluginStatus, \
|
||||
check_item_selected
|
||||
from openlp.core.lib.ui import create_widget_action
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.plugins.custom.forms.editcustomform import EditCustomForm
|
||||
from openlp.plugins.custom.lib import CustomXMLParser, CustomXMLBuilder
|
||||
from openlp.plugins.custom.lib.db import CustomSlide
|
||||
|
@ -88,7 +89,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||
def add_custom_context_actions(self):
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
create_widget_action(
|
||||
self.list_view, text=translate('OpenLP.MediaManagerItem', '&Clone'), icon=':/general/general_clone.png',
|
||||
self.list_view, text=translate('OpenLP.MediaManagerItem', '&Clone'), icon=UiIcons().clone,
|
||||
triggers=self.on_clone_click)
|
||||
|
||||
def config_update(self):
|
||||
|
@ -111,9 +112,9 @@ class CustomMediaItem(MediaManagerItem):
|
|||
Initialise the UI so it can provide Searches
|
||||
"""
|
||||
self.search_text_edit.set_search_types(
|
||||
[(CustomSearch.Titles, ':/songs/song_search_title.png', translate('SongsPlugin.MediaItem', 'Titles'),
|
||||
[(CustomSearch.Titles, UiIcons().search, translate('SongsPlugin.MediaItem', 'Titles'),
|
||||
translate('SongsPlugin.MediaItem', 'Search Titles...')),
|
||||
(CustomSearch.Themes, ':/slides/slide_theme.png', UiStrings().Themes, UiStrings().SearchThemes)])
|
||||
(CustomSearch.Themes, UiIcons().theme, UiStrings().Themes, UiStrings().SearchThemes)])
|
||||
self.load_list(self.plugin.db_manager.get_all_objects(CustomSlide, order_by_ref=CustomSlide.title))
|
||||
self.config_update()
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ from PyQt5 import QtGui
|
|||
|
||||
from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import Plugin, StringContent, ImageSource, build_icon
|
||||
from openlp.core.lib.db import Manager
|
||||
|
@ -53,7 +54,7 @@ class ImagePlugin(Plugin):
|
|||
super(ImagePlugin, self).__init__('images', __default_settings__, ImageMediaItem, ImageTab)
|
||||
self.manager = Manager('images', init_schema, upgrade_mod=upgrade)
|
||||
self.weight = -7
|
||||
self.icon_path = ':/plugins/plugin_images.png'
|
||||
self.icon_path = UiIcons().picture
|
||||
self.icon = build_icon(self.icon_path)
|
||||
register_endpoint(images_endpoint)
|
||||
register_endpoint(api_images_endpoint)
|
||||
|
|
|
@ -33,6 +33,7 @@ from openlp.core.common.settings import Settings
|
|||
from openlp.core.lib import ItemCapabilities, MediaManagerItem, ServiceItemContext, StringContent, build_icon, \
|
||||
check_item_selected, create_thumb, validate_thumb
|
||||
from openlp.core.lib.ui import create_widget_action, critical_error_message_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.views import TreeWidgetWithDnD
|
||||
from openlp.plugins.images.forms import AddGroupForm, ChooseGroupForm
|
||||
from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups
|
||||
|
@ -127,21 +128,21 @@ class ImageMediaItem(MediaManagerItem):
|
|||
create_widget_action(
|
||||
self.list_view,
|
||||
text=self.plugin.get_string(StringContent.Edit)['title'],
|
||||
icon=':/general/general_edit.png',
|
||||
icon=UiIcons().edit,
|
||||
triggers=self.on_edit_click)
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
create_widget_action(
|
||||
self.list_view,
|
||||
'listView{name}{preview}Item'.format(name=self.plugin.name.title(), preview=StringContent.Preview.title()),
|
||||
text=self.plugin.get_string(StringContent.Preview)['title'],
|
||||
icon=':/general/general_preview.png',
|
||||
icon=UiIcons().preview,
|
||||
can_shortcuts=True,
|
||||
triggers=self.on_preview_click)
|
||||
create_widget_action(
|
||||
self.list_view,
|
||||
'listView{name}{live}Item'.format(name=self.plugin.name.title(), live=StringContent.Live.title()),
|
||||
text=self.plugin.get_string(StringContent.Live)['title'],
|
||||
icon=':/general/general_live.png',
|
||||
icon=UiIcons().live,
|
||||
can_shortcuts=True,
|
||||
triggers=self.on_live_click)
|
||||
create_widget_action(
|
||||
|
@ -149,14 +150,14 @@ class ImageMediaItem(MediaManagerItem):
|
|||
'listView{name}{service}Item'.format(name=self.plugin.name.title(), service=StringContent.Service.title()),
|
||||
can_shortcuts=True,
|
||||
text=self.plugin.get_string(StringContent.Service)['title'],
|
||||
icon=':/general/general_add.png',
|
||||
icon=UiIcons().add,
|
||||
triggers=self.on_add_click)
|
||||
if self.add_to_service_item:
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
create_widget_action(
|
||||
self.list_view,
|
||||
text=translate('OpenLP.MediaManagerItem', '&Add to selected Service Item'),
|
||||
icon=':/general/general_add.png',
|
||||
icon=UiIcons().add,
|
||||
triggers=self.on_add_edit_click)
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
if self.has_delete_icon:
|
||||
|
@ -164,7 +165,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
self.list_view,
|
||||
'listView{name}{delete}Item'.format(name=self.plugin.name.title(), delete=StringContent.Delete.title()),
|
||||
text=self.plugin.get_string(StringContent.Delete)['title'],
|
||||
icon=':/general/general_delete.png',
|
||||
icon=UiIcons().delete,
|
||||
can_shortcuts=True, triggers=self.on_delete_click)
|
||||
self.add_custom_context_actions()
|
||||
# Create the context menu and add all actions from the list_view.
|
||||
|
@ -182,17 +183,16 @@ class ImageMediaItem(MediaManagerItem):
|
|||
create_widget_action(self.list_view, separator=True)
|
||||
create_widget_action(
|
||||
self.list_view,
|
||||
text=UiStrings().AddGroup, icon=':/images/image_new_group.png', triggers=self.on_add_group_click)
|
||||
text=UiStrings().AddGroup, icon=UiIcons().group, triggers=self.on_add_group_click)
|
||||
create_widget_action(
|
||||
self.list_view,
|
||||
text=translate('ImagePlugin', 'Add new image(s)'),
|
||||
icon=':/general/general_open.png', triggers=self.on_file_click)
|
||||
icon=UiIcons().open, triggers=self.on_file_click)
|
||||
create_widget_action(self.list_view, separator=True)
|
||||
self.replace_action_context = create_widget_action(
|
||||
self.list_view, text=UiStrings().ReplaceBG, icon=':/slides/slide_theme.png',
|
||||
triggers=self.on_replace_click)
|
||||
self.list_view, text=UiStrings().ReplaceBG, icon=UiIcons().theme, triggers=self.on_replace_click)
|
||||
self.reset_action_context = create_widget_action(
|
||||
self.list_view, text=UiStrings().ReplaceLiveBG, icon=':/system/system_close.png',
|
||||
self.list_view, text=UiStrings().ReplaceLiveBG, icon=UiIcons().close,
|
||||
visible=False, triggers=self.on_reset_click)
|
||||
|
||||
def add_start_header_bar(self):
|
||||
|
@ -200,7 +200,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
Add custom buttons to the start of the toolbar.
|
||||
"""
|
||||
self.add_group_action = self.toolbar.add_toolbar_action('add_group_action',
|
||||
icon=':/images/image_new_group.png',
|
||||
icon=UiIcons().group,
|
||||
triggers=self.on_add_group_click)
|
||||
|
||||
def add_end_header_bar(self):
|
||||
|
@ -208,10 +208,10 @@ class ImageMediaItem(MediaManagerItem):
|
|||
Add custom buttons to the end of the toolbar
|
||||
"""
|
||||
self.replace_action = self.toolbar.add_toolbar_action('replace_action',
|
||||
icon=':/slides/slide_theme.png',
|
||||
icon=UiIcons().theme,
|
||||
triggers=self.on_replace_click)
|
||||
self.reset_action = self.toolbar.add_toolbar_action('reset_action',
|
||||
icon=':/system/system_close.png',
|
||||
icon=UiIcons().close,
|
||||
visible=False, triggers=self.on_reset_click)
|
||||
|
||||
def recursively_delete_group(self, image_group):
|
||||
|
@ -282,7 +282,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
"""
|
||||
image_groups = self.manager.get_all_objects(ImageGroups, ImageGroups.parent_id == parent_group_id)
|
||||
image_groups.sort(key=lambda group_object: get_natural_key(group_object.group_name))
|
||||
folder_icon = build_icon(':/images/image_group.png')
|
||||
folder_icon = UiIcons().group
|
||||
for image_group in image_groups:
|
||||
group = QtWidgets.QTreeWidgetItem()
|
||||
group.setText(0, image_group.group_name)
|
||||
|
@ -371,7 +371,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||
file_name = image.file_path.name
|
||||
thumbnail_path = self.generate_thumbnail_path(image)
|
||||
if not image.file_path.exists():
|
||||
icon = build_icon(':/general/general_delete.png')
|
||||
icon = UiIcons().delete
|
||||
else:
|
||||
if validate_thumb(image.file_path, thumbnail_path):
|
||||
icon = build_icon(thumbnail_path)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_MediaClipSelector(object):
|
||||
|
@ -106,7 +106,7 @@ class Ui_MediaClipSelector(object):
|
|||
self.controls_layout = QtWidgets.QHBoxLayout()
|
||||
self.controls_layout.setObjectName('controls_layout')
|
||||
self.play_button = QtWidgets.QToolButton(media_clip_selector)
|
||||
self.play_button.setIcon(build_icon(':/slides/media_playback_start.png'))
|
||||
self.play_button.setIcon(UiIcons().play)
|
||||
self.play_button.setObjectName('play_button')
|
||||
self.controls_layout.addWidget(self.play_button)
|
||||
self.position_slider = QtWidgets.QSlider(media_clip_selector)
|
||||
|
|
|
@ -25,13 +25,14 @@ import re
|
|||
from datetime import datetime
|
||||
from time import sleep
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common import is_win, is_linux, is_macosx
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
from openlp.core.common.path import Path
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.ui.media.vlcplayer import get_vlc
|
||||
from openlp.plugins.media.forms.mediaclipselectordialog import Ui_MediaClipSelector
|
||||
|
||||
|
@ -66,12 +67,8 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
self.media_item = media_item
|
||||
self.setupUi(self)
|
||||
# setup play/pause icon
|
||||
self.play_icon = QtGui.QIcon()
|
||||
self.play_icon.addPixmap(QtGui.QPixmap(":/slides/media_playback_start.png"), QtGui.QIcon.Normal,
|
||||
QtGui.QIcon.Off)
|
||||
self.pause_icon = QtGui.QIcon()
|
||||
self.pause_icon.addPixmap(QtGui.QPixmap(":/slides/media_playback_pause.png"), QtGui.QIcon.Normal,
|
||||
QtGui.QIcon.Off)
|
||||
self.play_icon = UiIcons().play
|
||||
self.pause_icon = UiIcons().pause
|
||||
|
||||
def reject(self):
|
||||
"""
|
||||
|
@ -210,7 +207,7 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
|
|||
# detect if we're dealing with a DVD or CD, so we use different loading approaches depending on the OS.
|
||||
if is_win():
|
||||
# If the given path is in the format "D:\" or "D:", prefix it with "/" to make VLC happy
|
||||
pattern = re.compile('^\w:\\\\*$')
|
||||
pattern = re.compile(r'^\w:\\\\*$')
|
||||
if pattern.match(path):
|
||||
path = '/' + path
|
||||
self.vlc_media = self.vlc_instance.media_new_location('dvd://' + path)
|
||||
|
|
|
@ -32,9 +32,10 @@ from openlp.core.common.path import Path, path_to_str, create_paths
|
|||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import ItemCapabilities, MediaManagerItem, MediaType, ServiceItem, ServiceItemContext, \
|
||||
build_icon, check_item_selected
|
||||
check_item_selected
|
||||
from openlp.core.lib.ui import create_widget_action, critical_error_message_box, create_horizontal_adjusting_combo_box
|
||||
from openlp.core.ui import DisplayControllerType
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.ui.media import get_media_players, set_media_players, parse_optical_path, format_milliseconds
|
||||
from openlp.core.ui.media.vlcplayer import get_vlc
|
||||
|
||||
|
@ -45,7 +46,7 @@ if get_vlc() is not None:
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
CLAPPERBOARD = ':/media/slidecontroller_multimedia.png'
|
||||
CLAPPERBOARD = UiIcons().clapperboard
|
||||
|
||||
|
||||
class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
|
@ -67,10 +68,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
self.icon_path = 'images/image'
|
||||
self.background = False
|
||||
self.automatic = ''
|
||||
self.optical_icon = build_icon(':/media/media_optical.png')
|
||||
self.video_icon = build_icon(':/media/media_video.png')
|
||||
self.audio_icon = build_icon(':/media/media_audio.png')
|
||||
self.error_icon = build_icon(':/general/general_delete.png')
|
||||
self.error_icon = UiIcons().delete
|
||||
|
||||
def setup_item(self):
|
||||
"""
|
||||
|
@ -137,7 +135,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
|
||||
optical_button_tooltip = translate('MediaPlugin.MediaItem',
|
||||
'CD/DVD playback is only supported if VLC is installed and enabled.')
|
||||
self.load_optical = self.toolbar.add_toolbar_action('load_optical', icon=self.optical_icon,
|
||||
self.load_optical = self.toolbar.add_toolbar_action('load_optical', icon=UiIcons().optical,
|
||||
text=optical_button_text,
|
||||
tooltip=optical_button_tooltip,
|
||||
triggers=self.on_load_optical)
|
||||
|
@ -149,13 +147,13 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
Adds buttons to the end of the header bar.
|
||||
"""
|
||||
# Replace backgrounds do not work at present so remove functionality.
|
||||
self.replace_action = self.toolbar.add_toolbar_action('replace_action', icon=':/slides/slide_theme.png',
|
||||
self.replace_action = self.toolbar.add_toolbar_action('replace_action', icon=UiIcons().theme,
|
||||
triggers=self.on_replace_click)
|
||||
if 'webkit' not in get_media_players()[0]:
|
||||
self.replace_action.setDisabled(True)
|
||||
if hasattr(self, 'replace_action_context'):
|
||||
self.replace_action_context.setDisabled(True)
|
||||
self.reset_action = self.toolbar.add_toolbar_action('reset_action', icon=':/system/system_close.png',
|
||||
self.reset_action = self.toolbar.add_toolbar_action('reset_action', icon=UiIcons().close,
|
||||
visible=False, triggers=self.on_reset_click)
|
||||
self.media_widget = QtWidgets.QWidget(self)
|
||||
self.media_widget.setObjectName('media_widget')
|
||||
|
@ -179,7 +177,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
self.list_view, text=UiStrings().ReplaceBG, icon=':/slides/slide_theme.png',
|
||||
triggers=self.on_replace_click)
|
||||
self.reset_action_context = create_widget_action(
|
||||
self.list_view, text=UiStrings().ReplaceLiveBG, icon=':/system/system_close.png',
|
||||
self.list_view, text=UiStrings().ReplaceLiveBG, icon=UiIcons().close,
|
||||
visible=False, triggers=self.on_reset_click)
|
||||
|
||||
@staticmethod
|
||||
|
@ -205,7 +203,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
|
||||
def video_background_replaced(self):
|
||||
"""
|
||||
Triggered by main display on change of serviceitem.
|
||||
Triggered by main display on change of service item.
|
||||
"""
|
||||
self.reset_action.setVisible(False)
|
||||
self.reset_action_context.setVisible(False)
|
||||
|
@ -369,7 +367,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
# Handle optical based item
|
||||
(file_name, title, audio_track, subtitle_track, start, end, clip_name) = parse_optical_path(track)
|
||||
item_name = QtWidgets.QListWidgetItem(clip_name)
|
||||
item_name.setIcon(self.optical_icon)
|
||||
item_name.setIcon(UiIcons().optical)
|
||||
item_name.setData(QtCore.Qt.UserRole, track)
|
||||
item_name.setToolTip('{name}@{start}-{end}'.format(name=file_name,
|
||||
start=format_milliseconds(start),
|
||||
|
@ -378,7 +376,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
# File doesn't exist, mark as error.
|
||||
file_name = os.path.split(str(track))[1]
|
||||
item_name = QtWidgets.QListWidgetItem(file_name)
|
||||
item_name.setIcon(self.error_icon)
|
||||
item_name.setIcon(UiIcons().error)
|
||||
item_name.setData(QtCore.Qt.UserRole, track)
|
||||
item_name.setToolTip(track)
|
||||
elif track_info.isFile():
|
||||
|
@ -387,9 +385,9 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
|||
item_name = QtWidgets.QListWidgetItem(file_name)
|
||||
search = file_name.split('.')[-1].lower()
|
||||
if '*.{text}'.format(text=search) in self.media_controller.audio_extensions_list:
|
||||
item_name.setIcon(self.audio_icon)
|
||||
item_name.setIcon(UiIcons().audio)
|
||||
else:
|
||||
item_name.setIcon(self.video_icon)
|
||||
item_name.setIcon(UiIcons().video)
|
||||
item_name.setData(QtCore.Qt.UserRole, track)
|
||||
item_name.setToolTip(track)
|
||||
if item_name:
|
||||
|
|
|
@ -31,6 +31,7 @@ from openlp.core.api.http import register_endpoint
|
|||
from openlp.core.common import check_binary_exists
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.path import Path
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon
|
||||
from openlp.plugins.media.endpoint import api_media_endpoint, media_endpoint
|
||||
|
@ -56,7 +57,7 @@ class MediaPlugin(Plugin):
|
|||
def __init__(self):
|
||||
super(MediaPlugin, self).__init__('media', __default_settings__, MediaMediaItem)
|
||||
self.weight = -6
|
||||
self.icon_path = ':/plugins/plugin_media.png'
|
||||
self.icon_path = UiIcons().video
|
||||
self.icon = build_icon(self.icon_path)
|
||||
# passed with drag and drop messages
|
||||
self.dnd_id = 'Media'
|
||||
|
|
|
@ -30,15 +30,13 @@ from openlp.core.common.settings import Settings
|
|||
from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext, \
|
||||
build_icon, check_item_selected, create_thumb, validate_thumb
|
||||
from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.plugins.presentations.lib import MessageListener
|
||||
from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
ERROR_IMAGE = QtGui.QImage(':/general/general_delete.png')
|
||||
|
||||
|
||||
class PresentationMediaItem(MediaManagerItem):
|
||||
"""
|
||||
This is the Presentation media manager item for Presentation Items. It can present files using Openoffice and
|
||||
|
@ -174,7 +172,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
file_name = file_path.name
|
||||
if not file_path.exists():
|
||||
item_name = QtWidgets.QListWidgetItem(file_name)
|
||||
item_name.setIcon(build_icon(ERROR_IMAGE))
|
||||
item_name.setIcon(UiIcons().delete)
|
||||
item_name.setData(QtCore.Qt.UserRole, path_to_str(file_path))
|
||||
item_name.setToolTip(str(file_path))
|
||||
self.list_view.addItem(item_name)
|
||||
|
@ -196,7 +194,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
preview_path = doc.get_thumbnail_path(1, True)
|
||||
doc.close_presentation()
|
||||
if not (preview_path and preview_path.exists()):
|
||||
icon = build_icon(':/general/general_delete.png')
|
||||
icon = UiIcons().delete
|
||||
else:
|
||||
if validate_thumb(preview_path, thumbnail_path):
|
||||
icon = build_icon(thumbnail_path)
|
||||
|
@ -204,7 +202,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||
icon = create_thumb(preview_path, thumbnail_path)
|
||||
else:
|
||||
if initial_load:
|
||||
icon = build_icon(':/general/general_delete.png')
|
||||
icon = UiIcons().delete
|
||||
else:
|
||||
critical_error_message_box(UiStrings().UnsupportedFile,
|
||||
translate('PresentationPlugin.MediaItem',
|
||||
|
|
|
@ -347,7 +347,7 @@ class MessageListener(object):
|
|||
# Some of the original serviceitem attributes is needed in the new serviceitem
|
||||
item.footer = item_cpy.footer
|
||||
item.from_service = item_cpy.from_service
|
||||
item.iconic_representation = item_cpy.iconic_representation
|
||||
item.iconic_representation = item_cpy.icon
|
||||
item.image_border = item_cpy.image_border
|
||||
item.main = item_cpy.main
|
||||
item.theme_data = item_cpy.theme_data
|
||||
|
|
|
@ -31,6 +31,7 @@ from PyQt5 import QtCore
|
|||
from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common import extension_loader
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import Plugin, StringContent, build_icon
|
||||
from openlp.plugins.presentations.endpoint import api_presentations_endpoint, presentations_endpoint
|
||||
|
@ -68,7 +69,7 @@ class PresentationPlugin(Plugin):
|
|||
self.controllers = {}
|
||||
Plugin.__init__(self, 'presentations', __default_settings__, __default_settings__)
|
||||
self.weight = -8
|
||||
self.icon_path = ':/plugins/plugin_presentations.png'
|
||||
self.icon_path = UiIcons().presentation
|
||||
self.icon = build_icon(self.icon_path)
|
||||
register_endpoint(presentations_endpoint)
|
||||
register_endpoint(api_presentations_endpoint)
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_AuthorsDialog(object):
|
||||
|
@ -37,7 +37,7 @@ class Ui_AuthorsDialog(object):
|
|||
Set up the UI for the dialog.
|
||||
"""
|
||||
authors_dialog.setObjectName('authors_dialog')
|
||||
authors_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
authors_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
authors_dialog.resize(300, 10)
|
||||
authors_dialog.setModal(True)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(authors_dialog)
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box, create_button
|
||||
from openlp.core.ui import SingleColumnTableWidget
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.plugins.songs.lib.ui import SongStrings
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@ class Ui_EditSongDialog(object):
|
|||
"""
|
||||
def setupUi(self, edit_song_dialog):
|
||||
edit_song_dialog.setObjectName('edit_song_dialog')
|
||||
edit_song_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
edit_song_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
edit_song_dialog.resize(900, 600)
|
||||
edit_song_dialog.setModal(True)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(edit_song_dialog)
|
||||
|
|
|
@ -105,7 +105,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
self.topics_list_view.setSortingEnabled(False)
|
||||
self.topics_list_view.setAlternatingRowColors(True)
|
||||
self.audio_list_widget.setAlternatingRowColors(True)
|
||||
self.find_verse_split = re.compile('---\[\]---\n')
|
||||
self.find_verse_split = re.compile(r'---\[\]---\n')
|
||||
self.whitespace = re.compile(r'\W+')
|
||||
self.find_tags = re.compile(r'\{/?\w+\}')
|
||||
|
||||
|
@ -316,7 +316,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
|||
multiple.append(verse_tag)
|
||||
self.song.lyrics = str(sxml.extract_xml(), 'utf-8')
|
||||
for verse in multiple:
|
||||
self.song.verse_order = re.sub('([' + verse.upper() + verse.lower() + '])(\W|$)',
|
||||
self.song.verse_order = re.sub(r'([' + verse.upper() + verse.lower() + r'])(\W|$)',
|
||||
r'\g<1>1\2', self.song.verse_order)
|
||||
except:
|
||||
log.exception('Problem processing song Lyrics \n{xml}'.format(xml=sxml.dump_xml()))
|
||||
|
|
|
@ -24,8 +24,8 @@ from PyQt5 import QtWidgets
|
|||
|
||||
from openlp.core.common.i18n import UiStrings, translate
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.edits import SpellTextEdit
|
||||
from openlp.plugins.songs.lib import VerseType
|
||||
|
||||
|
@ -33,7 +33,7 @@ from openlp.plugins.songs.lib import VerseType
|
|||
class Ui_EditVerseDialog(object):
|
||||
def setupUi(self, edit_verse_dialog):
|
||||
edit_verse_dialog.setObjectName('edit_verse_dialog')
|
||||
edit_verse_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
edit_verse_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
edit_verse_dialog.resize(400, 400)
|
||||
edit_verse_dialog.setModal(True)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(edit_verse_dialog)
|
||||
|
@ -44,11 +44,11 @@ class Ui_EditVerseDialog(object):
|
|||
self.verse_type_layout = QtWidgets.QHBoxLayout()
|
||||
self.verse_type_layout.setObjectName('verse_type_layout')
|
||||
self.forced_split_button = QtWidgets.QPushButton(edit_verse_dialog)
|
||||
self.forced_split_button.setIcon(build_icon(':/general/general_add.png'))
|
||||
self.forced_split_button.setIcon(UiIcons().add)
|
||||
self.forced_split_button.setObjectName('forced_split_button')
|
||||
self.verse_type_layout.addWidget(self.forced_split_button)
|
||||
self.overflow_split_button = QtWidgets.QPushButton(edit_verse_dialog)
|
||||
self.overflow_split_button.setIcon(build_icon(':/general/general_add.png'))
|
||||
self.overflow_split_button.setIcon(UiIcons().add)
|
||||
self.overflow_split_button.setObjectName('overflow_split_button')
|
||||
self.verse_type_layout.addWidget(self.overflow_split_button)
|
||||
self.verse_type_label = QtWidgets.QLabel(edit_verse_dialog)
|
||||
|
@ -64,7 +64,7 @@ class Ui_EditVerseDialog(object):
|
|||
self.verse_number_box.setObjectName('verse_number_box')
|
||||
self.verse_type_layout.addWidget(self.verse_number_box)
|
||||
self.insert_button = QtWidgets.QPushButton(edit_verse_dialog)
|
||||
self.insert_button.setIcon(build_icon(':/general/general_add.png'))
|
||||
self.insert_button.setIcon(UiIcons().add)
|
||||
self.insert_button.setObjectName('insert_button')
|
||||
self.verse_type_layout.addWidget(self.insert_button)
|
||||
self.verse_type_layout.addStretch()
|
||||
|
@ -76,11 +76,11 @@ class Ui_EditVerseDialog(object):
|
|||
self.transpose_label.setObjectName('transpose_label')
|
||||
self.transpose_layout.addWidget(self.transpose_label)
|
||||
self.transpose_up_button = QtWidgets.QPushButton(edit_verse_dialog)
|
||||
self.transpose_up_button.setIcon(build_icon(':/services/service_up.png'))
|
||||
self.transpose_up_button.setIcon(UiIcons().arrow_up)
|
||||
self.transpose_up_button.setObjectName('transpose_up')
|
||||
self.transpose_layout.addWidget(self.transpose_up_button)
|
||||
self.transpose_down_button = QtWidgets.QPushButton(edit_verse_dialog)
|
||||
self.transpose_down_button.setIcon(build_icon(':/services/service_down.png'))
|
||||
self.transpose_down_button.setIcon(UiIcons().arrow_down)
|
||||
self.transpose_down_button.setObjectName('transpose_down')
|
||||
self.transpose_layout.addWidget(self.transpose_down_button)
|
||||
self.dialog_layout.addLayout(self.transpose_layout)
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_MediaFilesDialog(object):
|
||||
|
@ -36,7 +36,7 @@ class Ui_MediaFilesDialog(object):
|
|||
Set up the user interface.
|
||||
"""
|
||||
media_files_dialog.setObjectName('media_files_dialog')
|
||||
media_files_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
media_files_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
media_files_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
media_files_dialog.resize(400, 300)
|
||||
media_files_dialog.setModal(True)
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_SongBookDialog(object):
|
||||
|
@ -36,7 +36,7 @@ class Ui_SongBookDialog(object):
|
|||
Set up the user interface.
|
||||
"""
|
||||
song_book_dialog.setObjectName('song_book_dialog')
|
||||
song_book_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
song_book_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
song_book_dialog.resize(300, 10)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(song_book_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import UiStrings
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.plugins.songs.lib.ui import SongStrings
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@ class Ui_SongMaintenanceDialog(object):
|
|||
Set up the user interface for the song maintenance dialog
|
||||
"""
|
||||
song_maintenance_dialog.setObjectName('song_maintenance_dialog')
|
||||
song_maintenance_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
song_maintenance_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
song_maintenance_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
song_maintenance_dialog.resize(600, 600)
|
||||
self.dialog_layout = QtWidgets.QGridLayout(song_maintenance_dialog)
|
||||
|
@ -47,11 +47,11 @@ class Ui_SongMaintenanceDialog(object):
|
|||
self.type_list_widget.setUniformItemSizes(True)
|
||||
self.type_list_widget.setObjectName('type_list_widget')
|
||||
self.authors_list_item = QtWidgets.QListWidgetItem(self.type_list_widget)
|
||||
self.authors_list_item.setIcon(build_icon(':/songs/author_maintenance.png'))
|
||||
self.authors_list_item.setIcon(UiIcons().usermo)
|
||||
self.topics_list_item = QtWidgets.QListWidgetItem(self.type_list_widget)
|
||||
self.topics_list_item.setIcon(build_icon(':/songs/topic_maintenance.png'))
|
||||
self.topics_list_item.setIcon(UiIcons().light_bulb)
|
||||
self.books_list_item = QtWidgets.QListWidgetItem(self.type_list_widget)
|
||||
self.books_list_item.setIcon(build_icon(':/songs/book_maintenance.png'))
|
||||
self.books_list_item.setIcon(UiIcons().book)
|
||||
self.dialog_layout.addWidget(self.type_list_widget, 0, 0)
|
||||
self.stacked_layout = QtWidgets.QStackedLayout()
|
||||
self.stacked_layout.setObjectName('stacked_layout')
|
||||
|
@ -67,15 +67,15 @@ class Ui_SongMaintenanceDialog(object):
|
|||
self.authors_buttons_layout.setObjectName('authors_buttons_layout')
|
||||
self.authors_buttons_layout.addStretch()
|
||||
self.add_author_button = QtWidgets.QPushButton(self.authors_page)
|
||||
self.add_author_button.setIcon(build_icon(':/songs/author_add.png'))
|
||||
self.add_author_button.setIcon(UiIcons().add)
|
||||
self.add_author_button.setObjectName('add_author_button')
|
||||
self.authors_buttons_layout.addWidget(self.add_author_button)
|
||||
self.edit_author_button = QtWidgets.QPushButton(self.authors_page)
|
||||
self.edit_author_button.setIcon(build_icon(':/songs/author_edit.png'))
|
||||
self.edit_author_button.setIcon(UiIcons().edit)
|
||||
self.edit_author_button.setObjectName('edit_author_button')
|
||||
self.authors_buttons_layout.addWidget(self.edit_author_button)
|
||||
self.delete_author_button = QtWidgets.QPushButton(self.authors_page)
|
||||
self.delete_author_button.setIcon(build_icon(':/songs/author_delete.png'))
|
||||
self.delete_author_button.setIcon(UiIcons().delete)
|
||||
self.delete_author_button.setObjectName('delete_author_button')
|
||||
self.authors_buttons_layout.addWidget(self.delete_author_button)
|
||||
self.authors_layout.addLayout(self.authors_buttons_layout)
|
||||
|
@ -92,15 +92,15 @@ class Ui_SongMaintenanceDialog(object):
|
|||
self.topics_buttons_layout.setObjectName('topicsButtonLayout')
|
||||
self.topics_buttons_layout.addStretch()
|
||||
self.add_topic_button = QtWidgets.QPushButton(self.topics_page)
|
||||
self.add_topic_button.setIcon(build_icon(':/songs/topic_add.png'))
|
||||
self.add_topic_button.setIcon(UiIcons().add)
|
||||
self.add_topic_button.setObjectName('add_topic_button')
|
||||
self.topics_buttons_layout.addWidget(self.add_topic_button)
|
||||
self.edit_topic_button = QtWidgets.QPushButton(self.topics_page)
|
||||
self.edit_topic_button.setIcon(build_icon(':/songs/topic_edit.png'))
|
||||
self.edit_topic_button.setIcon(UiIcons().edit)
|
||||
self.edit_topic_button.setObjectName('edit_topic_button')
|
||||
self.topics_buttons_layout.addWidget(self.edit_topic_button)
|
||||
self.delete_topic_button = QtWidgets.QPushButton(self.topics_page)
|
||||
self.delete_topic_button.setIcon(build_icon(':/songs/topic_delete.png'))
|
||||
self.delete_topic_button.setIcon(UiIcons().delete)
|
||||
self.delete_topic_button.setObjectName('delete_topic_button')
|
||||
self.topics_buttons_layout.addWidget(self.delete_topic_button)
|
||||
self.topics_layout.addLayout(self.topics_buttons_layout)
|
||||
|
@ -117,15 +117,15 @@ class Ui_SongMaintenanceDialog(object):
|
|||
self.books_buttons_layout.setObjectName('booksButtonLayout')
|
||||
self.books_buttons_layout.addStretch()
|
||||
self.add_book_button = QtWidgets.QPushButton(self.books_page)
|
||||
self.add_book_button.setIcon(build_icon(':/songs/book_add.png'))
|
||||
self.add_book_button.setIcon(UiIcons().add)
|
||||
self.add_book_button.setObjectName('add_book_button')
|
||||
self.books_buttons_layout.addWidget(self.add_book_button)
|
||||
self.edit_book_button = QtWidgets.QPushButton(self.books_page)
|
||||
self.edit_book_button.setIcon(build_icon(':/songs/book_edit.png'))
|
||||
self.edit_book_button.setIcon(UiIcons().edit)
|
||||
self.edit_book_button.setObjectName('edit_book_button')
|
||||
self.books_buttons_layout.addWidget(self.edit_book_button)
|
||||
self.delete_book_button = QtWidgets.QPushButton(self.books_page)
|
||||
self.delete_book_button.setIcon(build_icon(':/songs/book_delete.png'))
|
||||
self.delete_book_button.setIcon(UiIcons().delete)
|
||||
self.delete_book_button.setObjectName('delete_book_button')
|
||||
self.books_buttons_layout.addWidget(self.delete_book_button)
|
||||
self.books_layout.addLayout(self.books_buttons_layout)
|
||||
|
|
|
@ -24,7 +24,7 @@ A widget representing a song in the duplicate song removal wizard review page.
|
|||
"""
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.plugins.songs.lib import VerseType
|
||||
from openlp.plugins.songs.lib.openlyricsxml import SongXML
|
||||
|
||||
|
@ -182,7 +182,7 @@ class SongReviewWidget(QtWidgets.QWidget):
|
|||
self.song_vertical_layout.addWidget(self.song_group_box)
|
||||
self.song_remove_button = QtWidgets.QPushButton(self)
|
||||
self.song_remove_button.setObjectName('song_remove_button')
|
||||
self.song_remove_button.setIcon(build_icon(':/general/general_delete.png'))
|
||||
self.song_remove_button.setIcon(UiIcons().delete)
|
||||
self.song_remove_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
self.song_vertical_layout.addWidget(self.song_remove_button, alignment=QtCore.Qt.AlignHCenter)
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@ The :mod:`~openlp.plugins.songs.forms.songselectdialog` module contains the user
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.ui import SingleColumnTableWidget
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.widgets.edits import HistoryComboBox
|
||||
|
||||
|
||||
|
@ -90,7 +90,7 @@ class Ui_SongSelectDialog(object):
|
|||
self.login_progress_bar.setVisible(False)
|
||||
self.login_button_layout.addWidget(self.login_progress_bar)
|
||||
self.login_button = QtWidgets.QPushButton(self.login_page)
|
||||
self.login_button.setIcon(build_icon(':/songs/song_author_edit.png'))
|
||||
self.login_button.setIcon(UiIcons().edit)
|
||||
self.login_button.setObjectName('login_button')
|
||||
self.login_button_layout.addWidget(self.login_button)
|
||||
self.login_layout.setLayout(4, QtWidgets.QFormLayout.SpanningRole, self.login_button_layout)
|
||||
|
@ -111,7 +111,7 @@ class Ui_SongSelectDialog(object):
|
|||
self.search_combobox.setObjectName('search_combobox')
|
||||
self.search_input_layout.addWidget(self.search_combobox)
|
||||
self.search_button = QtWidgets.QPushButton(self.search_page)
|
||||
self.search_button.setIcon(build_icon(':/general/general_find.png'))
|
||||
self.search_button.setIcon(UiIcons().search)
|
||||
self.search_button.setObjectName('search_button')
|
||||
self.search_input_layout.addWidget(self.search_button)
|
||||
self.search_layout.addLayout(self.search_input_layout)
|
||||
|
@ -124,7 +124,7 @@ class Ui_SongSelectDialog(object):
|
|||
self.search_progress_bar.setValue(0)
|
||||
self.search_progress_layout.addWidget(self.search_progress_bar)
|
||||
self.stop_button = QtWidgets.QPushButton(self.search_page)
|
||||
self.stop_button.setIcon(build_icon(':/songs/song_search_stop.png'))
|
||||
self.stop_button.setIcon(UiIcons().stop)
|
||||
self.stop_button.setObjectName('stop_button')
|
||||
self.search_progress_layout.addWidget(self.stop_button)
|
||||
self.search_layout.addLayout(self.search_progress_layout)
|
||||
|
@ -143,12 +143,12 @@ class Ui_SongSelectDialog(object):
|
|||
self.view_layout.setSpacing(8)
|
||||
self.view_layout.setObjectName('view_layout')
|
||||
self.logout_button = QtWidgets.QPushButton(self.search_page)
|
||||
self.logout_button.setIcon(build_icon(':/songs/song_author_edit.png'))
|
||||
self.logout_button.setIcon(UiIcons().edit)
|
||||
self.view_layout.addWidget(self.logout_button)
|
||||
self.view_spacer = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.view_layout.addItem(self.view_spacer)
|
||||
self.view_button = QtWidgets.QPushButton(self.search_page)
|
||||
self.view_button.setIcon(build_icon(':/songs/song_search_all.png'))
|
||||
self.view_button.setIcon(UiIcons().search)
|
||||
self.view_button.setObjectName('view_button')
|
||||
self.view_layout.addWidget(self.view_button)
|
||||
self.search_layout.addLayout(self.view_layout)
|
||||
|
@ -203,14 +203,14 @@ class Ui_SongSelectDialog(object):
|
|||
self.import_layout = QtWidgets.QHBoxLayout()
|
||||
self.import_layout.setObjectName('import_layout')
|
||||
self.back_button = QtWidgets.QPushButton(self.song_page)
|
||||
self.back_button.setIcon(build_icon(':/general/general_back.png'))
|
||||
self.back_button.setIcon(UiIcons().back)
|
||||
self.back_button.setObjectName('back_button')
|
||||
self.import_layout.addWidget(self.back_button)
|
||||
self.import_spacer = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding,
|
||||
QtWidgets.QSizePolicy.Minimum)
|
||||
self.import_layout.addItem(self.import_spacer)
|
||||
self.import_button = QtWidgets.QPushButton(self.song_page)
|
||||
self.import_button.setIcon(build_icon(':/general/general_import.png'))
|
||||
self.import_button.setIcon(UiIcons().download)
|
||||
self.import_button.setObjectName('import_button')
|
||||
self.import_layout.addWidget(self.import_button)
|
||||
self.song_layout.addLayout(self.import_layout, 5, 0, 1, 5)
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
from PyQt5 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.ui import create_button_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
class Ui_TopicsDialog(object):
|
||||
|
@ -36,7 +36,7 @@ class Ui_TopicsDialog(object):
|
|||
Set up the user interface for the topics dialog.
|
||||
"""
|
||||
topics_dialog.setObjectName('topics_dialog')
|
||||
topics_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
|
||||
topics_dialog.setWindowIcon(UiIcons().main_icon)
|
||||
topics_dialog.resize(300, 10)
|
||||
self.dialog_layout = QtWidgets.QVBoxLayout(topics_dialog)
|
||||
self.dialog_layout.setObjectName('dialog_layout')
|
||||
|
|
|
@ -557,7 +557,7 @@ def transpose_lyrics(lyrics, transpose_value):
|
|||
:return: The transposed lyrics
|
||||
"""
|
||||
# Split text by verse delimiter - both normal and optional
|
||||
verse_list = re.split('(---\[.+?:.+?\]---|\[---\])', lyrics)
|
||||
verse_list = re.split(r'(---\[.+?:.+?\]---|\[---\])', lyrics)
|
||||
transposed_lyrics = ''
|
||||
notation = Settings().value('songs/chord notation')
|
||||
for verse in verse_list:
|
||||
|
@ -580,7 +580,7 @@ def transpose_verse(verse_text, transpose_value, notation):
|
|||
if '[' not in verse_text:
|
||||
return verse_text
|
||||
# Split the lyrics based on chord tags
|
||||
lyric_list = re.split('(\[|\]|/)', verse_text)
|
||||
lyric_list = re.split(r'(\[|\]|/)', verse_text)
|
||||
transposed_lyrics = ''
|
||||
in_tag = False
|
||||
for word in lyric_list:
|
||||
|
|
|
@ -73,7 +73,7 @@ class DreamBeamImport(SongImport):
|
|||
|
||||
Valid extensions for a DreamBeam song file are:
|
||||
|
||||
* \*.xml
|
||||
* .xml
|
||||
"""
|
||||
|
||||
def do_import(self):
|
||||
|
|
|
@ -37,7 +37,7 @@ class EasySlidesImport(SongImport):
|
|||
Import songs exported from EasySlides
|
||||
|
||||
The format example is here:
|
||||
http://wiki.openlp.org/Development:EasySlides\_-_Song_Data_Format
|
||||
http://wiki.openlp.org/Development:EasySlides_-_Song_Data_Format
|
||||
"""
|
||||
def __init__(self, manager, **kwargs):
|
||||
"""
|
||||
|
@ -210,7 +210,7 @@ class EasySlidesImport(SongImport):
|
|||
vn = '1'
|
||||
# have we got any digits?
|
||||
# If so, versenumber is everything from the digits to the end
|
||||
match = re.match('(.*)(\d+.*)', marker)
|
||||
match = re.match(r'(.*)(\d+.*)', marker)
|
||||
if match:
|
||||
marker = match.group(1).strip()
|
||||
vn = match.group(2)
|
||||
|
|
|
@ -273,15 +273,15 @@ class FoilPresenter(object):
|
|||
elif copyright.find('C,)') != -1:
|
||||
temp = copyright.partition('C,)')
|
||||
copyright = temp[0]
|
||||
copyright = re.compile('\\n').sub(' ', copyright)
|
||||
copyright = re.compile('\(.*\)').sub('', copyright)
|
||||
copyright = re.compile(r'\\n').sub(' ', copyright)
|
||||
copyright = re.compile(r'\(.*\)').sub('', copyright)
|
||||
if copyright.find('Rechte') != -1:
|
||||
temp = copyright.partition('Rechte')
|
||||
copyright = temp[0]
|
||||
markers = ['Text +u\.?n?d? +Melodie[\w\,\. ]*:',
|
||||
'Text +u\.?n?d? +Musik', 'T & M', 'Melodie und Satz',
|
||||
'Text[\w\,\. ]*:', 'Melodie', 'Musik', 'Satz',
|
||||
'Weise', '[dD]eutsch', '[dD]t[\.\:]', 'Englisch',
|
||||
markers = [r'Text +u\.?n?d? +Melodie[\w\,\. ]*:',
|
||||
r'Text +u\.?n?d? +Musik', 'T & M', 'Melodie und Satz',
|
||||
r'Text[\w\,\. ]*:', 'Melodie', 'Musik', 'Satz',
|
||||
'Weise', '[dD]eutsch', r'[dD]t[\.\:]', 'Englisch',
|
||||
'[oO]riginal', 'Bearbeitung', '[R|r]efrain']
|
||||
for marker in markers:
|
||||
copyright = re.compile(marker).sub('<marker>', copyright, re.U)
|
||||
|
@ -301,17 +301,17 @@ class FoilPresenter(object):
|
|||
break
|
||||
author_temp = []
|
||||
for author in strings:
|
||||
temp = re.split(',(?=\D{2})|(?<=\D),|\/(?=\D{3,})|(?<=\D);', author)
|
||||
temp = re.split(r',(?=\D{2})|(?<=\D),|\/(?=\D{3,})|(?<=\D);', author)
|
||||
for tempx in temp:
|
||||
author_temp.append(tempx)
|
||||
for author in author_temp:
|
||||
regex = '^[\/,;\-\s\.]+|[\/,;\-\s\.]+$|\s*[0-9]{4}\s*[\-\/]?\s*([0-9]{4})?[\/,;\-\s\.]*$'
|
||||
regex = r'^[\/,;\-\s\.]+|[\/,;\-\s\.]+$|\s*[0-9]{4}\s*[\-\/]?\s*([0-9]{4})?[\/,;\-\s\.]*$'
|
||||
author = re.compile(regex).sub('', author)
|
||||
author = re.compile('[0-9]{1,2}\.\s?J(ahr)?h\.|um\s*$|vor\s*$').sub('', author)
|
||||
author = re.compile('[N|n]ach.*$').sub('', author)
|
||||
author = re.compile(r'[0-9]{1,2}\.\s?J(ahr)?h\.|um\s*$|vor\s*$').sub('', author)
|
||||
author = re.compile(r'[N|n]ach.*$').sub('', author)
|
||||
author = author.strip()
|
||||
if re.search('\w+\.?\s+\w{3,}\s+[a|u]nd\s|\w+\.?\s+\w{3,}\s+&\s', author, re.U):
|
||||
temp = re.split('\s[a|u]nd\s|\s&\s', author)
|
||||
if re.search(r'\w+\.?\s+\w{3,}\s+[a|u]nd\s|\w+\.?\s+\w{3,}\s+&\s', author, re.U):
|
||||
temp = re.split(r'\s[a|u]nd\s|\s&\s', author)
|
||||
for tempx in temp:
|
||||
tempx = tempx.strip()
|
||||
authors.append(tempx)
|
||||
|
|
|
@ -80,7 +80,7 @@ class LyrixImport(SongImport):
|
|||
continue
|
||||
# Detect and get CCLI number
|
||||
if line.lower().startswith('ccli'):
|
||||
ccli = re.findall('\d+', line)[0]
|
||||
ccli = re.findall(r'\d+', line)[0]
|
||||
try:
|
||||
# If the CCLI was found, we are near the end
|
||||
# Find author
|
||||
|
|
|
@ -156,7 +156,7 @@ class OpenSongImport(SongImport):
|
|||
ustring = str(root.__getattr__(attr))
|
||||
if isinstance(fn_or_string, str):
|
||||
if attr in ['ccli']:
|
||||
ustring = ''.join(re.findall('\d+', ustring))
|
||||
ustring = ''.join(re.findall(r'\d+', ustring))
|
||||
if ustring:
|
||||
setattr(self, fn_or_string, int(ustring))
|
||||
else:
|
||||
|
@ -231,7 +231,7 @@ class OpenSongImport(SongImport):
|
|||
content = this_line[1:right_bracket].lower()
|
||||
# have we got any digits? If so, verse number is everything from the digits to the end (openlp does not
|
||||
# have concept of part verses, so just ignore any non integers on the end (including floats))
|
||||
match = re.match('(\D*)(\d+)', content)
|
||||
match = re.match(r'(\D*)(\d+)', content)
|
||||
if match is not None:
|
||||
verse_tag = match.group(1)
|
||||
verse_num = match.group(2)
|
||||
|
@ -303,7 +303,7 @@ class OpenSongImport(SongImport):
|
|||
# whitespace.
|
||||
order = order.lower().split()
|
||||
for verse_def in order:
|
||||
match = re.match('(\D*)(\d+.*)', verse_def)
|
||||
match = re.match(r'(\D*)(\d+.*)', verse_def)
|
||||
if match is not None:
|
||||
verse_tag = match.group(1)
|
||||
verse_num = match.group(2)
|
||||
|
|
|
@ -122,7 +122,7 @@ class OPSProImport(SongImport):
|
|||
# Try to split lyrics based on various rules
|
||||
if lyrics:
|
||||
lyrics_text = lyrics.Lyrics
|
||||
verses = re.split('\r\n\s*?\r\n', lyrics_text)
|
||||
verses = re.split(r'\r\n\s*?\r\n', lyrics_text)
|
||||
verse_tag_defs = {}
|
||||
verse_tag_texts = {}
|
||||
for verse_text in verses:
|
||||
|
@ -130,13 +130,13 @@ class OPSProImport(SongImport):
|
|||
continue
|
||||
verse_def = 'v'
|
||||
# Detect verse number
|
||||
verse_number = re.match('^(\d+)\r\n', verse_text)
|
||||
verse_number = re.match(r'^(\d+)\r\n', verse_text)
|
||||
if verse_number:
|
||||
verse_text = re.sub('^\d+\r\n', '', verse_text)
|
||||
verse_text = re.sub(r'^\d+\r\n', '', verse_text)
|
||||
verse_def = 'v' + verse_number.group(1)
|
||||
# Detect verse tags
|
||||
elif re.match('^.+?\:\r\n', verse_text):
|
||||
tag_match = re.match('^(.+?)\:\r\n(.*)', verse_text, flags=re.DOTALL)
|
||||
elif re.match(r'^.+?\:\r\n', verse_text):
|
||||
tag_match = re.match(r'^(.+?)\:\r\n(.*)', verse_text, flags=re.DOTALL)
|
||||
tag = tag_match.group(1).lower()
|
||||
tag = tag.split(' ')[0]
|
||||
verse_text = tag_match.group(2)
|
||||
|
@ -147,25 +147,25 @@ class OPSProImport(SongImport):
|
|||
verse_tag_defs[tag] = verse_def
|
||||
verse_tag_texts[tag] = verse_text
|
||||
# Detect tag reference
|
||||
elif re.match('^\(.*?\)$', verse_text):
|
||||
tag_match = re.match('^\((.*?)\)$', verse_text)
|
||||
elif re.match(r'^\(.*?\)$', verse_text):
|
||||
tag_match = re.match(r'^\((.*?)\)$', verse_text)
|
||||
tag = tag_match.group(1).lower()
|
||||
if tag in verse_tag_defs:
|
||||
verse_text = verse_tag_texts[tag]
|
||||
verse_def = verse_tag_defs[tag]
|
||||
# Detect end tag
|
||||
elif re.match('^\[slot\]\r\n', verse_text, re.IGNORECASE):
|
||||
elif re.match(r'^\[slot\]\r\n', verse_text, re.IGNORECASE):
|
||||
verse_def = 'e'
|
||||
verse_text = re.sub('^\[slot\]\r\n', '', verse_text, flags=re.IGNORECASE)
|
||||
verse_text = re.sub(r'^\[slot\]\r\n', '', verse_text, flags=re.IGNORECASE)
|
||||
# Replace the join tag with line breaks
|
||||
verse_text = verse_text.replace('[join]', '')
|
||||
# Replace the split tag with line breaks and an optional split
|
||||
verse_text = re.sub('\[splits?\]', '\r\n[---]', verse_text)
|
||||
verse_text = re.sub(r'\[splits?\]', '\r\n[---]', verse_text)
|
||||
# Handle translations
|
||||
if lyrics.IsDualLanguage:
|
||||
verse_text = self.handle_translation(verse_text)
|
||||
# Remove comments
|
||||
verse_text = re.sub('\(.*?\)\r\n', '', verse_text, flags=re.IGNORECASE)
|
||||
verse_text = re.sub(r'\(.*?\)\r\n', '', verse_text, flags=re.IGNORECASE)
|
||||
self.add_verse(verse_text, verse_def)
|
||||
self.finish()
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ class PowerSongImport(SongImport):
|
|||
"""
|
||||
Checks if source is a PowerSong 1.0 folder:
|
||||
* is a directory
|
||||
* contains at least one \*.song file
|
||||
* contains at least one * .song file
|
||||
|
||||
:param openlp.core.common.path.Path import_source: Should be a Path object that fulfills the above criteria
|
||||
:return: If the source is valid
|
||||
|
|
|
@ -51,7 +51,7 @@ class PresentationManagerImport(SongImport):
|
|||
encoding = get_file_encoding(file_path)['encoding']
|
||||
# Open file with detected encoding and remove encoding declaration
|
||||
text = file_path.read_text(encoding=encoding)
|
||||
text = re.sub('.+\?>\n', '', text)
|
||||
text = re.sub(r'.+\?>\n', '', text)
|
||||
try:
|
||||
tree = etree.fromstring(text, parser=etree.XMLParser(recover=True))
|
||||
except ValueError:
|
||||
|
|
|
@ -333,7 +333,7 @@ class SongsOfFellowshipImport(OpenOfficeImport):
|
|||
There is a complicated word "One", which is sometimes lower and
|
||||
sometimes upper depending on context. Never mind, keep it lower.
|
||||
"""
|
||||
text_arr = re.split('(\W+)', text)
|
||||
text_arr = re.split(r'(\W+)', text)
|
||||
text_arr[0] = text_arr[0].capitalize()
|
||||
for i in range(1, len(text_arr)):
|
||||
# Do not translate these. Fixed strings in SOF song file
|
||||
|
|
|
@ -142,7 +142,7 @@ class WorshipAssistantImport(SongImport):
|
|||
# drop the square brackets
|
||||
right_bracket = line.find(']')
|
||||
content = line[1:right_bracket].lower()
|
||||
match = re.match('(\D*)(\d+)', content)
|
||||
match = re.match(r'(\D*)(\d+)', content)
|
||||
if match is not None:
|
||||
verse_tag = match.group(1)
|
||||
verse_num = match.group(2)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue