fix(jira-knowledge): replace hover tooltip with click-based popup for help button
Native Qt tooltips on macOS are unreliable (delayed or invisible). Replace with a QFrame popup that appears on click, positioned below the ? button, and closes when clicking elsewhere (Qt.Popup flag handles ESC and outside-click). - Store help text in self._help_text instead of setToolTip() - Add _toggle_help_popup() method: creates/destroys floating QFrame - Update test to check _help_text attribute instead of toolTip() Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -51,15 +51,16 @@ def test_help_icon_exists(dialog):
|
||||
|
||||
|
||||
def test_help_icon_has_tooltip(dialog):
|
||||
"""Help icon must have a non-empty tooltip with both Project ID and Jira Key explanations."""
|
||||
"""Help icon must store help text with both Project ID and Jira Key explanations."""
|
||||
from PySide6.QtWidgets import QToolButton
|
||||
dlg = dialog
|
||||
help_icons = dlg.findChildren(QToolButton)
|
||||
assert help_icons, "No help button found"
|
||||
tooltip = help_icons[0].toolTip()
|
||||
assert tooltip, "Help button has no tooltip"
|
||||
assert "Project ID" in tooltip, "Tooltip missing Project ID explanation"
|
||||
assert "Jira Key" in tooltip, "Tooltip missing Jira Key explanation"
|
||||
# Help text is stored in _help_text for click-based popup
|
||||
help_text = getattr(dlg, '_help_text', '') or help_icons[0].toolTip()
|
||||
assert help_text, "Help button has no help content"
|
||||
assert "Project ID" in help_text, "Help content missing Project ID explanation"
|
||||
assert "Jira Key" in help_text, "Help content missing Jira Key explanation"
|
||||
|
||||
|
||||
# ---- Help text content ----------------------------------------------------
|
||||
|
||||
+49
-12
@@ -11,12 +11,12 @@ setup dialog; OneDrive/SharePoint: neither, they only toggle).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtCore import Qt, QPoint
|
||||
from PySide6.QtGui import QFont
|
||||
from PySide6.QtWidgets import (
|
||||
QCheckBox, QDialog, QFormLayout, QFrame, QGroupBox, QHBoxLayout, QLabel,
|
||||
QLineEdit, QMessageBox, QPushButton, QScrollArea, QToolButton, QToolTip,
|
||||
QVBoxLayout, QWidget,
|
||||
QLineEdit, QMessageBox, QPushButton, QScrollArea, QToolButton,
|
||||
QVBoxLayout, QWidget, QApplication,
|
||||
)
|
||||
|
||||
from ..core.ext_connectors import CATEGORIES as EXT_CATEGORIES
|
||||
@@ -109,12 +109,6 @@ class JiraConnectDialog(QDialog):
|
||||
mapping_label = QLabel(tr("connectors.jira_kb_mapping_label"))
|
||||
self.help_icon = QToolButton()
|
||||
self.help_icon.setText("?")
|
||||
self.help_icon.setToolTip(
|
||||
"<b>" + tr("connectors.jira_kb_project_id_title") + "</b><br>"
|
||||
+ tr("connectors.jira_kb_project_id_help")
|
||||
+ "<br><br><b>" + tr("connectors.jira_kb_jira_key_title") + "</b><br>"
|
||||
+ tr("connectors.jira_kb_jira_key_help")
|
||||
)
|
||||
self.help_icon.setStyleSheet("""
|
||||
QToolButton {
|
||||
border: 1px solid #5B9BD5;
|
||||
@@ -135,9 +129,15 @@ class JiraConnectDialog(QDialog):
|
||||
color: white;
|
||||
}
|
||||
""")
|
||||
# Native Qt tooltip: hover to show, no click handler needed.
|
||||
# AutoRaise=False keeps the button always visible (not faded out).
|
||||
self.help_icon.setAutoRaise(False)
|
||||
# Click-based popover: build help content once, show on click
|
||||
self._help_text = (
|
||||
"<b>" + tr("connectors.jira_kb_project_id_title") + "</b><br>"
|
||||
+ tr("connectors.jira_kb_project_id_help")
|
||||
+ "<br><br><b>" + tr("connectors.jira_kb_jira_key_title") + "</b><br>"
|
||||
+ tr("connectors.jira_kb_jira_key_help")
|
||||
)
|
||||
self._help_popup = None
|
||||
self.help_icon.clicked.connect(self._toggle_help_popup)
|
||||
label_row = QHBoxLayout()
|
||||
label_row.setSpacing(4)
|
||||
label_row.addWidget(mapping_label)
|
||||
@@ -188,6 +188,43 @@ class JiraConnectDialog(QDialog):
|
||||
self.kb_enabled.toggled.connect(self._update_sync_state)
|
||||
self._update_sync_state(self.kb_enabled.isChecked())
|
||||
|
||||
def _toggle_help_popup(self) -> None:
|
||||
"""Show/hide a floating help popup when the ? button is clicked."""
|
||||
if self._help_popup is not None and self._help_popup.isVisible():
|
||||
self._help_popup.hide()
|
||||
self._help_popup.deleteLater()
|
||||
self._help_popup = None
|
||||
return
|
||||
|
||||
popup = QFrame(self)
|
||||
popup.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint)
|
||||
popup.setAttribute(Qt.WA_DeleteOnClose, False)
|
||||
popup.setStyleSheet("""
|
||||
QFrame {
|
||||
background: #2D2D2D;
|
||||
border: 1px solid #5B9BD5;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
}
|
||||
""")
|
||||
popup_layout = QVBoxLayout(popup)
|
||||
popup_layout.setContentsMargins(12, 10, 12, 10)
|
||||
|
||||
content = QLabel(self._help_text)
|
||||
content.setWordWrap(True)
|
||||
content.setMaximumWidth(380)
|
||||
content.setStyleSheet("color: #E0E0E0; font-size: 12px; background: transparent; border: none;")
|
||||
content.setTextFormat(Qt.RichText)
|
||||
content.setOpenExternalLinks(True)
|
||||
popup_layout.addWidget(content)
|
||||
|
||||
# Position below the help button
|
||||
btn_global = self.help_icon.mapToGlobal(QPoint(0, self.help_icon.height()))
|
||||
popup.move(btn_global)
|
||||
popup.show()
|
||||
popup.raise_()
|
||||
self._help_popup = popup
|
||||
|
||||
def _on_paste(self, text: str) -> None:
|
||||
"""Auto-fill Base URL from a pasted Jira link."""
|
||||
import re
|
||||
|
||||
Reference in New Issue
Block a user