Files
WGSecure/app/ui/history_dialog.py
T
2026-06-02 07:34:09 +02:00

159 lines
5.5 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
_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()