Reorganized and fixed the WebAuth related dialog and moved it in a new package. eric7

Wed, 17 Jul 2024 16:48:46 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 17 Jul 2024 16:48:46 +0200
branch
eric7
changeset 10852
65ee5eba7b10
parent 10851
5c47172bb240
child 10853
1f651b204780

Reorganized and fixed the WebAuth related dialog and moved it in a new package.

eric7.epj file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/Ui_WebBrowserWebAuthDialog.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebAuth/Ui_WebBrowserWebAuthDialog.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebAuth/WebBrowserWebAuthDialog.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebAuth/WebBrowserWebAuthDialog.ui file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebAuth/__init__.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebBrowserView.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebBrowserWebAuthDialog.py file | annotate | diff | comparison | revisions
src/eric7/WebBrowser/WebBrowserWebAuthDialog.ui file | annotate | diff | comparison | revisions
--- a/eric7.epj	Tue Jul 16 19:47:54 2024 +0200
+++ b/eric7.epj	Wed Jul 17 16:48:46 2024 +0200
@@ -783,9 +783,9 @@
       "src/eric7/WebBrowser/VirusTotal/VirusTotalDomainReportDialog.ui",
       "src/eric7/WebBrowser/VirusTotal/VirusTotalIpReportDialog.ui",
       "src/eric7/WebBrowser/VirusTotal/VirusTotalWhoisDialog.ui",
+      "src/eric7/WebBrowser/WebAuth/WebBrowserWebAuthDialog.ui",
       "src/eric7/WebBrowser/WebBrowserClearPrivateDataDialog.ui",
       "src/eric7/WebBrowser/WebBrowserLanguagesDialog.ui",
-      "src/eric7/WebBrowser/WebBrowserWebAuthDialog.ui",
       "src/eric7/WebBrowser/ZoomManager/ZoomValuesDialog.ui"
     ],
     "HASH": "df7daa8781250f7664e6ecaeaf1361fa2efd39ee",
@@ -2449,6 +2449,8 @@
       "src/eric7/WebBrowser/VirusTotal/VirusTotalIpReportDialog.py",
       "src/eric7/WebBrowser/VirusTotal/VirusTotalWhoisDialog.py",
       "src/eric7/WebBrowser/VirusTotal/__init__.py",
+      "src/eric7/WebBrowser/WebAuth/WebBrowserWebAuthDialog.py",
+      "src/eric7/WebBrowser/WebAuth/__init__.py",
       "src/eric7/WebBrowser/WebBrowserArgumentsCreator.py",
       "src/eric7/WebBrowser/WebBrowserClearPrivateDataDialog.py",
       "src/eric7/WebBrowser/WebBrowserJavaScriptConsole.py",
@@ -2459,7 +2461,6 @@
       "src/eric7/WebBrowser/WebBrowserTabBar.py",
       "src/eric7/WebBrowser/WebBrowserTabWidget.py",
       "src/eric7/WebBrowser/WebBrowserView.py",
-      "src/eric7/WebBrowser/WebBrowserWebAuthDialog.py",
       "src/eric7/WebBrowser/WebBrowserWebSearchWidget.py",
       "src/eric7/WebBrowser/WebBrowserWindow.py",
       "src/eric7/WebBrowser/WebInspector.py",
--- a/src/eric7/WebBrowser/Ui_WebBrowserWebAuthDialog.py	Tue Jul 16 19:47:54 2024 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-# Form implementation generated from reading ui file 'src/eric7/WebBrowser/WebBrowserWebAuthDialog.ui'
-#
-# Created by: PyQt6 UI code generator 6.7.0
-#
-# WARNING: Any manual changes made to this file will be lost when pyuic6 is
-# run again.  Do not edit this file unless you know what you are doing.
-
-
-from PyQt6 import QtCore, QtGui, QtWidgets
-
-
-class Ui_WebBrowserWebAuthDialog(object):
-    def setupUi(self, WebBrowserWebAuthDialog):
-        WebBrowserWebAuthDialog.setObjectName("WebBrowserWebAuthDialog")
-        WebBrowserWebAuthDialog.resize(500, 400)
-        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding)
-        sizePolicy.setHorizontalStretch(0)
-        sizePolicy.setVerticalStretch(0)
-        sizePolicy.setHeightForWidth(WebBrowserWebAuthDialog.sizePolicy().hasHeightForWidth())
-        WebBrowserWebAuthDialog.setSizePolicy(sizePolicy)
-        WebBrowserWebAuthDialog.setSizeGripEnabled(True)
-        self.verticalLayout = QtWidgets.QVBoxLayout(WebBrowserWebAuthDialog)
-        self.verticalLayout.setObjectName("verticalLayout")
-        self.headerLabel = QtWidgets.QLabel(parent=WebBrowserWebAuthDialog)
-        self.headerLabel.setText("Header")
-        self.headerLabel.setObjectName("headerLabel")
-        self.verticalLayout.addWidget(self.headerLabel)
-        self.descriptionLabel = QtWidgets.QLabel(parent=WebBrowserWebAuthDialog)
-        self.descriptionLabel.setText("Description")
-        self.descriptionLabel.setWordWrap(True)
-        self.descriptionLabel.setObjectName("descriptionLabel")
-        self.verticalLayout.addWidget(self.descriptionLabel)
-        self.pinGroupBox = QtWidgets.QGroupBox(parent=WebBrowserWebAuthDialog)
-        self.pinGroupBox.setFlat(True)
-        self.pinGroupBox.setObjectName("pinGroupBox")
-        self.gridLayout = QtWidgets.QGridLayout(self.pinGroupBox)
-        self.gridLayout.setObjectName("gridLayout")
-        self.pinLabel = QtWidgets.QLabel(parent=self.pinGroupBox)
-        self.pinLabel.setObjectName("pinLabel")
-        self.gridLayout.addWidget(self.pinLabel, 0, 0, 1, 1)
-        self.pinEdit = QtWidgets.QLineEdit(parent=self.pinGroupBox)
-        self.pinEdit.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
-        self.pinEdit.setObjectName("pinEdit")
-        self.gridLayout.addWidget(self.pinEdit, 0, 1, 1, 1)
-        self.pinButton = QtWidgets.QToolButton(parent=self.pinGroupBox)
-        self.pinButton.setCheckable(True)
-        self.pinButton.setObjectName("pinButton")
-        self.gridLayout.addWidget(self.pinButton, 0, 2, 1, 1)
-        self.confirmPinLabel = QtWidgets.QLabel(parent=self.pinGroupBox)
-        self.confirmPinLabel.setObjectName("confirmPinLabel")
-        self.gridLayout.addWidget(self.confirmPinLabel, 1, 0, 1, 1)
-        self.confirmPinEdit = QtWidgets.QLineEdit(parent=self.pinGroupBox)
-        self.confirmPinEdit.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
-        self.confirmPinEdit.setObjectName("confirmPinEdit")
-        self.gridLayout.addWidget(self.confirmPinEdit, 1, 1, 1, 1)
-        self.confirmPinErrorLabel = QtWidgets.QLabel(parent=self.pinGroupBox)
-        self.confirmPinErrorLabel.setObjectName("confirmPinErrorLabel")
-        self.gridLayout.addWidget(self.confirmPinErrorLabel, 2, 1, 1, 2)
-        self.pinErrorLabel = QtWidgets.QLabel(parent=self.pinGroupBox)
-        self.pinErrorLabel.setText("PIN Error")
-        self.pinErrorLabel.setWordWrap(True)
-        self.pinErrorLabel.setObjectName("pinErrorLabel")
-        self.gridLayout.addWidget(self.pinErrorLabel, 3, 0, 1, 3)
-        self.verticalLayout.addWidget(self.pinGroupBox)
-        self.selectAccountArea = QtWidgets.QScrollArea(parent=WebBrowserWebAuthDialog)
-        self.selectAccountArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
-        self.selectAccountArea.setObjectName("selectAccountArea")
-        self.selectAccountWidget = QtWidgets.QWidget()
-        self.selectAccountWidget.setGeometry(QtCore.QRect(0, 0, 450, 150))
-        self.selectAccountWidget.setObjectName("selectAccountWidget")
-        self.selectAccountArea.setWidget(self.selectAccountWidget)
-        self.verticalLayout.addWidget(self.selectAccountArea)
-        self.buttonBox = QtWidgets.QDialogButtonBox(parent=WebBrowserWebAuthDialog)
-        self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
-        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok|QtWidgets.QDialogButtonBox.StandardButton.Retry)
-        self.buttonBox.setObjectName("buttonBox")
-        self.verticalLayout.addWidget(self.buttonBox)
-
-        self.retranslateUi(WebBrowserWebAuthDialog)
-        QtCore.QMetaObject.connectSlotsByName(WebBrowserWebAuthDialog)
-        WebBrowserWebAuthDialog.setTabOrder(self.pinEdit, self.pinButton)
-        WebBrowserWebAuthDialog.setTabOrder(self.pinButton, self.confirmPinEdit)
-        WebBrowserWebAuthDialog.setTabOrder(self.confirmPinEdit, self.selectAccountArea)
-
-    def retranslateUi(self, WebBrowserWebAuthDialog):
-        _translate = QtCore.QCoreApplication.translate
-        WebBrowserWebAuthDialog.setWindowTitle(_translate("WebBrowserWebAuthDialog", "Web Authentication"))
-        self.pinLabel.setText(_translate("WebBrowserWebAuthDialog", "PIN:"))
-        self.pinEdit.setToolTip(_translate("WebBrowserWebAuthDialog", "Enter the PIN"))
-        self.pinButton.setToolTip(_translate("WebBrowserWebAuthDialog", "Press to show or hide the PIN."))
-        self.confirmPinLabel.setText(_translate("WebBrowserWebAuthDialog", "Confirm PIN:"))
-        self.confirmPinEdit.setToolTip(_translate("WebBrowserWebAuthDialog", "Enter the same PIN again."))
-        self.confirmPinErrorLabel.setText(_translate("WebBrowserWebAuthDialog", "PINs do not match!"))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/WebBrowser/WebAuth/Ui_WebBrowserWebAuthDialog.py	Wed Jul 17 16:48:46 2024 +0200
@@ -0,0 +1,93 @@
+# Form implementation generated from reading ui file 'src/eric7/WebBrowser/WebAuth/WebBrowserWebAuthDialog.ui'
+#
+# Created by: PyQt6 UI code generator 6.7.0
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
+# run again.  Do not edit this file unless you know what you are doing.
+
+
+from PyQt6 import QtCore, QtGui, QtWidgets
+
+
+class Ui_WebBrowserWebAuthDialog(object):
+    def setupUi(self, WebBrowserWebAuthDialog):
+        WebBrowserWebAuthDialog.setObjectName("WebBrowserWebAuthDialog")
+        WebBrowserWebAuthDialog.resize(500, 400)
+        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(WebBrowserWebAuthDialog.sizePolicy().hasHeightForWidth())
+        WebBrowserWebAuthDialog.setSizePolicy(sizePolicy)
+        WebBrowserWebAuthDialog.setSizeGripEnabled(True)
+        self.verticalLayout = QtWidgets.QVBoxLayout(WebBrowserWebAuthDialog)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.headerLabel = QtWidgets.QLabel(parent=WebBrowserWebAuthDialog)
+        self.headerLabel.setText("Header")
+        self.headerLabel.setObjectName("headerLabel")
+        self.verticalLayout.addWidget(self.headerLabel)
+        self.descriptionLabel = QtWidgets.QLabel(parent=WebBrowserWebAuthDialog)
+        self.descriptionLabel.setText("Description")
+        self.descriptionLabel.setWordWrap(True)
+        self.descriptionLabel.setObjectName("descriptionLabel")
+        self.verticalLayout.addWidget(self.descriptionLabel)
+        self.pinGroupBox = QtWidgets.QGroupBox(parent=WebBrowserWebAuthDialog)
+        self.pinGroupBox.setFlat(True)
+        self.pinGroupBox.setObjectName("pinGroupBox")
+        self.gridLayout = QtWidgets.QGridLayout(self.pinGroupBox)
+        self.gridLayout.setObjectName("gridLayout")
+        self.pinLabel = QtWidgets.QLabel(parent=self.pinGroupBox)
+        self.pinLabel.setObjectName("pinLabel")
+        self.gridLayout.addWidget(self.pinLabel, 0, 0, 1, 1)
+        self.pinEdit = QtWidgets.QLineEdit(parent=self.pinGroupBox)
+        self.pinEdit.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
+        self.pinEdit.setObjectName("pinEdit")
+        self.gridLayout.addWidget(self.pinEdit, 0, 1, 1, 1)
+        self.pinButton = QtWidgets.QToolButton(parent=self.pinGroupBox)
+        self.pinButton.setCheckable(True)
+        self.pinButton.setObjectName("pinButton")
+        self.gridLayout.addWidget(self.pinButton, 0, 2, 1, 1)
+        self.confirmPinLabel = QtWidgets.QLabel(parent=self.pinGroupBox)
+        self.confirmPinLabel.setObjectName("confirmPinLabel")
+        self.gridLayout.addWidget(self.confirmPinLabel, 1, 0, 1, 1)
+        self.confirmPinEdit = QtWidgets.QLineEdit(parent=self.pinGroupBox)
+        self.confirmPinEdit.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
+        self.confirmPinEdit.setObjectName("confirmPinEdit")
+        self.gridLayout.addWidget(self.confirmPinEdit, 1, 1, 1, 1)
+        self.confirmPinErrorLabel = QtWidgets.QLabel(parent=self.pinGroupBox)
+        self.confirmPinErrorLabel.setObjectName("confirmPinErrorLabel")
+        self.gridLayout.addWidget(self.confirmPinErrorLabel, 2, 1, 1, 2)
+        self.pinErrorLabel = QtWidgets.QLabel(parent=self.pinGroupBox)
+        self.pinErrorLabel.setText("PIN Error")
+        self.pinErrorLabel.setWordWrap(True)
+        self.pinErrorLabel.setObjectName("pinErrorLabel")
+        self.gridLayout.addWidget(self.pinErrorLabel, 3, 0, 1, 3)
+        self.verticalLayout.addWidget(self.pinGroupBox)
+        self.selectAccountArea = QtWidgets.QScrollArea(parent=WebBrowserWebAuthDialog)
+        self.selectAccountArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
+        self.selectAccountArea.setObjectName("selectAccountArea")
+        self.selectAccountWidget = QtWidgets.QWidget()
+        self.selectAccountWidget.setGeometry(QtCore.QRect(0, 0, 450, 150))
+        self.selectAccountWidget.setObjectName("selectAccountWidget")
+        self.selectAccountArea.setWidget(self.selectAccountWidget)
+        self.verticalLayout.addWidget(self.selectAccountArea)
+        self.buttonBox = QtWidgets.QDialogButtonBox(parent=WebBrowserWebAuthDialog)
+        self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
+        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok|QtWidgets.QDialogButtonBox.StandardButton.Retry)
+        self.buttonBox.setObjectName("buttonBox")
+        self.verticalLayout.addWidget(self.buttonBox)
+
+        self.retranslateUi(WebBrowserWebAuthDialog)
+        QtCore.QMetaObject.connectSlotsByName(WebBrowserWebAuthDialog)
+        WebBrowserWebAuthDialog.setTabOrder(self.pinEdit, self.pinButton)
+        WebBrowserWebAuthDialog.setTabOrder(self.pinButton, self.confirmPinEdit)
+        WebBrowserWebAuthDialog.setTabOrder(self.confirmPinEdit, self.selectAccountArea)
+
+    def retranslateUi(self, WebBrowserWebAuthDialog):
+        _translate = QtCore.QCoreApplication.translate
+        WebBrowserWebAuthDialog.setWindowTitle(_translate("WebBrowserWebAuthDialog", "Web Authentication"))
+        self.pinLabel.setText(_translate("WebBrowserWebAuthDialog", "PIN:"))
+        self.pinEdit.setToolTip(_translate("WebBrowserWebAuthDialog", "Enter the PIN"))
+        self.pinButton.setToolTip(_translate("WebBrowserWebAuthDialog", "Press to show or hide the PIN."))
+        self.confirmPinLabel.setText(_translate("WebBrowserWebAuthDialog", "Confirm PIN:"))
+        self.confirmPinEdit.setToolTip(_translate("WebBrowserWebAuthDialog", "Enter the same PIN again."))
+        self.confirmPinErrorLabel.setText(_translate("WebBrowserWebAuthDialog", "PINs do not match!"))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/WebBrowser/WebAuth/WebBrowserWebAuthDialog.py	Wed Jul 17 16:48:46 2024 +0200
@@ -0,0 +1,410 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+
+"""
+Module implementing a dialog to handle the various WebAuth requests.
+"""
+
+from PyQt6.QtCore import Qt, pyqtSlot
+from PyQt6.QtWebEngineCore import QWebEngineWebAuthUxRequest
+from PyQt6.QtWidgets import (
+    QButtonGroup,
+    QDialog,
+    QDialogButtonBox,
+    QLineEdit,
+    QRadioButton,
+    QSizePolicy,
+    QVBoxLayout,
+)
+
+from eric7.EricGui import EricPixmapCache
+
+from .Ui_WebBrowserWebAuthDialog import Ui_WebBrowserWebAuthDialog
+
+
+class WebBrowserWebAuthDialog(QDialog, Ui_WebBrowserWebAuthDialog):
+    """
+    Class implementing a dialog to handle the various WebAuth requests.
+    """
+
+    def __init__(self, uxRequest, parent=None):
+        """
+        Constructor
+
+        @param uxRequest reference to the WebAuth request object
+        @type QWebEngineWebAuthUxRequest
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        self.__uxRequest = uxRequest
+
+        self.pinButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+
+        self.selectAccountButtonGroup = QButtonGroup(self)
+        self.selectAccountButtonGroup.setExclusive(True)
+
+        self.selectAccountLayout = QVBoxLayout(self.selectAccountWidget)
+        self.selectAccountLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
+
+        self.buttonBox.accepted.connect(self.__acceptRequest)
+        self.buttonBox.rejected.connect(self.__cancelRequest)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).clicked.connect(
+            self.__retry
+        )
+
+        self.updateDialog()
+
+        self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Expanding)
+
+    @pyqtSlot(str)
+    def on_pinEdit_textEdited(self, pin):
+        """
+        Private slot handling entering a PIN.
+
+        @param pin entered PIN
+        @type str
+        """
+        self.confirmPinErrorLabel.setVisible(
+            self.confirmPinEdit.isVisible() and pin != self.confirmPinEdit.text()
+        )
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
+            (self.confirmPinEdit.isVisible() and pin == self.confirmPinEdit.text())
+            or not self.confirmPinEdit.isVisible()
+        )
+
+        self.adjustSize()
+
+    @pyqtSlot(bool)
+    def on_pinButton_toggled(self, checked):
+        """
+        Private slot to handle the toggling of the PIN visibility.
+
+        @param checked state of the PIN visibility button
+        @type bool
+        """
+        pinRequestInfo = self.__uxRequest.pinRequest()
+
+        if checked:
+            self.pinButton.setIcon(EricPixmapCache.getIcon("hidePassword"))
+            self.pinEdit.setEchoMode(QLineEdit.EchoMode.Normal)
+        else:
+            self.pinButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+            self.pinEdit.setEchoMode(QLineEdit.EchoMode.Password)
+
+        if pinRequestInfo.reason != QWebEngineWebAuthUxRequest.PinEntryReason.Challenge:
+            self.confirmPinLabel.setVisible(not checked)
+            self.confirmPinEdit.setVisible(not checked)
+            self.on_pinEdit_textEdited(self.pinEdit.text())
+
+    @pyqtSlot(str)
+    def on_confirmPinEdit_textEdited(self, pin):
+        """
+        Private slot handling entering of a confirmation PIN.
+
+        @param pin entered confirmation PIN
+        @type str
+        """
+        self.confirmPinErrorLabel.setVisible(pin != self.pinEdit.text())
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
+            pin == self.confirmPinEdit.text()
+        )
+
+        self.adjustSize()
+
+    @pyqtSlot()
+    def __acceptRequest(self):
+        """
+        Private slot to accept the WebAuth request.
+        """
+        requestState = self.__uxRequest.state()
+        if requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount:
+            checkedButton = self.selectAccountButtonGroup.checkedButton()
+            if checkedButton:
+                self.__uxRequest.setSelectedAccount(checkedButton.text())
+        elif requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.CollectPin:
+            self.__uxRequest.setPin(self.pinEdit.text())
+
+    @pyqtSlot()
+    def __cancelRequest(self):
+        """
+        Private slot to cancel the WebAuth request.
+        """
+        self.__uxRequest.cancel()
+
+    @pyqtSlot()
+    def __retry(self):
+        """
+        Private slot to retry the WebAuth request.
+        """
+        self.__uxRequest.retry()
+
+    @pyqtSlot()
+    def updateDialog(self):
+        """
+        Public slot to update the dialog depending on the current WebAuth request state.
+        """
+        requestState = self.__uxRequest.state()
+        if requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount:
+            self.__setupSelectAccountUi()
+        elif requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.CollectPin:
+            self.__setupCollectPinUi()
+        elif (
+            requestState
+            == QWebEngineWebAuthUxRequest.WebAuthUxState.FinishTokenCollection
+        ):
+            self.__setupFinishCollectTokenUi()
+        elif requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.RequestFailed:
+            self.__setupErrorUi()
+
+        self.adjustSize()
+
+    def __setupSelectAccountUi(self):
+        """
+        Private method to configure the 'Select Account' UI.
+        """
+        self.__clearSelectAccountButtons()
+
+        self.headerLabel.setText(self.tr("<b>Choose Passkey</b>"))
+        self.descriptionLabel.setText(
+            self.tr("Which passkey do you want to use for {0}?").format(
+                self.__uxRequest.relyingPartyId()
+            )
+        )
+        self.pinGroupBox.setVisible(False)
+
+        self.selectAccountArea.setVisible(True)
+        self.selectAccountWidget.resize(self.width(), self.height())
+        userNames = self.__uxRequest.userNames()
+        for name in sorted(userNames):
+            button = QRadioButton(name)
+            self.selectAccountLayout.addWidget(button)
+            self.selectAccountButtonGroup.addButton(button)
+        if len(userNames) == 1:
+            # nothing to select from, select the one and only button
+            self.selectAccountButtonGroup.buttons()[0].setChecked(True)
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(self.tr("Ok"))
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setVisible(True)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setVisible(True)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setVisible(False)
+
+        if len(userNames) > 1:
+            self.selectAccountButtonGroup.buttons()[0].setFocus(
+                Qt.FocusReason.OtherFocusReason
+            )
+        else:
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setFocus(
+                Qt.FocusReason.OtherFocusReason
+            )
+
+    def __setupCollectPinUi(self):
+        """
+        Private method to configure the 'Collect PIN' UI.
+        """
+        self.__clearSelectAccountButtons()
+
+        self.selectAccountArea.setVisible(False)
+
+        self.pinGroupBox.setVisible(True)
+        self.confirmPinLabel.setVisible(False)
+        self.confirmPinEdit.setVisible(False)
+        self.confirmPinErrorLabel.setVisible(False)
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(
+            self.tr("Next")
+        )
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setVisible(True)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setVisible(True)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setVisible(False)
+
+        pinRequestInfo = self.__uxRequest.pinRequest()
+        if pinRequestInfo.reason == QWebEngineWebAuthUxRequest.PinEntryReason.Challenge:
+            self.headerLabel.setText(self.tr("<b>PIN Required</b>"))
+            self.descriptionLabel.setText(
+                self.tr("Enter the PIN for your security key.")
+            )
+        else:
+            if pinRequestInfo.reason == QWebEngineWebAuthUxRequest.PinEntryReason.Set:
+                self.headerLabel.setText(self.tr("<b>New PIN Required</b>"))
+                self.descriptionLabel.setText(
+                    self.tr("Set new PIN for your security key.")
+                )
+            else:
+                self.headerLabel.setText(self.tr("<b>PIN Change Required</b>"))
+                self.descriptionLabel.setText(
+                    self.tr("Change the PIN for your security key.")
+                )
+            self.confirmPinLabel.setVisible(True)
+            self.confirmPinEdit.setVisible(True)
+
+        errorDetails = ""
+        if (
+            pinRequestInfo.error
+            == QWebEngineWebAuthUxRequest.PinEntryError.InternalUvLocked
+        ):
+            errorDetails = self.tr("Internal User Verification Locked!")
+        elif pinRequestInfo.error == QWebEngineWebAuthUxRequest.PinEntryError.WrongPin:
+            errorDetails = self.tr("Wrong PIN!")
+        elif pinRequestInfo.error == QWebEngineWebAuthUxRequest.PinEntryError.TooShort:
+            errorDetails = self.tr("PIN Too Short!")
+        elif (
+            pinRequestInfo.error
+            == QWebEngineWebAuthUxRequest.PinEntryError.InvalidCharacters
+        ):
+            errorDetails = self.tr("PIN Contains Invalid Characters!")
+        elif (
+            pinRequestInfo.error
+            == QWebEngineWebAuthUxRequest.PinEntryError.SameAsCurrentPin
+        ):
+            errorDetails = self.tr("New PIN is same as current PIN!")
+        if errorDetails:
+            errorDetails = self.tr(
+                "{0} %n attempt(s) remaining.", "", pinRequestInfo.remainingAttempts
+            ).format(errorDetails)
+        self.pinErrorLabel.setText(errorDetails)
+        self.pinErrorLabel.setVisible(bool(errorDetails))
+
+        self.pinEdit.setFocus(Qt.FocusReason.OtherFocusReason)
+
+    def __setupFinishCollectTokenUi(self):
+        """
+        Private method to configure the 'Finish Collect Token' UI.
+        """
+        self.__clearSelectAccountButtons()
+
+        self.headerLabel.setText(
+            self.tr("<b>Use your security key with {0}</b>").format(
+                self.__uxRequest.relyingPartyId()
+            )
+        )
+        self.descriptionLabel.setText(
+            self.tr("Touch your security key to complete the request.")
+        )
+
+        self.pinGroupBox.setVisible(False)
+        self.selectAccountArea.setVisible(False)
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setVisible(False)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setVisible(True)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setVisible(False)
+
+    def __setupErrorUi(self):
+        """
+        Private method to configure the 'Error' UI.
+        """
+        self.__clearSelectAccountButtons()
+
+        errorMsg = ""
+        retryVisible = False
+
+        requestFailureReason = self.__uxRequest.requestFailureReason()
+        if (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.Timeout
+        ):
+            errorMsg = self.tr("Request Timeout")
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.KeyNotRegistered
+        ):
+            errorMsg = self.tr("Security key is not registered.")
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.KeyAlreadyRegistered
+        ):
+            errorMsg = self.tr(
+                "You already registered this security key. Try again with another"
+                " security key."
+            )
+            retryVisible = True
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.SoftPinBlock
+        ):
+            errorMsg = self.tr(
+                "The security key is locked because the wrong PIN was entered too"
+                " many times. To unlock it, remove and reinsert it."
+            )
+            retryVisible = True
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.HardPinBlock
+        ):
+            errorMsg = self.tr(
+                "The security key is locked because the wrong PIN was entered too"
+                " many times. You will need to reset the security key."
+            )
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorRemovedDuringPinEntry  # noqa: E501
+        ):
+            errorMsg = self.tr(
+                "Security key removed during verification. Please reinsert and try"
+                " again."
+            )
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingResidentKeys  # noqa: E501
+        ):
+            errorMsg = self.tr("Security key does not have resident key support.")
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingUserVerification  # noqa: E501
+        ):
+            errorMsg = self.tr("Security key is missing user verification.")
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingLargeBlob  # noqa: E501
+        ):
+            errorMsg = self.tr("Security key is missing Large Blob support.")
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.NoCommonAlgorithms
+        ):
+            errorMsg = self.tr("Security key does not provide a common algorithm.")
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.StorageFull
+        ):
+            errorMsg = self.tr("No storage space left on the security key.")
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.UserConsentDenied
+        ):
+            errorMsg = self.tr("User consent denied.")
+        elif (
+            requestFailureReason
+            == QWebEngineWebAuthUxRequest.RequestFailureReason.WinUserCancelled
+        ):
+            errorMsg = self.tr("User canceled the WebAuth request.")
+
+        self.headerLabel.setText(self.tr("<b>Something went wrong</b>"))
+        self.descriptionLabel.setText(errorMsg)
+        self.descriptionLabel.adjustSize()
+
+        self.pinGroupBox.setVisible(False)
+        self.selectAccountArea.setVisible(False)
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setVisible(False)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setVisible(True)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(
+            self.tr("Close")
+        )
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setVisible(
+            retryVisible
+        )
+        if retryVisible:
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setFocus()
+
+    def __clearSelectAccountButtons(self):
+        """
+        Private method to remove the account selection buttons.
+        """
+        for button in self.selectAccountButtonGroup.buttons():
+            self.selectAccountLayout.removeWidget(button)
+            self.selectAccountButtonGroup.removeButton(button)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/WebBrowser/WebAuth/WebBrowserWebAuthDialog.ui	Wed Jul 17 16:48:46 2024 +0200
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WebBrowserWebAuthDialog</class>
+ <widget class="QDialog" name="WebBrowserWebAuthDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>500</width>
+    <height>400</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle">
+   <string>Web Authentication</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QLabel" name="headerLabel">
+     <property name="text">
+      <string notr="true">Header</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="descriptionLabel">
+     <property name="text">
+      <string notr="true">Description</string>
+     </property>
+     <property name="wordWrap">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="pinGroupBox">
+     <property name="flat">
+      <bool>true</bool>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="pinLabel">
+        <property name="text">
+         <string>PIN:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="pinEdit">
+        <property name="toolTip">
+         <string>Enter the PIN</string>
+        </property>
+        <property name="echoMode">
+         <enum>QLineEdit::Password</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <widget class="QToolButton" name="pinButton">
+        <property name="toolTip">
+         <string>Press to show or hide the PIN.</string>
+        </property>
+        <property name="checkable">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="confirmPinLabel">
+        <property name="text">
+         <string>Confirm PIN:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLineEdit" name="confirmPinEdit">
+        <property name="toolTip">
+         <string>Enter the same PIN again.</string>
+        </property>
+        <property name="echoMode">
+         <enum>QLineEdit::Password</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1" colspan="2">
+       <widget class="QLabel" name="confirmPinErrorLabel">
+        <property name="text">
+         <string>PINs do not match!</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0" colspan="3">
+       <widget class="QLabel" name="pinErrorLabel">
+        <property name="text">
+         <string notr="true">PIN Error</string>
+        </property>
+        <property name="wordWrap">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QScrollArea" name="selectAccountArea">
+     <property name="horizontalScrollBarPolicy">
+      <enum>Qt::ScrollBarAlwaysOff</enum>
+     </property>
+     <widget class="QWidget" name="selectAccountWidget">
+      <property name="geometry">
+       <rect>
+        <x>0</x>
+        <y>0</y>
+        <width>450</width>
+        <height>150</height>
+       </rect>
+      </property>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Retry</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>pinEdit</tabstop>
+  <tabstop>pinButton</tabstop>
+  <tabstop>confirmPinEdit</tabstop>
+  <tabstop>selectAccountArea</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/WebBrowser/WebAuth/__init__.py	Wed Jul 17 16:48:46 2024 +0200
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package implementing dialogs for the WebAuth flow and security key management.
+"""
--- a/src/eric7/WebBrowser/WebBrowserView.py	Tue Jul 16 19:47:54 2024 +0200
+++ b/src/eric7/WebBrowser/WebBrowserView.py	Wed Jul 17 16:48:46 2024 +0200
@@ -2688,7 +2688,7 @@
             @param authUxRequest reference to the WebAuth request object
             @type QWebEngineWebAuthUxRequest
             """
-            from .WebBrowserWebAuthDialog import WebBrowserWebAuthDialog
+            from .WebAuth.WebBrowserWebAuthDialog import WebBrowserWebAuthDialog
 
             if self.__webAuthDialog is not None:
                 del self.__webAuthDialog
@@ -2698,7 +2698,7 @@
             self.__webAuthDialog.setModal(False)
             self.__webAuthDialog.setWindowFlags(
                 self.__webAuthDialog.windowFlags()
-                & Qt.WindowType.WindowContextHelpButtonHint
+                & ~Qt.WindowType.WindowContextHelpButtonHint
             )
 
             authUxRequest.stateChanged.connect(self.__webAuthUxRequestStateChanged)
--- a/src/eric7/WebBrowser/WebBrowserWebAuthDialog.py	Tue Jul 16 19:47:54 2024 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-
-"""
-Module implementing a dialog to handle the various WebAuth requests.
-"""
-
-from PyQt6.QtCore import Qt, pyqtSlot
-from PyQt6.QtWebEngineCore import QWebEngineWebAuthUxRequest
-from PyQt6.QtWidgets import (
-    QButtonGroup,
-    QDialog,
-    QDialogButtonBox,
-    QLineEdit,
-    QRadioButton,
-    QSizePolicy,
-    QVBoxLayout,
-)
-
-from eric7.EricGui import EricPixmapCache
-
-from .Ui_WebBrowserWebAuthDialog import Ui_WebBrowserWebAuthDialog
-
-
-class WebBrowserWebAuthDialog(QDialog, Ui_WebBrowserWebAuthDialog):
-    """
-    Class implementing a dialog to handle the various WebAuth requests.
-    """
-
-    def __init__(self, uxRequest, parent=None):
-        """
-        Constructor
-
-        @param uxRequest reference to the WebAuth request object
-        @type QWebEngineWebAuthUxRequest
-        @param parent reference to the parent widget (defaults to None)
-        @type QWidget (optional)
-        """
-        super().__init__(parent)
-        self.setupUi(self)
-
-        self.__uxRequest = uxRequest
-
-        self.pinButton.setIcon(EricPixmapCache.getIcon("showPassword"))
-
-        self.selectAccountButtonGroup = QButtonGroup(self)
-        self.selectAccountButtonGroup.setExclusive(True)
-
-        self.selectAccountLayout = QVBoxLayout(self.selectAccountWidget)
-        self.selectAccountLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
-
-        self.buttonBox.accepted.connect(self.__acceptRequest)
-        self.buttonBox.rejected.connect(self.__cancelRequest)
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).clicked.connect(
-            self.__retry
-        )
-
-        self.updateDialog()
-
-        self.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Expanding)
-
-    @pyqtSlot(str)
-    def on_pinEdit_textEdited(self, pin):
-        """
-        Private slot handling entering a PIN.
-
-        @param pin entered PIN
-        @type str
-        """
-        self.confirmPinErrorLabel.setVisible(
-            self.confirmPinEdit.isVisible() and pin != self.confirmPinEdit.text()
-        )
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-            (self.confirmPinEdit.isVisible() and pin == self.confirmPinEdit.text())
-            or not self.confirmPinEdit.isVisible()
-        )
-
-    @pyqtSlot(bool)
-    def on_pinButton_toggled(self, checked):
-        """
-        Private slot to handle the toggling of the PIN visibility.
-
-        @param checked state of the PIN visibility button
-        @type bool
-        """
-        pinRequestInfo = self.__uxRequest.pinRequest()
-
-        if checked:
-            self.pinButton.setIcon(EricPixmapCache.getIcon("hidePassword"))
-            self.pinEdit.setEchoMode(QLineEdit.EchoMode.Normal)
-        else:
-            self.pinButton.setIcon(EricPixmapCache.getIcon("showPassword"))
-            self.pinEdit.setEchoMode(QLineEdit.EchoMode.Password)
-
-        if pinRequestInfo.reason != QWebEngineWebAuthUxRequest.PinEntryReason.Challenge:
-            self.confirmPinLabel.setVisible(not checked)
-            self.confirmPinEdit.setVisible(not checked)
-            self.on_pinEdit_textEdited(self.pinEdit.text())
-
-    @pyqtSlot(str)
-    def on_confirmPinEdit_textEdited(self, pin):
-        """
-        Private slot handling entering of a confirmation PIN.
-
-        @param pin entered confirmation PIN
-        @type str
-        """
-        self.confirmPinErrorLabel.setVisible(pin != self.pinEdit.text())
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
-            pin == self.confirmPinEdit.text()
-        )
-
-    @pyqtSlot()
-    def __acceptRequest(self):
-        """
-        Private slot to accept the WebAuth request.
-        """
-        requestState = self.__uxRequest.state()
-        if requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount:
-            checkedButton = self.selectAccountButtonGroup.checkedButton()
-            if checkedButton:
-                self.__uxRequest.setSelectedAccount(checkedButton.text())
-        elif requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.CollectPin:
-            self.__uxRequest.setPin(self.pinEdit.text())
-
-    @pyqtSlot()
-    def __cancelRequest(self):
-        """
-        Private slot to cancel the WebAuth request.
-        """
-        self.__uxRequest.cancel()
-
-    @pyqtSlot()
-    def __retry(self):
-        """
-        Private slot to retry the WebAuth request.
-        """
-        self.__uxRequest.retry()
-
-    @pyqtSlot()
-    def updateDialog(self):
-        """
-        Public slot to update the dialog depending on the current WebAuth request state.
-        """
-        requestState = self.__uxRequest.state()
-        if requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.SelectAccount:
-            self.__setupSelectAccountUi()
-        elif requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.CollectPin:
-            self.__setupCollectPinUi()
-        elif (
-            requestState
-            == QWebEngineWebAuthUxRequest.WebAuthUxState.FinishTokenCollection
-        ):
-            self.__setupFinishCollectTokenUi()
-        elif requestState == QWebEngineWebAuthUxRequest.WebAuthUxState.RequestFailed:
-            self.__setupErrorUi()
-
-        self.adjustSize()
-
-    def __setupSelectAccountUi(self):
-        """
-        Private method to configure the 'Select Account' UI.
-        """
-        self.__clearSelectAccountButtons()
-
-        self.headerLabel.setText(self.tr("<b>Choose Passkey</b>"))
-        self.descriptionLabel.setText(
-            self.tr("Which passkey do you want to use for {0}?").format(
-                self.__uxRequest.relyingPartyId()
-            )
-        )
-        self.pinGroupBox.setVisible(False)
-
-        self.selectAccountArea.setVisible(True)
-        self.selectAccountWidget.resize(self.width(), self.height())
-        userNames = self.__uxRequest.userNames()
-        for name in sorted(userNames):
-            button = QRadioButton(name)
-            self.selectAccountLayout.addWidget(button)
-            self.selectAccountButtonGroup.addButton(button)
-        if len(userNames) == 1:
-            # nothing to select from, select the one and only button
-            self.selectAccountButtonGroup.buttons()[0].setChecked(True)
-
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(self.tr("Ok"))
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setVisible(True)
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setVisible(True)
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setVisible(False)
-
-    def __setupCollectPinUi(self):
-        """
-        Private method to configure the 'Collect PIN' UI.
-        """
-        self.__clearSelectAccountButtons()
-
-        self.selectAccountArea.setVisible(False)
-
-        self.pinGroupBox.setVisible(True)
-        self.confirmPinLabel.setVisible(False)
-        self.confirmPinEdit.setVisible(False)
-        self.confirmPinErrorLabel.setVisible(False)
-
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText(
-            self.tr("Next")
-        )
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setVisible(True)
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setVisible(True)
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setVisible(False)
-
-        pinRequestInfo = self.__uxRequest.pinRequest()
-        if pinRequestInfo.reason == QWebEngineWebAuthUxRequest.PinEntryReason.Challenge:
-            self.headerLabel.setText(self.tr("<b>PIN Required</b>"))
-            self.descriptionLabel.setText(
-                self.tr("Enter the PIN for your security key.")
-            )
-        else:
-            if pinRequestInfo.reason == QWebEngineWebAuthUxRequest.PinEntryReason.Set:
-                self.headerLabel.setText(self.tr("<b>New PIN Required</b>"))
-                self.descriptionLabel.setText(
-                    self.tr("Set new PIN for your security key.")
-                )
-            else:
-                self.headerLabel.setText(self.tr("<b>PIN Change Required</b>"))
-                self.descriptionLabel.setText(
-                    self.tr("Change the PIN for your security key.")
-                )
-            self.confirmPinLabel.setVisible(True)
-            self.confirmPinEdit.setVisible(True)
-
-        errorDetails = ""
-        if (
-            pinRequestInfo.error
-            == QWebEngineWebAuthUxRequest.PinEntryError.InternalUvLocked
-        ):
-            errorDetails = self.tr("Internal User Verification Locked!")
-        elif pinRequestInfo.error == QWebEngineWebAuthUxRequest.PinEntryError.WrongPin:
-            errorDetails = self.tr("Wrong PIN!")
-        elif pinRequestInfo.error == QWebEngineWebAuthUxRequest.PinEntryError.TooShort:
-            errorDetails = self.tr("PIN Too Short!")
-        elif (
-            pinRequestInfo.error
-            == QWebEngineWebAuthUxRequest.PinEntryError.InvalidCharacters
-        ):
-            errorDetails = self.tr("PIN Contains Invalid Characters!")
-        elif (
-            pinRequestInfo.error
-            == QWebEngineWebAuthUxRequest.PinEntryError.SameAsCurrentPin
-        ):
-            errorDetails = self.tr("New PIN is same as current PIN!")
-        if errorDetails:
-            errorDetails = self.tr(
-                "{0} %n attempt(s) remaining.", "", pinRequestInfo.remainingAttempts
-            ).format(errorDetails)
-        self.pinErrorLabel.setText(errorDetails)
-
-    def __setupFinishCollectTokenUi(self):
-        """
-        Private method to configure the 'Finish Collect Token' UI.
-        """
-        self.__clearSelectAccountButtons()
-
-        self.headerLabel.setText(
-            self.tr("<b>Use your security key with {0}</b>").format(
-                self.__uxRequest.relyingPartyId()
-            )
-        )
-        self.descriptionLabel.setText(
-            self.tr("Touch your security key to complete the request.")
-        )
-        self.pinGroupBox.setVisible(False)
-
-        self.selectAccountArea.setVisible(False)
-
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setVisible(False)
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setVisible(True)
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setVisible(False)
-
-    def __setupErrorUi(self):
-        """
-        Private method to configure the 'Error' UI.
-        """
-        self.__clearSelectAccountButtons()
-
-        errorMsg = ""
-        retryVisible = False
-
-        requestFailureReason = self.__uxRequest.requestFailureReason()
-        if (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.Timeout
-        ):
-            errorMsg = self.tr("Request Timeout")
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.KeyNotRegistered
-        ):
-            errorMsg = self.tr("Security key is not registered.")
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.KeyAlreadyRegistered
-        ):
-            errorMsg = self.tr(
-                "You already registered this security key. Try again with another"
-                " security key."
-            )
-            retryVisible = True
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.SoftPinBlock
-        ):
-            errorMsg = self.tr(
-                "The security key is locked because the wrong PIN was entered too"
-                " many times. To unlock it, remove and reinsert it."
-            )
-            retryVisible = True
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.HardPinBlock
-        ):
-            errorMsg = self.tr(
-                "The security key is locked because the wrong PIN was entered too"
-                " many times. You will need to reset the security key."
-            )
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorRemovedDuringPinEntry  # noqa: E501
-        ):
-            errorMsg = self.tr(
-                "Security key removed during verification. Please reinsert and try"
-                " again."
-            )
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingResidentKeys  # noqa: E501
-        ):
-            errorMsg = self.tr("Security key does not have resident key support.")
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingUserVerification  # noqa: E501
-        ):
-            errorMsg = self.tr("Security key is missing user verification.")
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.AuthenticatorMissingLargeBlob  # noqa: E501
-        ):
-            errorMsg = self.tr("Security key is missing Large Blob support.")
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.NoCommonAlgorithms
-        ):
-            errorMsg = self.tr("Security key does not provide a common algorithm.")
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.StorageFull
-        ):
-            errorMsg = self.tr("No storage space left on the security key.")
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.UserConsentDenied
-        ):
-            errorMsg = self.tr("User consent denied.")
-        elif (
-            requestFailureReason
-            == QWebEngineWebAuthUxRequest.RequestFailureReason.WinUserCancelled
-        ):
-            errorMsg = self.tr("User canceled the WebAuth request.")
-
-        self.headerLabel.setText(self.tr("<b>Something went wrong</b>"))
-        self.descriptionLabel.setText(errorMsg)
-        self.descriptionLabel.adjustSize()
-
-        self.pinGroupBox.setVisible(False)
-        self.selectAccountArea.setVisible(False)
-
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setVisible(False)
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setVisible(True)
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setText(
-            self.tr("Close")
-        )
-        self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setVisible(
-            retryVisible
-        )
-        if retryVisible:
-            self.buttonBox.button(QDialogButtonBox.StandardButton.Retry).setFocus()
-
-    def __clearSelectAccountButtons(self):
-        """
-        Private method to remove the account selection buttons.
-        """
-        for button in self.selectAccountButtonGroup.buttons():
-            self.selectAccountLayout.removeWidget(button)
-            self.selectAccountButtonGroup.removeButton(button)
--- a/src/eric7/WebBrowser/WebBrowserWebAuthDialog.ui	Tue Jul 16 19:47:54 2024 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>WebBrowserWebAuthDialog</class>
- <widget class="QDialog" name="WebBrowserWebAuthDialog">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>500</width>
-    <height>400</height>
-   </rect>
-  </property>
-  <property name="sizePolicy">
-   <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
-    <horstretch>0</horstretch>
-    <verstretch>0</verstretch>
-   </sizepolicy>
-  </property>
-  <property name="windowTitle">
-   <string>Web Authentication</string>
-  </property>
-  <property name="sizeGripEnabled">
-   <bool>true</bool>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <widget class="QLabel" name="headerLabel">
-     <property name="text">
-      <string notr="true">Header</string>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QLabel" name="descriptionLabel">
-     <property name="text">
-      <string notr="true">Description</string>
-     </property>
-     <property name="wordWrap">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="pinGroupBox">
-     <property name="flat">
-      <bool>true</bool>
-     </property>
-     <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="0">
-       <widget class="QLabel" name="pinLabel">
-        <property name="text">
-         <string>PIN:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLineEdit" name="pinEdit">
-        <property name="toolTip">
-         <string>Enter the PIN</string>
-        </property>
-        <property name="echoMode">
-         <enum>QLineEdit::Password</enum>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="2">
-       <widget class="QToolButton" name="pinButton">
-        <property name="toolTip">
-         <string>Press to show or hide the PIN.</string>
-        </property>
-        <property name="checkable">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="confirmPinLabel">
-        <property name="text">
-         <string>Confirm PIN:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QLineEdit" name="confirmPinEdit">
-        <property name="toolTip">
-         <string>Enter the same PIN again.</string>
-        </property>
-        <property name="echoMode">
-         <enum>QLineEdit::Password</enum>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1" colspan="2">
-       <widget class="QLabel" name="confirmPinErrorLabel">
-        <property name="text">
-         <string>PINs do not match!</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="0" colspan="3">
-       <widget class="QLabel" name="pinErrorLabel">
-        <property name="text">
-         <string notr="true">PIN Error</string>
-        </property>
-        <property name="wordWrap">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QScrollArea" name="selectAccountArea">
-     <property name="horizontalScrollBarPolicy">
-      <enum>Qt::ScrollBarAlwaysOff</enum>
-     </property>
-     <widget class="QWidget" name="selectAccountWidget">
-      <property name="geometry">
-       <rect>
-        <x>0</x>
-        <y>0</y>
-        <width>450</width>
-        <height>150</height>
-       </rect>
-      </property>
-     </widget>
-    </widget>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Retry</set>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <tabstops>
-  <tabstop>pinEdit</tabstop>
-  <tabstop>pinButton</tabstop>
-  <tabstop>confirmPinEdit</tabstop>
-  <tabstop>selectAccountArea</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>

eric ide

mercurial