mirror of
https://gitlab.com/openlp/openlp.git
synced 2024-12-25 11:14:07 +00:00
Migrate from PyQt5 to PySide6
This commit is contained in:
parent
9646242881
commit
169212c812
@ -47,7 +47,8 @@ test-fedora:
|
||||
image: $IMAGE_BASE/fedora
|
||||
script:
|
||||
- sh scripts/generate_resources.sh
|
||||
- xvfb-run -s '-screen 0 1024x768x24' pytest-3 --color=no --disable-warnings
|
||||
# - xvfb-run -s '-screen 0 1024x768x24' pytest-3 --color=no --disable-warnings
|
||||
- xwfb-run -c weston -s \\-geometry -s 1024x768x24 -- pytest
|
||||
|
||||
test-arch:
|
||||
stage: test
|
||||
|
@ -31,7 +31,7 @@ install:
|
||||
# Update pip
|
||||
- python -m pip install --upgrade pip
|
||||
# Install generic dependencies from pypi.
|
||||
- python -m pip install sqlalchemy alembic platformdirs chardet beautifulsoup4 lxml Mako mysql-connector-python pytest mock psycopg2-binary websockets waitress six requests QtAwesome PyQt5 PyQtWebEngine pymediainfo PyMuPDF QDarkStyle python-vlc flask-cors pytest-qt pyenchant pysword qrcode flask packaging
|
||||
- python -m pip install sqlalchemy alembic platformdirs chardet beautifulsoup4 lxml Mako mysql-connector-python pytest mock psycopg2-binary websockets waitress six requests QtAwesome PySide6 PyMuPDF QDarkStyle python-vlc flask-cors pytest-qt pyenchant pysword qrcode flask packaging
|
||||
# Install Windows only dependencies
|
||||
- cmd: python -m pip install pyodbc pypiwin32
|
||||
- cmd: choco install vlc %CHOCO_VLC_ARG% --no-progress --limit-output
|
||||
|
@ -29,7 +29,7 @@ Ignore the version file and pull the version directly
|
||||
from Bazaar
|
||||
.TP
|
||||
\fB\-s\fR STYLE, \fB\-\-style\fR=\fISTYLE\fR
|
||||
Set the Qt5 style (passed directly to Qt5).
|
||||
Set the Qt6 style (passed directly to Qt6).
|
||||
.TP
|
||||
\fB\-\-testing\fR
|
||||
Run by testing framework
|
||||
|
@ -27,7 +27,7 @@ import re
|
||||
from datetime import date
|
||||
from zipfile import ZipFile
|
||||
|
||||
from PyQt5 import QtCore
|
||||
from PySide6 import QtCore
|
||||
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.httputils import download_file, get_web_page, get_openlp_user_agent
|
||||
@ -45,8 +45,8 @@ class RemoteVersionWorker(ThreadWorker):
|
||||
A worker class to fetch the version of the web remote. This is run from within a thread so that it
|
||||
doesn't affect the loading time of OpenLP.
|
||||
"""
|
||||
new_version = QtCore.pyqtSignal(str)
|
||||
no_internet = QtCore.pyqtSignal()
|
||||
new_version = QtCore.Signal(str)
|
||||
no_internet = QtCore.Signal()
|
||||
|
||||
def __init__(self, current_version):
|
||||
"""
|
||||
|
@ -27,7 +27,7 @@ from qrcode.image.svg import SvgPathFillImage
|
||||
|
||||
from time import sleep
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PySide6 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from openlp.core.api.deploy import download_and_install, download_version_info, get_installed_version
|
||||
from openlp.core.common import get_network_interfaces
|
||||
@ -65,8 +65,8 @@ class ApiTab(SettingsTab):
|
||||
self.server_settings_layout.addRow(self.address_label)
|
||||
self.address_edit = QtWidgets.QLineEdit(self.server_settings_group_box)
|
||||
self.address_edit.setSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Fixed)
|
||||
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.setValidator(QtGui.QRegularExpressionValidator(QtCore.QRegularExpression(
|
||||
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'), self))
|
||||
self.address_edit.setObjectName('address_edit')
|
||||
self.address_revert_button = QtWidgets.QToolButton(self.server_settings_group_box)
|
||||
self.address_revert_button.setObjectName('address_revert_button')
|
||||
@ -165,7 +165,7 @@ class ApiTab(SettingsTab):
|
||||
self.app_qr_layout.setObjectName('app_qr_layout')
|
||||
self.app_qr_code_label = QtWidgets.QLabel(self.app_group_box)
|
||||
self.app_qr_code_label.setPixmap(QtGui.QPixmap(':/remotes/app_qr.svg'))
|
||||
self.app_qr_code_label.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.app_qr_code_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
|
||||
self.app_qr_code_label.setObjectName('app_qr_code_label')
|
||||
self.app_qr_layout.addWidget(self.app_qr_code_label)
|
||||
self.app_qr_description_label = QtWidgets.QLabel(self.app_group_box)
|
||||
@ -372,7 +372,7 @@ class ApiTab(SettingsTab):
|
||||
"""
|
||||
self.twelve_hour = False
|
||||
# we have a set value convert to True/False
|
||||
if check_state == QtCore.Qt.Checked:
|
||||
if check_state == QtCore.Qt.CheckState.Checked:
|
||||
self.twelve_hour = True
|
||||
|
||||
def on_thumbnails_check_box_changed(self, check_state):
|
||||
@ -381,7 +381,7 @@ class ApiTab(SettingsTab):
|
||||
"""
|
||||
self.thumbnails = False
|
||||
# we have a set value convert to True/False
|
||||
if check_state == QtCore.Qt.Checked:
|
||||
if check_state == QtCore.Qt.CheckState.Checked:
|
||||
self.thumbnails = True
|
||||
|
||||
def on_check_for_updates_button_clicked(self):
|
||||
|
@ -19,7 +19,7 @@
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
from flask import jsonify, Blueprint
|
||||
from PyQt5 import QtCore
|
||||
from PySide6 import QtCore
|
||||
|
||||
from openlp.core.api.lib import old_auth, old_success_response
|
||||
from openlp.core.common.registry import Registry
|
||||
@ -57,6 +57,7 @@ def plugin_list():
|
||||
def main_image():
|
||||
live_controller = Registry().get('live_controller')
|
||||
img_data = live_controller.staticMetaObject.invokeMethod(
|
||||
live_controller, 'grab_maindisplay', QtCore.Qt.BlockingQueuedConnection, QtCore.Q_RETURN_ARG(str))
|
||||
live_controller, 'grab_maindisplay', QtCore.Qt.ConnectionType.BlockingQueuedConnection,
|
||||
QtCore.Q_RETURN_ARG(str))
|
||||
img = 'data:image/jpeg;base64,{}'.format(img_data)
|
||||
return jsonify({'slide_image': img})
|
||||
|
@ -21,7 +21,7 @@
|
||||
import logging
|
||||
|
||||
from flask import jsonify, request, abort, Blueprint
|
||||
from PyQt5 import QtCore
|
||||
from PySide6 import QtCore
|
||||
|
||||
from openlp.core.api.lib import login_required
|
||||
from openlp.core.common.i18n import LanguageManager
|
||||
@ -109,6 +109,7 @@ def login():
|
||||
def main_image():
|
||||
live_controller = Registry().get('live_controller')
|
||||
img_data = live_controller.staticMetaObject.invokeMethod(
|
||||
live_controller, 'grab_maindisplay', QtCore.Qt.BlockingQueuedConnection, QtCore.Q_RETURN_ARG(str))
|
||||
live_controller, 'grab_maindisplay', QtCore.Qt.ConnectionType.BlockingQueuedConnection,
|
||||
QtCore.Q_RETURN_ARG(str))
|
||||
img = 'data:image/jpeg;base64,{}'.format(img_data)
|
||||
return jsonify({'binary_image': img})
|
||||
|
@ -24,7 +24,7 @@ import json
|
||||
import re
|
||||
|
||||
from flask import abort, request, Blueprint, jsonify, Response
|
||||
from PyQt5 import QtCore
|
||||
from PySide6 import QtCore
|
||||
|
||||
from openlp.core.api.lib import login_required, extract_request, old_success_response, old_auth
|
||||
from openlp.core.lib.plugin import PluginStatus
|
||||
@ -46,7 +46,7 @@ def search(plugin_name, text):
|
||||
if hasattr(plugin.media_item.search, '__pyqtSignature__'):
|
||||
# If this method has a signature, it means that it should be called from the parent thread
|
||||
results = plugin.media_item.staticMetaObject.invokeMethod(
|
||||
plugin.media_item, 'search', QtCore.Qt.BlockingQueuedConnection,
|
||||
plugin.media_item, 'search', QtCore.Qt.ConnectionType.BlockingQueuedConnection,
|
||||
QtCore.Q_RETURN_ARG(list), QtCore.Q_ARG(str, text), QtCore.Q_ARG(bool, False))
|
||||
else:
|
||||
# Fall back to original behaviour
|
||||
|
@ -30,7 +30,7 @@ from dataclasses import asdict, dataclass
|
||||
from typing import Optional, Union
|
||||
|
||||
import time
|
||||
from PyQt5 import QtCore
|
||||
from PySide6 import QtCore
|
||||
from websockets import serve
|
||||
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
@ -207,7 +207,7 @@ class WebSocketServer(RegistryBase, RegistryProperties, QtCore.QObject, LogMixin
|
||||
"""
|
||||
Wrapper round a server instance
|
||||
"""
|
||||
_send_message_signal = QtCore.pyqtSignal(WebSocketMessage)
|
||||
_send_message_signal = QtCore.Signal(WebSocketMessage)
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
@ -231,7 +231,7 @@ class WebSocketServer(RegistryBase, RegistryProperties, QtCore.QObject, LogMixin
|
||||
# Only hooking poller signals after all UI is available
|
||||
Registry().register_function('bootstrap_completion', self.try_poller_hook_signals)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
@QtCore.Slot()
|
||||
def handle_poller_signal(self):
|
||||
if self.worker is not None:
|
||||
self.worker.add_state_to_queues(poller.get_state())
|
||||
|
@ -18,7 +18,7 @@
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
from PyQt5 import QtCore
|
||||
from PySide6 import QtCore
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ class WebSocketPoller(QtCore.QObject, RegistryProperties):
|
||||
Accessed by web sockets to get status type information from the application
|
||||
"""
|
||||
|
||||
poller_changed = QtCore.pyqtSignal()
|
||||
poller_changed = QtCore.Signal()
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
@ -67,9 +67,9 @@ class WebSocketPoller(QtCore.QObject, RegistryProperties):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@QtCore.pyqtSlot(list)
|
||||
@QtCore.pyqtSlot(str)
|
||||
@QtCore.pyqtSlot()
|
||||
@QtCore.Slot(list)
|
||||
@QtCore.Slot(str)
|
||||
@QtCore.Slot()
|
||||
def on_signal_received(self):
|
||||
self._state = self.create_state()
|
||||
self.poller_changed.emit()
|
||||
|
@ -35,7 +35,7 @@ from pathlib import Path
|
||||
from shutil import copytree, move
|
||||
from traceback import format_exception
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWebEngineWidgets, QtWidgets # noqa
|
||||
from PySide6 import QtCore, QtGui, QtWebEngineCore, QtWidgets # noqa
|
||||
|
||||
from openlp.core.api.deploy import check_for_remote_update
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
@ -43,7 +43,7 @@ from openlp.core.common.enum import HiDPIMode
|
||||
from openlp.core.common.i18n import LanguageManager, UiStrings, translate
|
||||
from openlp.core.common.mixins import LogMixin
|
||||
from openlp.core.common.path import create_paths, resolve
|
||||
from openlp.core.common.platform import is_macosx, is_win
|
||||
from openlp.core.common.platform import is_macosx, is_wayland_compositor, is_win
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.display.screens import ScreenList
|
||||
@ -110,7 +110,7 @@ class OpenLP(QtCore.QObject, LogMixin):
|
||||
if not has_run_wizard:
|
||||
ftw = FirstTimeForm()
|
||||
ftw.initialize(screens)
|
||||
if ftw.exec() == QtWidgets.QDialog.Accepted:
|
||||
if ftw.exec() == QtWidgets.QDialog.DialogCode.Accepted:
|
||||
self.settings.setValue('core/has run wizard', True)
|
||||
else:
|
||||
QtCore.QCoreApplication.exit()
|
||||
@ -124,7 +124,9 @@ class OpenLP(QtCore.QObject, LogMixin):
|
||||
# Check if OpenLP has been upgrade and if a backup of data should be created
|
||||
self.backup_on_upgrade(has_run_wizard, can_show_splash)
|
||||
# start the main app window
|
||||
Registry().toggle_suppressing()
|
||||
loader()
|
||||
Registry().toggle_suppressing()
|
||||
# Set the darkmode based on theme
|
||||
set_default_theme(app)
|
||||
self.main_window = MainWindow()
|
||||
@ -162,7 +164,7 @@ class OpenLP(QtCore.QObject, LogMixin):
|
||||
Tell the user there is a 2nd instance running.
|
||||
"""
|
||||
QtWidgets.QMessageBox.critical(None, UiStrings().Error, UiStrings().OpenLPStart,
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
QtWidgets.QMessageBox.StandardButton(QtWidgets.QMessageBox.StandardButton.Ok))
|
||||
|
||||
def is_data_path_missing(self):
|
||||
"""
|
||||
@ -180,9 +182,10 @@ class OpenLP(QtCore.QObject, LogMixin):
|
||||
'current location available.\n\nDo you want to reset to the default data location? '
|
||||
'If not, OpenLP will be closed so you can try to fix the problem.')
|
||||
.format(path=data_folder_path),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
if status == QtWidgets.QMessageBox.No:
|
||||
QtWidgets.QMessageBox.StandardButton(QtWidgets.QMessageBox.StandardButton.Yes |
|
||||
QtWidgets.QMessageBox.StandardButton.No),
|
||||
QtWidgets.QMessageBox.StandardButton.No)
|
||||
if status == QtWidgets.QMessageBox.StandardButton.No:
|
||||
# If answer was "No", return "True", it will shutdown OpenLP in def main
|
||||
log.info('User requested termination')
|
||||
return True
|
||||
@ -230,10 +233,11 @@ class OpenLP(QtCore.QObject, LogMixin):
|
||||
elif data_version != openlp_version:
|
||||
if can_show_splash and self.splash.isVisible():
|
||||
self.splash.hide()
|
||||
if QtWidgets.QMessageBox.question(None, translate('OpenLP', 'Backup'),
|
||||
translate('OpenLP', 'OpenLP has been upgraded, do you want to create\n'
|
||||
'a backup of the old data folder?'),
|
||||
defaultButton=QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.Yes:
|
||||
if (QtWidgets.QMessageBox.question(None, translate('OpenLP', 'Backup'),
|
||||
translate('OpenLP', 'OpenLP has been upgraded, do you want to create\n'
|
||||
'a backup of the old data folder?'),
|
||||
defaultButton=QtWidgets.QMessageBox.StandardButton.Yes) ==
|
||||
QtWidgets.QMessageBox.StandardButton.Yes):
|
||||
# Create copy of data folder
|
||||
data_folder_path = AppLocation.get_data_path()
|
||||
timestamp = time.strftime("%Y%m%d-%H%M%S")
|
||||
@ -266,7 +270,7 @@ class OpenLP(QtCore.QObject, LogMixin):
|
||||
"""
|
||||
Sets the Busy Cursor for the Application
|
||||
"""
|
||||
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.BusyCursor)
|
||||
QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.CursorShape.BusyCursor)
|
||||
QtWidgets.QApplication.processEvents()
|
||||
|
||||
@staticmethod
|
||||
@ -329,7 +333,7 @@ def set_up_web_engine_cache(web_cache_path):
|
||||
:param Path web_cache_path: The folder for the web engine files
|
||||
:rtype: None
|
||||
"""
|
||||
web_engine_profile = QtWebEngineWidgets.QWebEngineProfile.defaultProfile()
|
||||
web_engine_profile = QtWebEngineCore.QWebEngineProfile.defaultProfile()
|
||||
web_engine_profile.setCachePath(str(web_cache_path))
|
||||
web_engine_profile.setPersistentStoragePath(str(web_cache_path))
|
||||
|
||||
@ -359,9 +363,10 @@ def backup_if_version_changed(settings):
|
||||
'OpenLP will start with a fresh install as downgrading data is not supported. Any existing data '
|
||||
'will be backed up to:\n\n{data_folder_backup_path}\n\n'
|
||||
'Do you want to continue?').format(data_folder_backup_path=data_folder_backup_path),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
|
||||
QtWidgets.QMessageBox.No)
|
||||
if close_result == QtWidgets.QMessageBox.No:
|
||||
QtWidgets.QMessageBox.StandardButton(QtWidgets.QMessageBox.StandardButton.Yes |
|
||||
QtWidgets.QMessageBox.StandardButton.No),
|
||||
QtWidgets.QMessageBox.StandardButton.No)
|
||||
if close_result == QtWidgets.QMessageBox.StandardButton.No:
|
||||
# Return false as backup failed.
|
||||
return False
|
||||
# Backup the settings
|
||||
@ -410,14 +415,6 @@ def apply_dpi_adjustments_stage_qt(hidpi_mode, qt_args):
|
||||
qt_args[platform_index + 1] += ' windows:dpiawareness=0'
|
||||
except ValueError:
|
||||
qt_args.extend(['-platform', 'windows:dpiawareness=0'])
|
||||
else:
|
||||
QtWidgets.QApplication.setAttribute(QtCore.Qt.ApplicationAttribute.AA_EnableHighDpiScaling)
|
||||
if hidpi_mode == HiDPIMode.Default:
|
||||
no_custom_factor_rounding = not ('QT_SCALE_FACTOR_ROUNDING_POLICY' in os.environ
|
||||
and bool(os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'].strip()))
|
||||
if no_custom_factor_rounding:
|
||||
# TODO Won't be needed on PyQt6, PassThrough is the default
|
||||
os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'] = 'PassThrough'
|
||||
|
||||
|
||||
def apply_dpi_adjustments_stage_application(hidpi_mode: HiDPIMode, application: QtWidgets.QApplication):
|
||||
@ -428,20 +425,12 @@ def apply_dpi_adjustments_stage_application(hidpi_mode: HiDPIMode, application:
|
||||
:param settings: The settings object
|
||||
:param stage: The stage of app
|
||||
"""
|
||||
if hidpi_mode == HiDPIMode.Default:
|
||||
no_custom_factor_rounding = not ('QT_SCALE_FACTOR_ROUNDING_POLICY' in os.environ
|
||||
and bool(os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'].strip()))
|
||||
if no_custom_factor_rounding and hasattr(QtWidgets.QApplication, 'setHighDpiScaleFactorRoundingPolicy'):
|
||||
# TODO Won't be needed on PyQt6, PassThrough is the default
|
||||
application.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
|
||||
if is_win() and application.devicePixelRatio() > 1.0:
|
||||
# Increasing font size to match pixel ratio (Windows only)
|
||||
# TODO: Review on PyQt6 migration
|
||||
font = application.font()
|
||||
font.setPointSizeF(font.pointSizeF() * application.devicePixelRatio())
|
||||
application.setFont(font)
|
||||
if hidpi_mode != HiDPIMode.Windows_Unaware:
|
||||
application.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
|
||||
if hidpi_mode == HiDPIMode.Default and is_win() and application.devicePixelRatio() > 1.0:
|
||||
# Increasing font size to match pixel ratio (Windows only)
|
||||
# TODO: Review on Qt6 migration
|
||||
font = application.font()
|
||||
font.setPointSizeF(font.pointSizeF() * application.devicePixelRatio())
|
||||
application.setFont(font)
|
||||
|
||||
|
||||
def setup_portable_settings(portable_path: Path | str | None) -> Settings:
|
||||
@ -485,17 +474,15 @@ def main():
|
||||
# support dark mode on windows 10. This makes the titlebar dark, the rest is setup later
|
||||
# by calling set_windows_darkmode
|
||||
qt_args.extend(['-platform', 'windows:darkmode=1'])
|
||||
elif is_macosx() and getattr(sys, 'frozen', False):
|
||||
elif is_macosx() and getattr(sys, 'frozen', False) and not os.environ.get('QTWEBENGINEPROCESS_PATH'):
|
||||
# Set the location to the QtWebEngineProcess binary, normally set by PyInstaller, but it moves around...
|
||||
os.environ['QTWEBENGINEPROCESS_PATH'] = str((AppLocation.get_directory(AppLocation.AppDir) / '..' /
|
||||
'Frameworks' / 'QtWebEngineCore.framework' / 'Versions' / '5' /
|
||||
'Helpers' / 'QtWebEngineProcess.app' / 'Contents' / 'MacOS' /
|
||||
'QtWebEngineProcess').resolve())
|
||||
no_custom_factor_rounding = not ('QT_SCALE_FACTOR_ROUNDING_POLICY' in os.environ
|
||||
and bool(os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'].strip()))
|
||||
if no_custom_factor_rounding:
|
||||
# TODO Won't be needed on PyQt6
|
||||
os.environ['QT_SCALE_FACTOR_ROUNDING_POLICY'] = 'PassThrough'
|
||||
os.environ['QTWEBENGINEPROCESS_PATH'] = str((AppLocation.get_directory(AppLocation.AppDir) / 'PySide6' /
|
||||
'Qt6' / 'lib' / 'QtWebEngineCore.framework' / 'Versions' /
|
||||
'6' / 'Helpers' / 'QtWebEngineProcess.app' / 'Contents' /
|
||||
'MacOS' / 'QtWebEngineProcess').resolve())
|
||||
# Prevent the use of wayland, use xcb instead
|
||||
if is_wayland_compositor():
|
||||
qt_args.extend(['-platform', 'xcb'])
|
||||
# Initialise the resources
|
||||
qInitResources()
|
||||
# Initialise OpenLP
|
||||
@ -518,12 +505,9 @@ def main():
|
||||
# Instantiating QCoreApplication
|
||||
init_webview_custom_schemes()
|
||||
application = QtWidgets.QApplication(qt_args)
|
||||
application.setAttribute(QtCore.Qt.AA_DontCreateNativeWidgetSiblings, True)
|
||||
application.setAttribute(QtCore.Qt.ApplicationAttribute.AA_DontCreateNativeWidgetSiblings, True)
|
||||
# Doing HiDPI adjustments that need to be done after QCoreApplication instantiation.
|
||||
apply_dpi_adjustments_stage_application(hidpi_mode, application)
|
||||
if no_custom_factor_rounding and hasattr(QtWidgets.QApplication, 'setHighDpiScaleFactorRoundingPolicy'):
|
||||
# TODO: Check won't be needed on PyQt6
|
||||
application.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
|
||||
if is_win() and application.devicePixelRatio() > 1.0:
|
||||
# Increasing font size to match pixel ratio (Windows only)
|
||||
font = application.font()
|
||||
|
@ -33,9 +33,9 @@ from ipaddress import IPv4Address, IPv6Address, AddressValueError
|
||||
from pathlib import Path
|
||||
from shutil import which
|
||||
|
||||
from PyQt5 import QtGui
|
||||
from PyQt5.QtCore import QCryptographicHash as QHash
|
||||
from PyQt5.QtNetwork import QAbstractSocket, QHostAddress, QNetworkInterface
|
||||
from PySide6 import QtGui
|
||||
from PySide6.QtCore import QCryptographicHash as QHash
|
||||
from PySide6.QtNetwork import QAbstractSocket, QHostAddress, QNetworkInterface
|
||||
from chardet.universaldetector import UniversalDetector
|
||||
|
||||
log = logging.getLogger(__name__ + '.__init__')
|
||||
@ -68,21 +68,21 @@ def get_network_interfaces():
|
||||
log.debug('Filtering out interfaces we don\'t care about: {name}'.format(name=interface_name))
|
||||
continue
|
||||
log.debug('Checking for isValid and flags == IsUP | IsRunning')
|
||||
if not interface.isValid() or not (interface.flags() & (QNetworkInterface.IsUp | QNetworkInterface.IsRunning)):
|
||||
if not interface.isValid() or not (interface.flags() & (QNetworkInterface.InterfaceFlag.IsUp |
|
||||
QNetworkInterface.InterfaceFlag.IsRunning)):
|
||||
continue
|
||||
log.debug('Checking address(es) protocol')
|
||||
for address in interface.addressEntries():
|
||||
ip = address.ip()
|
||||
log.debug('Checking for protocol == IPv4Protocol')
|
||||
if ip.protocol() == QAbstractSocket.IPv4Protocol:
|
||||
if ip.protocol() == QAbstractSocket.NetworkLayerProtocol.IPv4Protocol:
|
||||
log.debug('Getting interface information')
|
||||
interfaces[interface_name] = {
|
||||
'ip': ip.toString(),
|
||||
'broadcast': address.broadcast().toString(),
|
||||
'netmask': address.netmask().toString(),
|
||||
'prefix': address.prefixLength(),
|
||||
'localnet': QHostAddress(address.netmask().toIPv4Address() &
|
||||
ip.toIPv4Address()).toString()
|
||||
'localnet': QHostAddress(address.netmask().toIPv4Address() & ip.toIPv4Address()).toString()
|
||||
}
|
||||
log.debug('Adding {interface} to active list'.format(interface=interface.name()))
|
||||
if len(interfaces) == 0:
|
||||
@ -298,7 +298,7 @@ def sha256_file_hash(filename):
|
||||
def qmd5_hash(salt=None, data=None):
|
||||
"""
|
||||
Returns the hashed output of MD5Sum on salt, data
|
||||
using PyQt5.QCryptographicHash. Function returns a
|
||||
using PySide6.QCryptographicHash. Function returns a
|
||||
QByteArray instead of a text string.
|
||||
If you need a string instead, call with
|
||||
|
||||
|
@ -24,7 +24,7 @@ by the shortcuts system.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PySide6 import QtCore, QtGui
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
|
||||
@ -352,17 +352,19 @@ class ActionList(object):
|
||||
:param existing_actions: A list of actions which already use a particular shortcut.
|
||||
:param action: The action which wants to use a particular shortcut.
|
||||
"""
|
||||
global_context = action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]
|
||||
global_context = action.shortcutContext() in [QtCore.Qt.ShortcutContext.WindowShortcut,
|
||||
QtCore.Qt.ShortcutContext.ApplicationShortcut]
|
||||
affected_actions = []
|
||||
if global_context:
|
||||
affected_actions = [a for a in self.get_all_child_objects(action.parent()) if isinstance(a,
|
||||
QtWidgets.QAction)]
|
||||
QtGui.QAction)]
|
||||
for existing_action in existing_actions:
|
||||
if action is existing_action:
|
||||
continue
|
||||
if existing_action in affected_actions:
|
||||
return False
|
||||
if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||
if existing_action.shortcutContext() in [QtCore.Qt.ShortcutContext.WindowShortcut,
|
||||
QtCore.Qt.ShortcutContext.ApplicationShortcut]:
|
||||
return False
|
||||
elif action in self.get_all_child_objects(existing_action.parent()):
|
||||
return False
|
||||
|
@ -26,7 +26,7 @@ from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
from PySide6 import QtWidgets
|
||||
|
||||
from openlp.core.common.i18n import translate
|
||||
|
||||
|
@ -30,7 +30,7 @@ from random import randint
|
||||
from tempfile import gettempdir
|
||||
|
||||
import requests
|
||||
from PyQt5 import QtCore
|
||||
from PySide6 import QtCore
|
||||
|
||||
from openlp.core.common import trace_error_handler
|
||||
from openlp.core.common.registry import Registry
|
||||
@ -249,8 +249,8 @@ class DownloadWorker(ThreadWorker):
|
||||
"""
|
||||
This worker allows a file to be downloaded in a thread
|
||||
"""
|
||||
download_failed = QtCore.pyqtSignal()
|
||||
download_succeeded = QtCore.pyqtSignal(Path)
|
||||
download_failed = QtCore.Signal()
|
||||
download_succeeded = QtCore.Signal(Path)
|
||||
|
||||
def __init__(self, base_url, file_name):
|
||||
"""
|
||||
@ -283,7 +283,7 @@ class DownloadWorker(ThreadWorker):
|
||||
time.sleep(1)
|
||||
self.quit.emit()
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
@QtCore.Slot()
|
||||
def cancel_download(self):
|
||||
"""
|
||||
A slot to allow the download to be cancelled from outside of the thread
|
||||
|
@ -27,7 +27,7 @@ import logging
|
||||
import re
|
||||
from collections import namedtuple
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from PySide6 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common import Singleton
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
@ -40,7 +40,7 @@ log = logging.getLogger(__name__)
|
||||
# Due to dependency issues, this HAS to be at the top of the file
|
||||
def translate(context, text, comment=None, qt_translate=QtCore.QCoreApplication.translate):
|
||||
"""
|
||||
A special shortcut method to wrap around the Qt5 translation functions. This abstracts the translation procedure so
|
||||
A special shortcut method to wrap around the Qt6 translation functions. This abstracts the translation procedure so
|
||||
that we can change it if at a later date if necessary, without having to redo the whole of OpenLP.
|
||||
|
||||
:param context: The translation context, used to give each string a context or a namespace.
|
||||
@ -231,8 +231,8 @@ class LanguageManager(object):
|
||||
log.info(f"Language: '{language}' loaded.")
|
||||
# A translator for buttons and other default strings provided by Qt.
|
||||
if not is_win() and not is_macosx():
|
||||
lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)
|
||||
# As of Qt5, the core translations come in 2 files per language
|
||||
lang_path = QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.LibraryPath.TranslationsPath)
|
||||
# As of Qt6, the core translations come in 2 files per language
|
||||
default_translator = QtCore.QTranslator()
|
||||
default_translator.load('qt_%s' % language, lang_path)
|
||||
base_translator = QtCore.QTranslator()
|
||||
@ -246,7 +246,7 @@ class LanguageManager(object):
|
||||
"""
|
||||
log.debug('Translation files: {files}'.format(files=AppLocation.get_directory(AppLocation.LanguageDir)))
|
||||
trans_dir = QtCore.QDir(str(AppLocation.get_directory(AppLocation.LanguageDir)))
|
||||
file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Filter.Files, QtCore.QDir.Name)
|
||||
file_names = trans_dir.entryList(['*.qm'], QtCore.QDir.Filter.Files, QtCore.QDir.SortFlag.Name)
|
||||
# Remove qm files from the list which start with "qt".
|
||||
file_names = [file_ for file_ in file_names if not file_.startswith('qt')]
|
||||
return list(map(trans_dir.filePath, file_names))
|
||||
@ -310,7 +310,7 @@ class LanguageManager(object):
|
||||
LanguageManager.__qm_list__ = {}
|
||||
qm_files = LanguageManager.find_qm_files()
|
||||
for counter, qmf in enumerate(qm_files):
|
||||
reg_ex = QtCore.QRegExp("^.*i18n/(.*).qm")
|
||||
reg_ex = QtCore.QRegularExpression("^.*i18n/(.*).qm")
|
||||
if reg_ex.exactMatch(qmf):
|
||||
name = '{regex}'.format(regex=reg_ex.cap(1))
|
||||
LanguageManager.__qm_list__[
|
||||
|
@ -27,10 +27,12 @@ import logging
|
||||
from openlp.core.common import trace_error_handler
|
||||
from openlp.core.common.platform import is_win
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
|
||||
|
||||
DO_NOT_TRACE_EVENTS = ['timerEvent', 'paintEvent', 'drag_enter_event', 'drop_event', 'on_controller_size_changed',
|
||||
'preview_size_changed', 'resizeEvent', 'eventFilter', 'tick', 'resize', 'update_ui']
|
||||
'preview_size_changed', 'resizeEvent', 'eventFilter', 'tick', 'resize', 'update_ui',
|
||||
'get_time']
|
||||
|
||||
|
||||
class LogMixin(object):
|
||||
@ -240,7 +242,7 @@ class RegistryProperties(object):
|
||||
return self._projector_manager
|
||||
|
||||
@property
|
||||
def settings(self):
|
||||
def settings(self) -> Settings:
|
||||
"""
|
||||
Adds the settings object to the class dynamically
|
||||
"""
|
||||
|
@ -110,7 +110,7 @@ def is_xorg_platform():
|
||||
|
||||
:return: True if the Qt is running on X.org/XWayland display server (Linux/*nix), otherwise False.
|
||||
"""
|
||||
from PyQt5 import QtGui
|
||||
from PySide6 import QtGui
|
||||
return QtGui.QGuiApplication.platformName() == 'xcb'
|
||||
|
||||
|
||||
@ -120,5 +120,5 @@ def is_wayland_platform():
|
||||
|
||||
:return: True if the OpenLP/Qt instance is running in a Wayland compositor, otherwise False
|
||||
"""
|
||||
from PyQt5 import QtGui
|
||||
from PySide6 import QtGui
|
||||
return QtGui.QGuiApplication.platformName() == 'wayland'
|
||||
|
@ -54,6 +54,12 @@ class Registry(metaclass=Singleton):
|
||||
registry._is_suppressing = False
|
||||
return registry
|
||||
|
||||
def toggle_suppressing(self) -> None:
|
||||
"""
|
||||
Switch error message suppression during initialisation
|
||||
"""
|
||||
self._is_suppressing = not self._is_suppressing
|
||||
|
||||
def get(self, key: str) -> Any | None:
|
||||
"""
|
||||
Extracts the registry value from the list based on the key passed in
|
||||
@ -62,6 +68,8 @@ class Registry(metaclass=Singleton):
|
||||
"""
|
||||
if key in self.service_list:
|
||||
return self.service_list[key]
|
||||
elif self._is_suppressing:
|
||||
return None
|
||||
else:
|
||||
warn(f'Service "{key}" not found in list', stacklevel=2)
|
||||
return None
|
||||
|
@ -29,7 +29,7 @@ from enum import IntEnum
|
||||
from pathlib import Path
|
||||
from tempfile import gettempdir
|
||||
|
||||
from PyQt5 import QtCore, QtGui
|
||||
from PySide6 import QtCore, QtGui
|
||||
|
||||
from openlp.core.common import SlideLimits, ThemeLevel
|
||||
from openlp.core.common.enum import AlertLocation, BibleSearch, CustomSearch, HiDPIMode, ImageThemeMode, LayoutStyle, \
|
||||
@ -301,7 +301,7 @@ class Settings(QtCore.QSettings):
|
||||
'media/status': PluginStatus.Inactive,
|
||||
'media/media files': [],
|
||||
'media/last directory': None,
|
||||
'media/media auto start': QtCore.Qt.Unchecked,
|
||||
'media/media auto start': QtCore.Qt.CheckState.Unchecked,
|
||||
'media/vlc arguments': '',
|
||||
'media/live volume': 50,
|
||||
'media/preview volume': 0,
|
||||
@ -317,18 +317,18 @@ class Settings(QtCore.QSettings):
|
||||
'planningcenter/application_id': '',
|
||||
'planningcenter/secret': '',
|
||||
'presentations/status': PluginStatus.Inactive,
|
||||
'presentations/override app': QtCore.Qt.Unchecked,
|
||||
'presentations/maclo': QtCore.Qt.Checked,
|
||||
'presentations/Impress': QtCore.Qt.Checked,
|
||||
'presentations/Powerpoint': QtCore.Qt.Checked,
|
||||
'presentations/Pdf': QtCore.Qt.Checked,
|
||||
'presentations/Keynote': QtCore.Qt.Checked,
|
||||
'presentations/PowerPointMac': QtCore.Qt.Checked,
|
||||
'presentations/override app': QtCore.Qt.CheckState.Unchecked,
|
||||
'presentations/maclo': QtCore.Qt.CheckState.Checked,
|
||||
'presentations/Impress': QtCore.Qt.CheckState.Checked,
|
||||
'presentations/Powerpoint': QtCore.Qt.CheckState.Checked,
|
||||
'presentations/Pdf': QtCore.Qt.CheckState.Checked,
|
||||
'presentations/Keynote': QtCore.Qt.CheckState.Checked,
|
||||
'presentations/PowerPointMac': QtCore.Qt.CheckState.Checked,
|
||||
'presentations/presentations files': [],
|
||||
'presentations/thumbnail_scheme': '',
|
||||
'presentations/powerpoint slide click advance': QtCore.Qt.Unchecked,
|
||||
'presentations/powerpoint control window': QtCore.Qt.Unchecked,
|
||||
'presentations/impress use display setting': QtCore.Qt.Unchecked,
|
||||
'presentations/powerpoint slide click advance': QtCore.Qt.CheckState.Unchecked,
|
||||
'presentations/powerpoint control window': QtCore.Qt.CheckState.Unchecked,
|
||||
'presentations/impress use display setting': QtCore.Qt.CheckState.Unchecked,
|
||||
'presentations/last directory': None,
|
||||
'presentations/db type': 'sqlite',
|
||||
'presentations/db username': '',
|
||||
@ -535,17 +535,18 @@ class Settings(QtCore.QSettings):
|
||||
def init_default_shortcuts(self):
|
||||
# Add shortcuts here so QKeySequence has a QApplication instance to use.
|
||||
Settings.__default_settings__.update({
|
||||
'shortcuts/aboutItem': [QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_F1)],
|
||||
'shortcuts/aboutItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Control + QtCore.Qt.Key.Key_F1)],
|
||||
'shortcuts/addToService': [],
|
||||
'shortcuts/audioPauseItem': [],
|
||||
'shortcuts/displayTagItem': [],
|
||||
'shortcuts/blankScreen': [QtGui.QKeySequence(QtCore.Qt.Key_Period)],
|
||||
'shortcuts/collapse': [QtGui.QKeySequence(QtCore.Qt.Key_Minus)],
|
||||
'shortcuts/desktopScreen': [QtGui.QKeySequence(QtCore.Qt.Key_D), QtGui.QKeySequence(QtCore.Qt.Key_Escape)],
|
||||
'shortcuts/blankScreen': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Period)],
|
||||
'shortcuts/collapse': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Minus)],
|
||||
'shortcuts/desktopScreen': [QtGui.QKeySequence(QtCore.Qt.Key.Key_D),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Escape)],
|
||||
'shortcuts/delete': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
|
||||
'shortcuts/down': [QtGui.QKeySequence(QtCore.Qt.Key_Down)],
|
||||
'shortcuts/down': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Down)],
|
||||
'shortcuts/editSong': [],
|
||||
'shortcuts/expand': [QtGui.QKeySequence(QtCore.Qt.Key_Plus)],
|
||||
'shortcuts/expand': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus)],
|
||||
'shortcuts/exportThemeItem': [],
|
||||
'shortcuts/fileNewItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.New)],
|
||||
'shortcuts/fileSaveAsItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.SaveAs)],
|
||||
@ -557,82 +558,85 @@ class Settings(QtCore.QSettings):
|
||||
'shortcuts/importThemeItem': [],
|
||||
'shortcuts/importBibleItem': [],
|
||||
'shortcuts/listViewBiblesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
|
||||
'shortcuts/listViewBiblesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewBiblesLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewBiblesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||
'shortcuts/listViewBiblesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewBiblesLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewBiblesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
|
||||
'shortcuts/listViewCustomDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
|
||||
'shortcuts/listViewCustomPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewCustomLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewCustomServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||
'shortcuts/listViewCustomPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewCustomLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewCustomServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
|
||||
'shortcuts/listViewImagesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
|
||||
'shortcuts/listViewImagesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewImagesLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewImagesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||
'shortcuts/listViewImagesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewImagesLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewImagesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
|
||||
'shortcuts/listViewMediaDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
|
||||
'shortcuts/listViewMediaPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewMediaLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewMediaServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||
'shortcuts/listViewMediaPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewMediaLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewMediaServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
|
||||
'shortcuts/listViewPresentationsDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
|
||||
'shortcuts/listViewPresentationsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewPresentationsLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewPresentationsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||
'shortcuts/listViewPresentationsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewPresentationsLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift +
|
||||
QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift +
|
||||
QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewPresentationsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
|
||||
'shortcuts/listViewSongsDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Delete)],
|
||||
'shortcuts/listViewSongsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewSongsLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/listViewSongsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||
'shortcuts/listViewSongsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewSongsLiveItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Shift + QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/listViewSongsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Plus),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Equal)],
|
||||
'shortcuts/lockPanel': [],
|
||||
'shortcuts/modeDefaultItem': [],
|
||||
'shortcuts/modeLiveItem': [],
|
||||
'shortcuts/make_live': [QtGui.QKeySequence(QtCore.Qt.Key_Return), QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
|
||||
'shortcuts/moveUp': [QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
|
||||
'shortcuts/moveTop': [QtGui.QKeySequence(QtCore.Qt.Key_Home)],
|
||||
'shortcuts/make_live': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Return),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_Enter)],
|
||||
'shortcuts/moveUp': [QtGui.QKeySequence(QtCore.Qt.Key.Key_PageUp)],
|
||||
'shortcuts/moveTop': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Home)],
|
||||
'shortcuts/modeSetupItem': [],
|
||||
'shortcuts/moveBottom': [QtGui.QKeySequence(QtCore.Qt.Key_End)],
|
||||
'shortcuts/moveDown': [QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
|
||||
'shortcuts/moveBottom': [QtGui.QKeySequence(QtCore.Qt.Key.Key_End)],
|
||||
'shortcuts/moveDown': [QtGui.QKeySequence(QtCore.Qt.Key.Key_PageDown)],
|
||||
'shortcuts/nextTrackItem': [],
|
||||
'shortcuts/nextItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Down),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
|
||||
'shortcuts/nextItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key_Down),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
|
||||
'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key_Right)],
|
||||
'shortcuts/nextItem_live': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Down),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_PageDown)],
|
||||
'shortcuts/nextItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Down),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_PageDown)],
|
||||
'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Right)],
|
||||
'shortcuts/newService': [],
|
||||
'shortcuts/openService': [],
|
||||
'shortcuts/saveService': [],
|
||||
'shortcuts/previousItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
|
||||
'shortcuts/previousItem_live': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Up),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_PageUp)],
|
||||
'shortcuts/playbackPause': [],
|
||||
'shortcuts/playbackPlay': [],
|
||||
'shortcuts/playbackStop': [],
|
||||
'shortcuts/playSlidesLoop': [],
|
||||
'shortcuts/playSlidesOnce': [],
|
||||
'shortcuts/previousService': [QtGui.QKeySequence(QtCore.Qt.Key_Left)],
|
||||
'shortcuts/previousItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
|
||||
'shortcuts/previousService': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Left)],
|
||||
'shortcuts/previousItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Up),
|
||||
QtGui.QKeySequence(QtCore.Qt.Key.Key_PageUp)],
|
||||
'shortcuts/printServiceItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Print)],
|
||||
'shortcuts/songExportItem': [],
|
||||
'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key_F4)],
|
||||
'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F4)],
|
||||
'shortcuts/searchShortcut': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Find)],
|
||||
'shortcuts/settingsShortcutsItem': [],
|
||||
'shortcuts/settingsImportItem': [],
|
||||
'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_F7)],
|
||||
'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Alt + QtCore.Qt.Key.Key_F7)],
|
||||
'shortcuts/songUsageDelete': [],
|
||||
'shortcuts/settingsConfigureItem': [QtGui.QKeySequence(QtGui.QKeySequence.StandardKey.Preferences)],
|
||||
'shortcuts/shortcutAction_B': [QtGui.QKeySequence(QtCore.Qt.Key_B)],
|
||||
@ -656,22 +660,22 @@ class Settings(QtCore.QSettings):
|
||||
'shortcuts/settingsExportItem': [],
|
||||
'shortcuts/songUsageReport': [],
|
||||
'shortcuts/songImportItem': [],
|
||||
'shortcuts/themeScreen': [QtGui.QKeySequence(QtCore.Qt.Key_T)],
|
||||
'shortcuts/themeScreen': [QtGui.QKeySequence(QtCore.Qt.Key.Key_T)],
|
||||
'shortcuts/toolsReindexItem': [],
|
||||
'shortcuts/toolsFindDuplicates': [],
|
||||
'shortcuts/toolsSongListReport': [],
|
||||
'shortcuts/toolsAlertItem': [QtGui.QKeySequence(QtCore.Qt.Key_F7)],
|
||||
'shortcuts/toolsAlertItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F7)],
|
||||
'shortcuts/toolsFirstTimeWizard': [],
|
||||
'shortcuts/toolsOpenDataFolder': [],
|
||||
'shortcuts/toolsAddToolItem': [],
|
||||
'shortcuts/updateThemeImages': [],
|
||||
'shortcuts/up': [QtGui.QKeySequence(QtCore.Qt.Key_Up)],
|
||||
'shortcuts/viewProjectorManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key_F6)],
|
||||
'shortcuts/viewThemeManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key_F10)],
|
||||
'shortcuts/viewMediaManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key_F8)],
|
||||
'shortcuts/viewPreviewPanel': [QtGui.QKeySequence(QtCore.Qt.Key_F11)],
|
||||
'shortcuts/viewLivePanel': [QtGui.QKeySequence(QtCore.Qt.Key_F12)],
|
||||
'shortcuts/viewServiceManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key_F9)],
|
||||
'shortcuts/up': [QtGui.QKeySequence(QtCore.Qt.Key.Key_Up)],
|
||||
'shortcuts/viewProjectorManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F6)],
|
||||
'shortcuts/viewThemeManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F10)],
|
||||
'shortcuts/viewMediaManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F8)],
|
||||
'shortcuts/viewPreviewPanel': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F11)],
|
||||
'shortcuts/viewLivePanel': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F12)],
|
||||
'shortcuts/viewServiceManagerItem': [QtGui.QKeySequence(QtCore.Qt.Key.Key_F9)],
|
||||
'shortcuts/webSiteItem': []
|
||||
})
|
||||
|
||||
|
@ -28,7 +28,7 @@ import math
|
||||
import os
|
||||
import re
|
||||
|
||||
from PyQt5 import QtWidgets, QtGui
|
||||
from PySide6 import QtWidgets, QtGui
|
||||
|
||||
from openlp.core.common import ThemeLevel
|
||||
from openlp.core.common.enum import ServiceItemType
|
||||
|
@ -26,7 +26,7 @@ import logging
|
||||
import copy
|
||||
from functools import cmp_to_key
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from PySide6 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common import Singleton
|
||||
from openlp.core.common.i18n import translate
|
||||
@ -299,7 +299,8 @@ class ScreenList(metaclass=Singleton):
|
||||
'There is a mismatch between screens and screen settings. '
|
||||
'OpenLP will try to automatically select a display screen, but '
|
||||
'you should consider updating the screen settings.'),
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||
QtWidgets.QMessageBox.StandardButton(
|
||||
QtWidgets.QMessageBox.StandardButton.Ok))
|
||||
self.find_new_display_screen()
|
||||
else:
|
||||
# if no settings we need to set a display
|
||||
|
@ -25,7 +25,7 @@ Heavily inspired by https://stackoverflow.com/questions/33467776/qt-qwebengine-r
|
||||
import logging
|
||||
import os.path
|
||||
|
||||
from PyQt5 import QtCore, QtWebEngineWidgets, QtWidgets, QtWebEngineCore
|
||||
from PySide6 import QtCore, QtWebEngineCore, QtWebEngineWidgets, QtWidgets
|
||||
from typing import Tuple
|
||||
|
||||
from openlp.core.common import Singleton
|
||||
@ -35,16 +35,16 @@ from openlp.core.common.platform import is_win
|
||||
|
||||
|
||||
LOG_LEVELS = {
|
||||
QtWebEngineWidgets.QWebEnginePage.InfoMessageLevel: logging.INFO,
|
||||
QtWebEngineWidgets.QWebEnginePage.WarningMessageLevel: logging.WARNING,
|
||||
QtWebEngineWidgets.QWebEnginePage.ErrorMessageLevel: logging.ERROR
|
||||
QtWebEngineCore.QWebEnginePage.JavaScriptConsoleMessageLevel.InfoMessageLevel: logging.INFO,
|
||||
QtWebEngineCore.QWebEnginePage.JavaScriptConsoleMessageLevel.WarningMessageLevel: logging.WARNING,
|
||||
QtWebEngineCore.QWebEnginePage.JavaScriptConsoleMessageLevel.ErrorMessageLevel: logging.ERROR
|
||||
}
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
|
||||
class WebEnginePage(QtWebEngineCore.QWebEnginePage):
|
||||
"""
|
||||
A custom WebEngine page to capture Javascript console logging
|
||||
"""
|
||||
@ -68,7 +68,7 @@ class WebEngineView(QtWebEngineWidgets.QWebEngineView):
|
||||
and set some attributtes.
|
||||
"""
|
||||
_child = None # QtWidgets.QOpenGLWidget or QWidget?
|
||||
delegatePaint = QtCore.pyqtSignal()
|
||||
delegatePaint = QtCore.Signal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
@ -76,22 +76,26 @@ class WebEngineView(QtWebEngineWidgets.QWebEngineView):
|
||||
"""
|
||||
super(WebEngineView, self).__init__(parent)
|
||||
self.setPage(WebEnginePage(self))
|
||||
self.settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalStorageEnabled, True)
|
||||
self.settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessFileUrls, True)
|
||||
self.settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessRemoteUrls, True)
|
||||
self.page().settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalStorageEnabled, True)
|
||||
self.page().settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessFileUrls, True)
|
||||
self.page().settings().setAttribute(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessRemoteUrls, True)
|
||||
self.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
|
||||
self.settings().setAttribute(QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalStorageEnabled, True)
|
||||
self.settings().setAttribute(
|
||||
QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, True)
|
||||
self.settings().setAttribute(
|
||||
QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, True)
|
||||
self.page().settings().setAttribute(QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalStorageEnabled, True)
|
||||
self.page().settings().setAttribute(
|
||||
QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalContentCanAccessFileUrls, True)
|
||||
self.page().settings().setAttribute(
|
||||
QtWebEngineCore.QWebEngineSettings.WebAttribute.LocalContentCanAccessRemoteUrls, True)
|
||||
self.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.PreventContextMenu)
|
||||
|
||||
def eventFilter(self, obj, ev):
|
||||
"""
|
||||
Emit delegatePaint on paint event of the last added QOpenGLWidget child
|
||||
"""
|
||||
if obj == self._child:
|
||||
if ev.type() == QtCore.QEvent.MouseButtonPress or ev.type() == QtCore.QEvent.TouchBegin:
|
||||
if ev.type() == QtCore.QEvent.Type.MouseButtonPress or ev.type() == QtCore.QEvent.Type.TouchBegin:
|
||||
self.display_clicked()
|
||||
if ev.type() == QtCore.QEvent.Paint:
|
||||
if ev.type() == QtCore.QEvent.Type.Paint:
|
||||
self.delegatePaint.emit()
|
||||
return super(WebEngineView, self).eventFilter(obj, ev)
|
||||
|
||||
@ -105,7 +109,7 @@ class WebEngineView(QtWebEngineWidgets.QWebEngineView):
|
||||
"""
|
||||
Handle events
|
||||
"""
|
||||
if ev.type() == QtCore.QEvent.ChildAdded:
|
||||
if ev.type() == QtCore.QEvent.Type.ChildAdded:
|
||||
# Only use QWidget child (used to be QOpenGLWidget)
|
||||
w = ev.child()
|
||||
if w and isinstance(w, QtWidgets.QWidget):
|
||||
@ -217,7 +221,7 @@ class WebViewCustomScheme(QtCore.QObject):
|
||||
|
||||
def init_handler(self, profile=None):
|
||||
if profile is None:
|
||||
profile = QtWebEngineWidgets.QWebEngineProfile.defaultProfile()
|
||||
profile = QtWebEngineCore.QWebEngineProfile.defaultProfile()
|
||||
handler = profile.urlSchemeHandler(self.scheme_name)
|
||||
if handler is not None:
|
||||
profile.removeUrlSchemeHandler(handler)
|
||||
|
@ -27,7 +27,7 @@ import os
|
||||
import copy
|
||||
import re
|
||||
|
||||
from PyQt5 import QtCore, QtWebChannel, QtWidgets
|
||||
from PySide6 import QtCore, QtWebChannel, QtWidgets
|
||||
|
||||
from openlp.core.common.enum import ServiceItemType
|
||||
from openlp.core.common.i18n import translate
|
||||
@ -49,7 +49,7 @@ class DisplayWatcher(QtCore.QObject):
|
||||
"""
|
||||
This facilitates communication from the Display object in the browser back to the Python
|
||||
"""
|
||||
initialised = QtCore.pyqtSignal(bool)
|
||||
initialised = QtCore.Signal(bool)
|
||||
|
||||
def __init__(self, parent, window_title=None):
|
||||
super().__init__()
|
||||