"""Fenêtre d'historique des sessions WGSecure.""" from PyQt6.QtWidgets import ( QDialog, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem, QPushButton, QLabel, QHeaderView, QMessageBox, ) from PyQt6.QtCore import Qt from PyQt6.QtGui import QColor, QFont from app.core import history as hist _DARK = "#1c2833" _DARK2 = "#17202a" _CSS = f""" QDialog {{ background: {_DARK2}; }} QLabel {{ color: white; background: transparent; }} QTableWidget {{ background: {_DARK}; color: white; gridline-color: #2e4057; border: none; font-size: 11px; }} QHeaderView::section {{ background: #2e4057; color: white; padding: 5px; border: none; font-weight: bold; font-size: 11px; }} QTableWidget::item:selected {{ background: #2471a3; }} QPushButton {{ background: #2e4057; color: white; border-radius: 5px; padding: 6px 14px; border: none; }} QPushButton:hover {{ background: #3d5166; }} """ class HistoryDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("WGSecure — Historique des sessions") self.setMinimumSize(680, 420) self.setStyleSheet(_CSS) self._build_ui() self._load() def _build_ui(self): layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) # Bannière banner = QLabel(" 📊 Historique des sessions VPN") banner.setFixedHeight(40) banner.setStyleSheet( f"background: {_DARK2}; color: white; font-size: 14px; font-weight: bold;" ) layout.addWidget(banner) # Tableau self._table = QTableWidget(0, 6) self._table.setHorizontalHeaderLabels([ "Date début", "Serveur", "Profil", "Durée", "↓ Reçu", "↑ Envoyé" ]) self._table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch) self._table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents) self._table.verticalHeader().setVisible(False) self._table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows) self._table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers) self._table.setAlternatingRowColors(True) self._table.setStyleSheet( _CSS + "QTableWidget { alternate-background-color: #212f3d; }" ) layout.addWidget(self._table) # Barre infos + boutons bar = QLabel("") bar.setFixedHeight(1) bar.setStyleSheet(f"background: #2e4057;") layout.addWidget(bar) btn_row_w = QVBoxLayout() btn_row_w.setContentsMargins(0, 0, 0, 0) bottom = QHBoxLayout() bottom.setContentsMargins(14, 8, 14, 12) self._summary_lbl = QLabel("") self._summary_lbl.setStyleSheet("color: #5d6d7e; font-size: 11px;") bottom.addWidget(self._summary_lbl) bottom.addStretch() btn_clear = QPushButton("🗑️ Effacer l'historique") btn_clear.setStyleSheet( "QPushButton { background: #6e2e1c; color: white; border-radius: 5px;" " padding: 6px 14px; border: none; }" "QPushButton:hover { background: #922b21; }" ) btn_clear.clicked.connect(self._clear) btn_close = QPushButton("Fermer") btn_close.clicked.connect(self.accept) bottom.addWidget(btn_clear) bottom.addWidget(btn_close) bottom_w = QWidget() bottom_w.setStyleSheet(f"background: {_DARK2};") bottom_w.setLayout(bottom) layout.addWidget(bottom_w) def _load(self): self._table.setRowCount(0) sessions = hist.get_sessions(100) total_rx = total_tx = total_s = 0 for row, s in enumerate(sessions): self._table.insertRow(row) end = s.get("end") color = "#a9dfbf" if end else "#f9e79f" # vert=terminée, jaune=en cours cells = [ s.get("start", "—"), s.get("server", "—"), s.get("profile", "Défaut"), hist.fmt_duration(s.get("duration")), hist.fmt_bytes(s.get("rx", 0)), hist.fmt_bytes(s.get("tx", 0)), ] for col, text in enumerate(cells): item = QTableWidgetItem(text) item.setForeground(QColor(color)) item.setTextAlignment( Qt.AlignmentFlag.AlignVCenter | (Qt.AlignmentFlag.AlignRight if col >= 3 else Qt.AlignmentFlag.AlignLeft) ) self._table.setItem(row, col, item) total_rx += s.get("rx", 0) total_tx += s.get("tx", 0) if s.get("duration"): total_s += s["duration"] n = len(sessions) self._summary_lbl.setText( f"{n} session{'s' if n > 1 else ''} • " f"Total ↓ {hist.fmt_bytes(total_rx)} " f"↑ {hist.fmt_bytes(total_tx)} • " f"Durée cumulée : {hist.fmt_duration(total_s)}" ) def _clear(self): reply = QMessageBox.question( self, "Confirmer", "Effacer tout l'historique des sessions ?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, ) if reply == QMessageBox.StandardButton.Yes: hist.clear() self._load()