Files
WGSecure/app/ui/history_dialog.py
T
2026-09-04 08:55:35 +02:00

156 lines
5.6 KiB
Python

"""Fenêtre d'historique des sessions WGSecure."""
from PyQt6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QTableWidget,
QTableWidgetItem, QPushButton, QLabel, QHeaderView,
QMessageBox, QWidget,
)
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QColor, QFont
from app.core import history as hist
from app.ui import theme
_CSS = f"""
QDialog {{ background: {theme.BG_SUNKEN}; }}
QLabel {{ color: {theme.TEXT}; background: transparent; }}
QTableWidget {{
background: {theme.BG}; color: {theme.TEXT}; gridline-color: {theme.BG_RAISED};
border: none; font-size: 11px;
}}
QHeaderView::section {{
background: {theme.BG_RAISED}; color: {theme.TEXT}; padding: 5px;
border: none; font-weight: bold; font-size: 11px;
}}
QTableWidget::item:selected {{ background: {theme.ACCENT}; }}
QPushButton {{
background: {theme.BG_RAISED}; color: {theme.TEXT}; border-radius: 5px;
padding: 6px 14px; border: none;
}}
QPushButton:hover {{ background: {theme.ACCENT_HOVER}; }}
"""
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: {theme.BG_SUNKEN}; color: {theme.TEXT}; 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 +
f"QTableWidget {{ alternate-background-color: {theme.BG_RAISED}; }}"
)
layout.addWidget(self._table)
# Barre infos + boutons
bar = QLabel("")
bar.setFixedHeight(1)
bar.setStyleSheet(f"background: {theme.BG_RAISED};")
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(f"color: {theme.TEXT_FAINT}; font-size: 11px;")
bottom.addWidget(self._summary_lbl)
bottom.addStretch()
btn_clear = QPushButton("🗑️ Effacer l'historique")
btn_clear.setStyleSheet(
f"QPushButton {{ background: {theme.FAIL_SOLID}; color: {theme.TEXT}; border-radius: 5px;"
" padding: 6px 14px; border: none; }"
"QPushButton:hover { background: #e74c3c; }"
)
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: {theme.BG_SUNKEN};")
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 = theme.OK_TEXT if end else theme.WARN_TEXT # 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()