feat: ajouter le split terminal (plusieurs panneaux par onglet)
Layouts : 1 (normal), 2 verticaux (cote a cote), 2 horizontaux (empiles), 4 panneaux (grille 2x2), via des QSplitter imbriques (app/ui/split_pane.py). Chaque panneau reutilise tel quel un widget d'onglet existant (SessionTabWidget, LocalTerminalTabWidget) : aucune modification de ces classes, seule une fine barre (menu ☰ + fermeture) les enveloppe. - Menu contextuel d'un onglet (SSH ou terminal local, pas SFTP, pas d'imbrication de splits) : "Diviser" -> choix du layout. Le contenu actuel occupe le premier panneau, les autres recoivent un terminal local par defaut. - Menu ☰ d'un panneau : changer son contenu (autre terminal local), ou "Deplacer un onglet ici" pour y faire migrer un onglet de premier niveau existant sans fermer sa connexion. - Fermer un panneau le retire de son QSplitter (qui redistribue l'espace tout seul) ; s'il n'en reste qu'un, l'onglet redevient un onglet normal (redescente automatique, pas de chrome de split residuel). - Fermer l'onglet divise (bouton x) ferme toutes les connexions des panneaux. - BroadcastManager (Multi-Send) atteint desormais aussi les panneaux a l'interieur d'un split (MainWindow._iter_tabs les deplie). Bug intercepte par les tests avant integration : reparenter le widget d'origine dans son panneau retire automatiquement son onglet du QTabWidget (un widget ne peut avoir qu'un seul parent), ce qui decale les onglets suivants ; un appel explicite a removeTab() ensuite visait donc le mauvais onglet. Corrige en laissant Qt gerer ce retrait implicitement plutot que de le dupliquer. tests/test_split_terminal.py : SSHConnection.start()/LocalTerminalConnection.start() neutralisees (teste l'agencement des panneaux et le cycle de vie des onglets, pas une connexion reelle). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ from app.theme import THEME_LABELS, apply_theme, current_theme, save_theme
|
||||
from app.controllers.broadcast_manager import BroadcastManager
|
||||
from app.controllers.session_controller import SessionController
|
||||
from app.controllers.connection_controller import ConnectionController
|
||||
from app.ui.split_pane import SplitContainer
|
||||
|
||||
# re-exporte pour compatibilite (utilise par tests/test_detect.py et du code existant)
|
||||
from app.services.ssh_target import detect_ssh_target # noqa: F401
|
||||
@@ -59,8 +60,17 @@ class MainWindow(QMainWindow):
|
||||
return self.connection_controller.tabs
|
||||
|
||||
def _iter_tabs(self):
|
||||
"""Widgets de terminal joignables par le Multi-Send : les onglets de
|
||||
premier niveau, et les panneaux a l'interieur des onglets divises."""
|
||||
tabs = self.connection_controller.tabs
|
||||
return [tabs.widget(i) for i in range(tabs.count())]
|
||||
result = []
|
||||
for i in range(tabs.count()):
|
||||
widget = tabs.widget(i)
|
||||
if isinstance(widget, SplitContainer):
|
||||
result.extend(pane.content for pane in widget.panes)
|
||||
else:
|
||||
result.append(widget)
|
||||
return result
|
||||
|
||||
# ---------- cablage entre controleurs ----------
|
||||
def _wire_controllers(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user