Renommage des onglets
Double-clic sur un onglet pour le renommer, ou clic droit pour le menu. Le menu contextuel permet aussi de fermer l'onglet vise ou tous les autres. Le nom saisi est conserve tel quel : un onglet renomme "Serveur prod" ne retrouve pas son libelle d'origine, y compris apres une reconnexion. Un nom vide ou uniquement compose d'espaces est refuse, et annuler la saisie laisse le nom inchange. La fermeture des autres onglets parcourt la liste a l'envers : retirer un onglet decale l'index des suivants, un parcours en avant en sauterait. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,8 @@ Client SSH/SFTP personnel (type MobaXterm/Termius/Bitvise), 100% local, sans com
|
|||||||
- Confort d'affichage : zoom `Ctrl+molette` ou `Ctrl+ +/-` (`Ctrl+0` remet a zero, la taille est
|
- Confort d'affichage : zoom `Ctrl+molette` ou `Ctrl+ +/-` (`Ctrl+0` remet a zero, la taille est
|
||||||
memorisee), barre de defilement de l'historique, `Maj+PagePrec/Suiv`, `Ctrl+Fin` pour revenir
|
memorisee), barre de defilement de l'historique, `Maj+PagePrec/Suiv`, `Ctrl+Fin` pour revenir
|
||||||
en direct, et recherche dans l'historique avec `Ctrl+F`
|
en direct, et recherche dans l'historique avec `Ctrl+F`
|
||||||
|
- Onglets renommables (double-clic sur l'onglet, ou clic droit) et deplaçables ;
|
||||||
|
le clic droit permet aussi de fermer les autres onglets
|
||||||
- Panneau des sessions redimensionnable en attrapant le separateur, et masquable entierement
|
- Panneau des sessions redimensionnable en attrapant le separateur, et masquable entierement
|
||||||
(`F9`, menu Affichage, ou la croix du panneau) pour donner tout l'ecran au terminal
|
(`F9`, menu Affichage, ou la croix du panneau) pour donner tout l'ecran au terminal
|
||||||
- **Tunnels SSH** (redirection de ports) : bouton "Tunnels" dans la barre d'un onglet SSH.
|
- **Tunnels SSH** (redirection de ports) : bouton "Tunnels" dans la barre d'un onglet SSH.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from PySide6.QtGui import QAction, QActionGroup, QKeySequence, QShortcut
|
|||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QMainWindow, QDockWidget, QTreeWidget, QTreeWidgetItem, QTabWidget, QWidget,
|
QMainWindow, QDockWidget, QTreeWidget, QTreeWidgetItem, QTabWidget, QWidget,
|
||||||
QVBoxLayout, QHBoxLayout, QToolButton, QLabel, QMenu, QMessageBox, QSplitter,
|
QVBoxLayout, QHBoxLayout, QToolButton, QLabel, QMenu, QMessageBox, QSplitter,
|
||||||
QStatusBar, QFrame, QApplication, QLineEdit, QFileDialog,
|
QStatusBar, QFrame, QApplication, QLineEdit, QFileDialog, QInputDialog,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app.session_manager import SessionStore, Session, AUTH_KEY, AUTH_PASSWORD
|
from app.session_manager import SessionStore, Session, AUTH_KEY, AUTH_PASSWORD
|
||||||
@@ -661,6 +661,10 @@ class MainWindow(QMainWindow):
|
|||||||
self.tabs = QTabWidget()
|
self.tabs = QTabWidget()
|
||||||
self.tabs.setTabsClosable(True)
|
self.tabs.setTabsClosable(True)
|
||||||
self.tabs.setMovable(True)
|
self.tabs.setMovable(True)
|
||||||
|
# double-clic sur un onglet pour le renommer, clic droit pour le menu
|
||||||
|
self.tabs.tabBarDoubleClicked.connect(self.rename_tab)
|
||||||
|
self.tabs.tabBar().setContextMenuPolicy(Qt.CustomContextMenu)
|
||||||
|
self.tabs.tabBar().customContextMenuRequested.connect(self._on_tab_context_menu)
|
||||||
self.tabs.tabCloseRequested.connect(self._on_tab_close)
|
self.tabs.tabCloseRequested.connect(self._on_tab_close)
|
||||||
self.setCentralWidget(self.tabs)
|
self.setCentralWidget(self.tabs)
|
||||||
|
|
||||||
@@ -896,6 +900,41 @@ class MainWindow(QMainWindow):
|
|||||||
def _register_broadcast(self, tab) -> None:
|
def _register_broadcast(self, tab) -> None:
|
||||||
tab.terminal.data_to_send.connect(lambda data, t=tab: self._broadcast(data, t))
|
tab.terminal.data_to_send.connect(lambda data, t=tab: self._broadcast(data, t))
|
||||||
|
|
||||||
|
# ---------- renommage des onglets ----------
|
||||||
|
def rename_tab(self, index: int) -> None:
|
||||||
|
if index < 0:
|
||||||
|
return
|
||||||
|
actuel = self.tabs.tabText(index)
|
||||||
|
nouveau, ok = QInputDialog.getText(
|
||||||
|
self, "Renommer l'onglet", "Nom de l'onglet :", text=actuel
|
||||||
|
)
|
||||||
|
if ok and nouveau.strip():
|
||||||
|
self.tabs.setTabText(index, nouveau.strip())
|
||||||
|
|
||||||
|
def _on_tab_context_menu(self, pos) -> None:
|
||||||
|
bar = self.tabs.tabBar()
|
||||||
|
index = bar.tabAt(pos)
|
||||||
|
if index < 0:
|
||||||
|
return
|
||||||
|
menu = QMenu(self)
|
||||||
|
act_rename = menu.addAction("Renommer... (double-clic)")
|
||||||
|
menu.addSeparator()
|
||||||
|
act_close = menu.addAction("Fermer cet onglet")
|
||||||
|
act_close_others = menu.addAction("Fermer les autres onglets")
|
||||||
|
act_close_others.setEnabled(self.tabs.count() > 1)
|
||||||
|
|
||||||
|
action = menu.exec(bar.mapToGlobal(pos))
|
||||||
|
if action == act_rename:
|
||||||
|
self.rename_tab(index)
|
||||||
|
elif action == act_close:
|
||||||
|
self._on_tab_close(index)
|
||||||
|
elif action == act_close_others:
|
||||||
|
# on ferme par la fin : retirer un onglet decale les suivants
|
||||||
|
cible = self.tabs.widget(index)
|
||||||
|
for other in range(self.tabs.count() - 1, -1, -1):
|
||||||
|
if self.tabs.widget(other) is not cible:
|
||||||
|
self._on_tab_close(other)
|
||||||
|
|
||||||
def _on_tab_close(self, index: int) -> None:
|
def _on_tab_close(self, index: int) -> None:
|
||||||
widget = self.tabs.widget(index)
|
widget = self.tabs.widget(index)
|
||||||
if isinstance(widget, (BaseTerminalTab, SFTPTabWidget)):
|
if isinstance(widget, (BaseTerminalTab, SFTPTabWidget)):
|
||||||
|
|||||||
Reference in New Issue
Block a user