Client SSH/SFTP personnel pour Windows

Reunit en un seul outil les fonctions utiles de MobaXterm, Termius et Bitvise,
sans compte ni service tiers, avec toutes les donnees en local.

- Terminaux multi-onglets : sessions SSH et terminaux Windows locaux
  (PowerShell / cmd) via la pseudo-console native ConPTY
- Gestionnaire de fichiers SFTP facon WinSCP : double panneau, colonnes
  triables, glisser-deposer, renommage, permissions, file de transferts.
  Ouvrable sur une connexion en cours sans creer de favori
- Gestion des cles SSH : generation Ed25519/RSA, import, export
- Gestion du fichier known_hosts, avec remplacement guide d'une cle d'hote
  modifiee (cas frequent des serveurs en DHCP)
- Trois themes (clair, bleu nuit, noir), commutables a chaud
- Authentification automatique reprenant le comportement de la commande ssh
  (agent SSH et cles ~/.ssh), mot de passe demande seulement en secours

Aucun mot de passe n'est stocke sur le disque.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
snoopy
2026-09-04 06:50:10 +02:00
commit b977842186
28 changed files with 3946 additions and 0 deletions

342
resources/theme.qss Normal file
View File

@@ -0,0 +1,342 @@
/* ============================================================
PySSH Client - gabarit de theme
Les jetons prefixes du signe dollar sont remplaces par la palette choisie
(voir app/theme.py).
Applique sur le style de base Fusion.
============================================================ */
* {
outline: none;
font-family: "Segoe UI", "Cascadia Mono", sans-serif;
font-size: 13px;
}
QWidget {
background-color: $base;
color: $text;
selection-background-color: $accent;
selection-color: $on_accent;
}
QMainWindow, QDialog {
background-color: $window;
}
/* ---------- Barre de menu ---------- */
QMenuBar {
background-color: $panel;
color: $text;
border-bottom: 1px solid $border;
padding: 2px 4px;
}
QMenuBar::item {
background: transparent;
padding: 6px 12px;
border-radius: 4px;
}
QMenuBar::item:selected {
background-color: $hover;
}
QMenu {
background-color: $panel;
border: 1px solid $border;
padding: 4px;
border-radius: 6px;
}
QMenu::item {
padding: 6px 24px 6px 12px;
border-radius: 4px;
color: $text;
}
QMenu::item:selected {
background-color: $accent;
color: $on_accent;
}
QMenu::separator {
height: 1px;
background: $border;
margin: 4px 8px;
}
/* ---------- Barre de statut ---------- */
QStatusBar {
background-color: $panel;
color: $text_dim;
border-top: 1px solid $border;
}
/* ---------- Dock / sidebar ---------- */
QDockWidget {
color: $text;
titlebar-close-icon: none;
border: none;
}
QDockWidget::title {
background-color: $panel;
padding: 8px 10px;
font-weight: 600;
border-bottom: 1px solid $border;
}
/* ---------- Arborescence des sessions ---------- */
QTreeWidget {
background-color: $panel;
border: none;
border-right: 1px solid $border;
padding: 4px;
show-decoration-selected: 1;
}
QTreeWidget::item {
padding: 6px 4px;
border-radius: 5px;
margin: 1px 2px;
}
QTreeWidget::item:hover {
background-color: $hover;
}
QTreeWidget::item:selected {
background-color: $accent;
color: $on_accent;
}
QTreeWidget::branch {
background: transparent;
}
QHeaderView::section {
background-color: $elevated;
color: $text_dim;
border: none;
border-right: 1px solid $border;
border-bottom: 1px solid $border;
padding: 5px 6px;
}
/* ---------- Onglets ---------- */
QTabWidget::pane {
border: none;
background-color: $window;
top: -1px;
}
QTabBar {
background-color: $panel;
}
QTabBar::tab {
background-color: $panel;
color: $text_dim;
padding: 9px 18px;
margin-right: 2px;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
border: 1px solid $border;
border-bottom: none;
}
QTabBar::tab:selected {
background-color: $window;
color: $text;
border-bottom: 2px solid $accent;
}
QTabBar::tab:hover:!selected {
background-color: $hover;
color: $text;
}
QTabBar::close-button {
subcontrol-position: right;
}
/* ---------- Boutons ---------- */
QPushButton {
background-color: $elevated;
color: $text;
border: 1px solid $border_strong;
border-radius: 6px;
padding: 7px 16px;
}
QPushButton:hover {
background-color: $hover;
border-color: $accent;
}
QPushButton:pressed {
background-color: $pressed;
}
QPushButton:disabled {
color: $text_disabled;
background-color: $base;
}
QPushButton#primary, QDialogButtonBox QPushButton[default="true"] {
background-color: $accent;
border-color: $accent_hover;
color: $on_accent;
font-weight: 600;
}
QPushButton#primary:hover, QDialogButtonBox QPushButton[default="true"]:hover {
background-color: $accent_hover;
}
QToolButton {
background-color: transparent;
color: $text;
border: 1px solid transparent;
border-radius: 6px;
padding: 6px 10px;
}
QToolButton:hover {
background-color: $hover;
border-color: $border_strong;
}
QToolButton:pressed, QToolButton:checked {
background-color: $accent;
color: $on_accent;
}
QToolButton::menu-indicator {
subcontrol-position: right center;
subcontrol-origin: padding;
right: 2px;
}
QToolButton#primary {
background-color: $accent;
border: 1px solid $accent_hover;
color: $on_accent;
font-weight: 600;
}
QToolButton#primary:hover {
background-color: $accent_hover;
}
/* ---------- Barre superieure des onglets terminal ---------- */
QFrame#tabBar {
background-color: $panel;
border-bottom: 1px solid $border;
}
QLabel#statusLabel {
color: $text_dim;
font-weight: 500;
}
/* ---------- Champs de saisie ---------- */
QLineEdit, QTextEdit, QPlainTextEdit, QSpinBox, QComboBox {
background-color: $input;
color: $text;
border: 1px solid $border_strong;
border-radius: 5px;
padding: 5px 8px;
selection-background-color: $accent;
selection-color: $on_accent;
}
QLineEdit:focus, QTextEdit:focus, QSpinBox:focus, QComboBox:focus {
border: 1px solid $accent;
}
QComboBox::drop-down {
border: none;
width: 22px;
}
QComboBox QAbstractItemView {
background-color: $input;
color: $text;
border: 1px solid $border_strong;
selection-background-color: $accent;
selection-color: $on_accent;
outline: none;
}
QSpinBox::up-button, QSpinBox::down-button {
background-color: $elevated;
width: 16px;
border-left: 1px solid $border;
}
QCheckBox {
color: $text;
spacing: 6px;
}
/* ---------- Listes ---------- */
QListWidget {
background-color: $panel;
border: 1px solid $border;
border-radius: 6px;
padding: 2px;
}
QListWidget::item {
padding: 5px 6px;
border-radius: 4px;
}
QListWidget::item:hover {
background-color: $hover;
}
QListWidget::item:selected {
background-color: $accent;
color: $on_accent;
}
/* ---------- Splitter ---------- */
QSplitter::handle {
background-color: $border;
}
QSplitter::handle:horizontal {
width: 2px;
}
QSplitter::handle:vertical {
height: 2px;
}
QSplitter::handle:hover {
background-color: $accent;
}
/* ---------- Barres de defilement ---------- */
QScrollBar:vertical {
background: $base;
width: 12px;
margin: 0;
}
QScrollBar::handle:vertical {
background: $scroll;
min-height: 24px;
border-radius: 5px;
margin: 2px;
}
QScrollBar::handle:vertical:hover {
background: $scroll_hover;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
height: 0;
}
QScrollBar:horizontal {
background: $base;
height: 12px;
}
QScrollBar::handle:horizontal {
background: $scroll;
min-width: 24px;
border-radius: 5px;
margin: 2px;
}
QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal {
width: 0;
}
/* ---------- Barres de progression ---------- */
QProgressBar {
background-color: $input;
border: 1px solid $border_strong;
border-radius: 5px;
text-align: center;
color: $text;
}
QProgressBar::chunk {
background-color: $accent;
border-radius: 5px;
}
/* ---------- Etiquettes ---------- */
QLabel {
background: transparent;
}
QLabel[heading="true"] {
font-size: 15px;
font-weight: 600;
color: $text;
}
QToolTip {
background-color: $elevated;
color: $text;
border: 1px solid $border_strong;
padding: 4px 6px;
}