feat: merge Automation progress and Console log into one Information dock
The two tabified bottom docks left their switcher tabs stranded at the window bottom; one Information dock with proper tabs mirrors the Sample List dock's layout. LogDock becomes the LogPanel widget with mirror views for the pop-out and a reveal_requested signal so the owner controls visibility (Ctrl+Shift+L, notifications). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+87
-55
@@ -78,7 +78,7 @@ from aare.gui.panels.fluorescence_panel import FluorescencePanel
|
||||
from aare.gui.panels.local_contact_panel import LocalContactDialog
|
||||
|
||||
# panels
|
||||
from aare.gui.panels.log_panel import LogDock
|
||||
from aare.gui.panels.log_panel import LogPanel
|
||||
from aare.gui.panels.monochromator_panel import MonochromatorPanel
|
||||
from aare.gui.panels.portrait_mode import PortraitModePanel
|
||||
from aare.gui.panels.prediction_metrics_panel import PredictionMetricsPanel
|
||||
@@ -611,21 +611,46 @@ class MainWindow(QMainWindow):
|
||||
self.manual_sample_panel = self.data_collection.manual_sample_panel
|
||||
|
||||
self.automation_progress_panel = AutomationProgressWidget()
|
||||
self.automation_progress_dock = QDockWidget("Automation progress", self)
|
||||
self.automation_progress_dock.setObjectName("automation_progress_dock")
|
||||
# Scroll host: the panel's ~420px minimum otherwise dictates the whole
|
||||
# bottom row's height and squeezes the Beamline column into a scrollbar.
|
||||
automation_scroll = NoWheelScrollArea(self.automation_progress_dock)
|
||||
automation_scroll = NoWheelScrollArea()
|
||||
automation_scroll.setWidget(self.automation_progress_panel)
|
||||
automation_scroll.setWidgetResizable(True)
|
||||
automation_scroll.setFrameShape(QFrame.Shape.NoFrame)
|
||||
self.automation_progress_dock.setWidget(automation_scroll)
|
||||
self.automation_progress_dock.setAllowedAreas(Qt.DockWidgetArea.BottomDockWidgetArea)
|
||||
self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, self.automation_progress_dock)
|
||||
# Same title-bar icons (⤢ pop-out + ✕) as Sample List / Console Log.
|
||||
self._automation_popout: PopoutWindow | None = None
|
||||
self.automation_progress_dock.setTitleBarWidget(
|
||||
DockTitleBar(self.automation_progress_dock, self._open_automation_popout)
|
||||
|
||||
# One "Information" dock with Automation progress + Console log tabs,
|
||||
# mirroring the Sample List dock's Dewar/Auxiliary layout — replaces
|
||||
# the two tabified docks whose switcher tabs sat at the window bottom.
|
||||
self.log_panel = LogPanel()
|
||||
self.log_panel.attach_logger("")
|
||||
self.log_panel.attach_logger("aareGUI")
|
||||
self.log_panel.reveal_requested.connect(self._reveal_console_log)
|
||||
|
||||
self.information_tabs = QTabWidget()
|
||||
self.information_tabs.addTab(automation_scroll, "Automation progress")
|
||||
self.information_tabs.addTab(self.log_panel, "Console log")
|
||||
|
||||
# Same wrapper trick as the Sample List dock: QTabWidget ignores its
|
||||
# own contents margins for the tab bar, so the inset lives one level up.
|
||||
information_wrap = QWidget()
|
||||
information_wrap_layout = QVBoxLayout(information_wrap)
|
||||
information_wrap_layout.setContentsMargins(DOCK_CONTENT_LEFT_PAD, 0, 0, 0)
|
||||
information_wrap_layout.setSpacing(0)
|
||||
information_wrap_layout.addWidget(self.information_tabs)
|
||||
|
||||
self.information_dock = QDockWidget("Information", self)
|
||||
self.information_dock.setObjectName("information_dock")
|
||||
self.information_dock.setWidget(information_wrap)
|
||||
self.information_dock.setAllowedAreas(Qt.DockWidgetArea.BottomDockWidgetArea)
|
||||
self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, self.information_dock)
|
||||
self.information_dock.setFeatures(
|
||||
QDockWidget.DockWidgetFeature.DockWidgetMovable
|
||||
| QDockWidget.DockWidgetFeature.DockWidgetClosable
|
||||
)
|
||||
# Same title-bar icons (⤢ pop-out + ✕) as Sample List.
|
||||
self._information_popout: PopoutWindow | None = None
|
||||
self.information_dock.setTitleBarWidget(
|
||||
DockTitleBar(self.information_dock, self._open_information_popout)
|
||||
)
|
||||
|
||||
self.face_panel = FaceDetectionPanel()
|
||||
@@ -650,15 +675,6 @@ class MainWindow(QMainWindow):
|
||||
self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, self.fluor_panel_dock)
|
||||
self.fluor_panel_dock.hide()
|
||||
|
||||
self.log_dock = LogDock("Console Log", self)
|
||||
self.log_dock.setObjectName("log_dock")
|
||||
self.addDockWidget(Qt.BottomDockWidgetArea, self.log_dock)
|
||||
self.log_dock.attach_logger("")
|
||||
self.log_dock.attach_logger("aareGUI")
|
||||
self.log_dock.hide()
|
||||
|
||||
self.tabifyDockWidget(self.automation_progress_dock, self.log_dock)
|
||||
|
||||
self.job_list_panel.samples_in_queue_changed.connect(
|
||||
self.automation_progress_panel.set_samples_in_queue
|
||||
)
|
||||
@@ -788,11 +804,11 @@ class MainWindow(QMainWindow):
|
||||
# the default-state capture so "reset layout" gets it too; a saved
|
||||
# user layout (restored below) still wins.
|
||||
self.resizeDocks(
|
||||
[self.tell_samples_dock, self.log_dock], [240, 240], Qt.Orientation.Vertical
|
||||
[self.tell_samples_dock, self.information_dock], [240, 240], Qt.Orientation.Vertical
|
||||
)
|
||||
# Equal oversized requests -> Qt distributes proportionally = 50/50.
|
||||
self.resizeDocks(
|
||||
[self.tell_samples_dock, self.automation_progress_dock],
|
||||
[self.tell_samples_dock, self.information_dock],
|
||||
[10000, 10000],
|
||||
Qt.Orientation.Horizontal,
|
||||
)
|
||||
@@ -1200,11 +1216,9 @@ class MainWindow(QMainWindow):
|
||||
)
|
||||
self.addAction(self._shortcut_toggle_smargon_trace)
|
||||
|
||||
self._shortcut_console_log = QAction("Toggle Console Log", self)
|
||||
self._shortcut_console_log = QAction("Show Console log", self)
|
||||
self._shortcut_console_log.setShortcut(QKeySequence("Ctrl+Shift+L"))
|
||||
self._shortcut_console_log.triggered.connect(
|
||||
lambda: (self.log_dock.setVisible(True), self.log_dock.raise_())
|
||||
)
|
||||
self._shortcut_console_log.triggered.connect(self._reveal_console_log)
|
||||
self.addAction(self._shortcut_console_log)
|
||||
|
||||
@Slot()
|
||||
@@ -1278,20 +1292,33 @@ class MainWindow(QMainWindow):
|
||||
self._sample_popout.raise_()
|
||||
self._sample_popout.activateWindow()
|
||||
|
||||
def _open_automation_popout(self) -> None:
|
||||
if self._automation_popout is None:
|
||||
# Mirror wired to the same feeds as the docked panel.
|
||||
def _open_information_popout(self) -> None:
|
||||
if self._information_popout is None:
|
||||
# Automation mirror wired to the same feeds as the docked panel.
|
||||
panel = AutomationProgressWidget()
|
||||
self.job_list_panel.samples_in_queue_changed.connect(panel.set_samples_in_queue)
|
||||
self.job_list_panel.automation_running_changed.connect(panel.set_running)
|
||||
self.daq.automation_progress.connect(panel.set_progress)
|
||||
panel.set_samples_in_queue(len(self.job_list_panel.table_model.samples))
|
||||
panel.set_running(self.job_list_panel.is_running())
|
||||
self._automation_popout = PopoutWindow("Automation progress", panel, parent=self)
|
||||
self._automation_popout.resize(420, 520)
|
||||
self._automation_popout.show()
|
||||
self._automation_popout.raise_()
|
||||
self._automation_popout.activateWindow()
|
||||
|
||||
tabs = QTabWidget()
|
||||
tabs.addTab(panel, "Automation progress")
|
||||
tabs.addTab(self.log_panel.make_mirror_view(), "Console log")
|
||||
self._information_popout = PopoutWindow("Information", tabs, parent=self)
|
||||
self._information_popout.resize(1000, 520)
|
||||
self._information_popout.show()
|
||||
self._information_popout.raise_()
|
||||
self._information_popout.activateWindow()
|
||||
|
||||
@Slot()
|
||||
def _reveal_console_log(self) -> None:
|
||||
"""Show the Information dock with the Console log tab on top — the
|
||||
one entry point for 'the user must see the log now' (notifications,
|
||||
Ctrl+Shift+L)."""
|
||||
self.information_dock.setVisible(True)
|
||||
self.information_dock.raise_()
|
||||
self.information_tabs.setCurrentWidget(self.log_panel)
|
||||
|
||||
def _clone_automation_row(self, dewar_panel: TellSamplePanel) -> QHBoxLayout:
|
||||
"""Pop-out copy of the automation controls, driving the same queue
|
||||
@@ -1520,13 +1547,12 @@ class MainWindow(QMainWindow):
|
||||
self._pre_automation_right_column_visible = self.beamline_controls_scroll.isVisible()
|
||||
|
||||
self.tell_samples_dock.setVisible(False)
|
||||
self.automation_progress_dock.setVisible(False)
|
||||
self.information_dock.setVisible(False)
|
||||
self.face_panel_dock.setVisible(False)
|
||||
self.fluor_panel_dock.setVisible(False)
|
||||
self.smargon_trace_dock.setVisible(False)
|
||||
self.target_stability_dock.setVisible(False)
|
||||
self.prediction_metrics_dock.setVisible(False)
|
||||
self.log_dock.setVisible(False)
|
||||
|
||||
self.collection_controls_scroll.setVisible(False)
|
||||
self.beamline_controls_scroll.setVisible(False)
|
||||
@@ -1589,13 +1615,12 @@ class MainWindow(QMainWindow):
|
||||
# Hide all dock widgets
|
||||
for dock_attr in (
|
||||
"tell_samples_dock",
|
||||
"automation_progress_dock",
|
||||
"information_dock",
|
||||
"face_panel_dock",
|
||||
"fluor_panel_dock",
|
||||
"smargon_trace_dock",
|
||||
"target_stability_dock",
|
||||
"prediction_metrics_dock",
|
||||
"log_dock",
|
||||
):
|
||||
dock = getattr(self, dock_attr, None)
|
||||
if dock is not None:
|
||||
@@ -1654,13 +1679,12 @@ class MainWindow(QMainWindow):
|
||||
self._pre_portrait_geometry = None
|
||||
|
||||
self.tell_samples_dock.setVisible(True)
|
||||
self.automation_progress_dock.setVisible(False)
|
||||
self.information_dock.setVisible(False)
|
||||
self.face_panel_dock.setVisible(False)
|
||||
self.fluor_panel_dock.setVisible(False)
|
||||
self.smargon_trace_dock.setVisible(False)
|
||||
self.target_stability_dock.setVisible(False)
|
||||
self.prediction_metrics_dock.setVisible(False)
|
||||
self.log_dock.setVisible(False)
|
||||
|
||||
@Slot(str, bool)
|
||||
def _portrait_alert_primary(self, msg: str, is_error: bool) -> None:
|
||||
@@ -1943,12 +1967,14 @@ class MainWindow(QMainWindow):
|
||||
)
|
||||
view_menu.addAction(show_prediction_metrics_action)
|
||||
|
||||
show_log_action = QAction("Show Log", self)
|
||||
show_log_action.setCheckable(True)
|
||||
show_log_action.setChecked(False)
|
||||
show_log_action.triggered.connect(lambda checked: self.log_dock.setVisible(checked))
|
||||
self.log_dock.visibilityChanged.connect(show_log_action.setChecked)
|
||||
view_menu.addAction(show_log_action)
|
||||
show_information_action = QAction("Show Information", self)
|
||||
show_information_action.setCheckable(True)
|
||||
show_information_action.setChecked(False)
|
||||
show_information_action.triggered.connect(
|
||||
lambda checked: self.information_dock.setVisible(checked)
|
||||
)
|
||||
self.information_dock.visibilityChanged.connect(show_information_action.setChecked)
|
||||
view_menu.addAction(show_information_action)
|
||||
|
||||
view_menu.addSeparator()
|
||||
|
||||
@@ -2036,7 +2062,10 @@ class MainWindow(QMainWindow):
|
||||
self.smargon_trace_dock.setVisible(False)
|
||||
self.target_stability_dock.setVisible(False)
|
||||
self.prediction_metrics_dock.setVisible(False)
|
||||
self.log_dock.setVisible(False)
|
||||
# Default look: Information dock open on the Automation progress tab
|
||||
# (the old automation dock was visible by default, the log hidden).
|
||||
self.information_dock.setVisible(True)
|
||||
self.information_tabs.setCurrentIndex(0)
|
||||
|
||||
self.tell_samples_dock.raise_()
|
||||
|
||||
@@ -2073,15 +2102,15 @@ class MainWindow(QMainWindow):
|
||||
sticky: bool = True,
|
||||
auto_clear_ms: int | None = None,
|
||||
) -> None:
|
||||
self.log_dock.show_notification(
|
||||
self.log_panel.show_notification(
|
||||
title=title, message=message, level=level, sticky=sticky, auto_clear_ms=auto_clear_ms
|
||||
)
|
||||
|
||||
def _show_runtime_waiting_notification(self, *, title: str, message: str) -> None:
|
||||
self.log_dock.show_waiting_notification(title=title, message=message)
|
||||
self.log_panel.show_waiting_notification(title=title, message=message)
|
||||
|
||||
def _clear_runtime_notification(self) -> None:
|
||||
self.log_dock.clear_notification()
|
||||
self.log_panel.clear_notification()
|
||||
|
||||
def _clear_automation_critical_banner(self) -> None:
|
||||
if not self._automation_critical_banner_active:
|
||||
@@ -2765,7 +2794,7 @@ class MainWindow(QMainWindow):
|
||||
settings.setValue("prediction_metrics", self.prediction_metrics_dock.isVisible())
|
||||
settings.setValue("face_detection", self.face_panel_dock.isVisible())
|
||||
settings.setValue("fluorescence", self.fluor_panel_dock.isVisible())
|
||||
settings.setValue("log", self.log_dock.isVisible())
|
||||
settings.setValue("information", self.information_dock.isVisible())
|
||||
settings.endGroup()
|
||||
|
||||
def _restore_panel_visibility_settings(self) -> None:
|
||||
@@ -2787,8 +2816,11 @@ class MainWindow(QMainWindow):
|
||||
self.face_panel_dock.setVisible(settings.value("face_detection", False, type=bool))
|
||||
if settings.contains("fluorescence"):
|
||||
self.fluor_panel_dock.setVisible(settings.value("fluorescence", False, type=bool))
|
||||
if settings.contains("log"):
|
||||
self.log_dock.setVisible(settings.value("log", False, type=bool))
|
||||
# New key: the old "log" flag described a dock that defaulted hidden;
|
||||
# the merged Information dock defaults visible, so old values would
|
||||
# wrongly hide it.
|
||||
if settings.contains("information"):
|
||||
self.information_dock.setVisible(settings.value("information", True, type=bool))
|
||||
|
||||
settings.endGroup()
|
||||
|
||||
@@ -2818,10 +2850,10 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def _apply_default_dock_split(self) -> None:
|
||||
self.resizeDocks(
|
||||
[self.tell_samples_dock, self.log_dock], [240, 240], Qt.Orientation.Vertical
|
||||
[self.tell_samples_dock, self.information_dock], [240, 240], Qt.Orientation.Vertical
|
||||
)
|
||||
self.resizeDocks(
|
||||
[self.tell_samples_dock, self.automation_progress_dock],
|
||||
[self.tell_samples_dock, self.information_dock],
|
||||
[10000, 10000],
|
||||
Qt.Orientation.Horizontal,
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from aarecommon.config.logger import attach_to_logger, find_existing_formatter
|
||||
from PySide6.QtCore import Qt, QTimer, Signal, Slot
|
||||
from PySide6.QtCore import QTimer, Signal, Slot
|
||||
from PySide6.QtWidgets import (
|
||||
QDockWidget,
|
||||
QFrame,
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
@@ -28,7 +27,6 @@ from aare.gui.styles import (
|
||||
TEXT,
|
||||
card_style,
|
||||
)
|
||||
from aare.gui.widgets.popout_window import DockTitleBar, PopoutWindow
|
||||
|
||||
|
||||
class RuntimeNotificationWidget(QFrame):
|
||||
@@ -61,7 +59,7 @@ class RuntimeNotificationWidget(QFrame):
|
||||
self._clear_button = QPushButton("Clear", self)
|
||||
self._clear_button.clicked.connect(self.clear_notification)
|
||||
|
||||
self._show_log_button = QPushButton("Show Log", self)
|
||||
self._show_log_button = QPushButton("Show log", self)
|
||||
self._show_log_button.clicked.connect(self.show_log_requested.emit)
|
||||
|
||||
header_layout = QHBoxLayout()
|
||||
@@ -194,43 +192,30 @@ class RuntimeNotificationWidget(QFrame):
|
||||
self.cleared.emit()
|
||||
|
||||
|
||||
class LogDock(QDockWidget):
|
||||
def __init__(self, title="Log", parent=None):
|
||||
super().__init__(title, parent)
|
||||
# saveState/restoreState (watch-mode hide/restore) skips unnamed docks.
|
||||
self.setObjectName("log_dock")
|
||||
self.setAllowedAreas(
|
||||
Qt.DockWidgetArea.BottomDockWidgetArea
|
||||
| Qt.DockWidgetArea.RightDockWidgetArea
|
||||
| Qt.DockWidgetArea.LeftDockWidgetArea
|
||||
)
|
||||
class LogPanel(QWidget):
|
||||
"""Console-log card: notification banner + log view. A tab inside the
|
||||
Information dock (was its own LogDock QDockWidget until the Automation
|
||||
progress / Console log docks merged). Revealing the dock/tab is the
|
||||
owner's job — this panel only signals when it needs to be seen."""
|
||||
|
||||
# No floating: popping a dock out rips it from the row and reshuffles
|
||||
# the rest. The ⤢ in the title bar (next to ✕) opens an ADDITIONAL
|
||||
# window on the same log instead.
|
||||
self.setFeatures(
|
||||
QDockWidget.DockWidgetFeature.DockWidgetMovable
|
||||
| QDockWidget.DockWidgetFeature.DockWidgetClosable
|
||||
)
|
||||
self._popout: PopoutWindow | None = None
|
||||
self._popout_view: QPlainTextEdit | None = None
|
||||
self.setTitleBarWidget(DockTitleBar(self, self._open_popout))
|
||||
reveal_requested = Signal()
|
||||
|
||||
self.container = QWidget(self)
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setObjectName("logPanel")
|
||||
self.notification = RuntimeNotificationWidget(self)
|
||||
self.notification.show_log_requested.connect(self._focus_log)
|
||||
|
||||
self.notification = RuntimeNotificationWidget(self.container)
|
||||
self.notification.show_log_requested.connect(self._raise_and_focus_log)
|
||||
|
||||
self.view = QPlainTextEdit(self.container)
|
||||
self.view = QPlainTextEdit(self)
|
||||
self.view.setReadOnly(True)
|
||||
|
||||
layout = QVBoxLayout(self.container)
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(6, 6, 6, 6)
|
||||
layout.setSpacing(6)
|
||||
layout.addWidget(self.notification)
|
||||
layout.addWidget(self.view, 1)
|
||||
|
||||
self.setWidget(self.container)
|
||||
self._mirror_views: list[QPlainTextEdit] = []
|
||||
|
||||
self.emitter = QtLogEmitter()
|
||||
self.emitter.message.connect(self._append_line)
|
||||
@@ -245,29 +230,23 @@ class LogDock(QDockWidget):
|
||||
def _append_line(self, text: str):
|
||||
self.view.appendPlainText(text)
|
||||
|
||||
@Slot()
|
||||
def _open_popout(self) -> None:
|
||||
if self._popout is None:
|
||||
# Mirror view fed by the same emitter; history is copied once at
|
||||
# creation. (One QTextDocument shared by two QPlainTextEdits would
|
||||
# make their layouts fight, hence the second document.)
|
||||
view = QPlainTextEdit()
|
||||
view.setReadOnly(True)
|
||||
# Frameless inside the pop-out — no nested boxes in this window.
|
||||
view.setStyleSheet("QPlainTextEdit { border: none; }")
|
||||
view.setPlainText(self.view.toPlainText())
|
||||
self.emitter.message.connect(view.appendPlainText)
|
||||
self._popout_view = view
|
||||
self._popout = PopoutWindow("Console Log", view, parent=self.window())
|
||||
self._popout.resize(1000, 450)
|
||||
self._popout.show()
|
||||
self._popout.raise_()
|
||||
self._popout.activateWindow()
|
||||
def make_mirror_view(self) -> QPlainTextEdit:
|
||||
"""Second view on the same emitter, for pop-out windows: history is
|
||||
copied once at creation, live lines reach every mirror, clear()
|
||||
empties them all. (One QTextDocument shared by two QPlainTextEdits
|
||||
would make their layouts fight, hence the separate documents.)"""
|
||||
view = QPlainTextEdit()
|
||||
view.setReadOnly(True)
|
||||
# Frameless inside the pop-out — no nested boxes in this window.
|
||||
view.setStyleSheet("QPlainTextEdit { border: none; }")
|
||||
view.setPlainText(self.view.toPlainText())
|
||||
self.emitter.message.connect(view.appendPlainText)
|
||||
self._mirror_views.append(view)
|
||||
return view
|
||||
|
||||
@Slot()
|
||||
def _raise_and_focus_log(self) -> None:
|
||||
self.setVisible(True)
|
||||
self.raise_()
|
||||
def _focus_log(self) -> None:
|
||||
self.reveal_requested.emit()
|
||||
self.view.setFocus()
|
||||
|
||||
def show_notification(
|
||||
@@ -279,15 +258,13 @@ class LogDock(QDockWidget):
|
||||
sticky: bool = True,
|
||||
auto_clear_ms: int | None = None,
|
||||
) -> None:
|
||||
self.setVisible(True)
|
||||
self.raise_()
|
||||
self.reveal_requested.emit()
|
||||
self.notification.show_notification(
|
||||
title=title, message=message, level=level, sticky=sticky, auto_clear_ms=auto_clear_ms
|
||||
)
|
||||
|
||||
def show_waiting_notification(self, *, title: str, message: str) -> None:
|
||||
self.setVisible(True)
|
||||
self.raise_()
|
||||
self.reveal_requested.emit()
|
||||
self.notification.show_waiting(title=title, message=message)
|
||||
|
||||
def clear_notification(self) -> None:
|
||||
@@ -295,5 +272,5 @@ class LogDock(QDockWidget):
|
||||
|
||||
def clear(self):
|
||||
self.view.clear()
|
||||
if self._popout_view is not None:
|
||||
self._popout_view.clear()
|
||||
for mirror in self._mirror_views:
|
||||
mirror.clear()
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
"""The console-log pop-out is a second view on the same emitter: history is
|
||||
copied on open, live lines reach both views, and clear() empties both."""
|
||||
"""A log mirror view is a second view on the same emitter: history is copied
|
||||
on creation, live lines reach both views, and clear() empties them all."""
|
||||
|
||||
from aare.gui.panels.log_panel import LogDock
|
||||
from aare.gui.panels.log_panel import LogPanel
|
||||
|
||||
|
||||
def test_log_popout_mirrors_and_clears(qtbot):
|
||||
dock = LogDock()
|
||||
qtbot.addWidget(dock)
|
||||
dock.emitter.message.emit("first line")
|
||||
assert "first line" in dock.view.toPlainText()
|
||||
def test_log_mirror_view_and_clear(qtbot):
|
||||
panel = LogPanel()
|
||||
qtbot.addWidget(panel)
|
||||
panel.emitter.message.emit("first line")
|
||||
assert "first line" in panel.view.toPlainText()
|
||||
|
||||
dock._open_popout()
|
||||
assert dock._popout is not None
|
||||
assert dock._popout.isVisible()
|
||||
popout_view = dock._popout_view
|
||||
assert popout_view is not None
|
||||
# History copied on open, live lines reach both views.
|
||||
assert "first line" in popout_view.toPlainText()
|
||||
dock.emitter.message.emit("second line")
|
||||
assert "second line" in dock.view.toPlainText()
|
||||
assert "second line" in popout_view.toPlainText()
|
||||
mirror = panel.make_mirror_view()
|
||||
qtbot.addWidget(mirror)
|
||||
# History copied on creation, live lines reach both views.
|
||||
assert "first line" in mirror.toPlainText()
|
||||
panel.emitter.message.emit("second line")
|
||||
assert "second line" in panel.view.toPlainText()
|
||||
assert "second line" in mirror.toPlainText()
|
||||
|
||||
# Reopening reuses the window instead of stacking mirrors.
|
||||
popout = dock._popout
|
||||
dock._open_popout()
|
||||
assert dock._popout is popout
|
||||
panel.clear()
|
||||
assert panel.view.toPlainText() == ""
|
||||
assert mirror.toPlainText() == ""
|
||||
|
||||
dock.clear()
|
||||
assert dock.view.toPlainText() == ""
|
||||
assert popout_view.toPlainText() == ""
|
||||
|
||||
def test_notification_requests_reveal(qtbot):
|
||||
panel = LogPanel()
|
||||
qtbot.addWidget(panel)
|
||||
with qtbot.waitSignal(panel.reveal_requested, timeout=1000):
|
||||
panel.show_notification(title="Boom", message="it broke")
|
||||
assert panel.notification._title.text() == "Boom"
|
||||
|
||||
Reference in New Issue
Block a user