""" Timeline Entry Widget Widget for displaying a single test result entry in the analysis timeline. """ from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QLabel, QPushButton from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtGui import QFont class TimelineEntry(QWidget): """ Timeline entry showing a test result. Signals: save_clicked: Emitted when save button is clicked view_clicked: Emitted when view button is clicked """ save_clicked = pyqtSignal(int) # test_id view_clicked = pyqtSignal(int) # test_id def __init__(self, test_id: int, timestamp: str, classification: str, confidence: float, processing_time: float, parent=None): super().__init__(parent) self.test_id = test_id self.init_ui(timestamp, classification, confidence, processing_time) def init_ui(self, timestamp: str, classification: str, confidence: float, processing_time: float): """Initialize the timeline entry UI.""" self.setFixedHeight(48) # Set background color (alternating) bg_color = "#f8f9fa" if self.test_id % 2 == 0 else "#ffffff" self.setStyleSheet(f""" QWidget {{ background-color: {bg_color}; border: 1px solid #ecf0f1; border-radius: 3px; }} """) layout = QHBoxLayout(self) layout.setContentsMargins(12, 8, 12, 8) layout.setSpacing(12) # Status indicator dot status_colors = { "Ripe": "#27ae60", "Overripe": "#f39c12", "Unripe": "#95a5a6", "Overripe": "#e74c3c" } color = status_colors.get(classification, "#95a5a6") status_dot = QLabel("●") status_dot.setFont(QFont("Arial", 12)) status_dot.setStyleSheet(f"color: {color};") status_dot.setFixedWidth(15) layout.addWidget(status_dot) # Info section info_layout = QVBoxLayout() info_layout.setSpacing(2) # Timestamp and test ID header_label = QLabel(f"{timestamp} - Test #{self.test_id:04d}") header_label.setFont(QFont("Arial", 10, QFont.Bold)) header_label.setStyleSheet("color: #2c3e50;") info_layout.addWidget(header_label) # Classification and details details = f"{classification.upper()} ({confidence:.1f}%) - Processing: {processing_time:.2f}s" details_label = QLabel(details) details_label.setFont(QFont("Arial", 9)) details_label.setStyleSheet(f"color: {color};") info_layout.addWidget(details_label) layout.addLayout(info_layout, 1) # Action button if self.test_id == 1: # Most recent - show SAVE button action_btn = QPushButton("SAVE") action_btn.clicked.connect(lambda: self.save_clicked.emit(self.test_id)) btn_color = "#27ae60" else: # Older entries - show VIEW button action_btn = QPushButton("VIEW") action_btn.clicked.connect(lambda: self.view_clicked.emit(self.test_id)) btn_color = "#3498db" action_btn.setFont(QFont("Arial", 8, QFont.Bold)) action_btn.setFixedSize(50, 24) action_btn.setStyleSheet(f""" QPushButton {{ background-color: {btn_color}; border: none; border-radius: 2px; color: white; }} QPushButton:hover {{ opacity: 0.9; }} """) layout.addWidget(action_btn)