98 lines
3.5 KiB
Python
98 lines
3.5 KiB
Python
"""APIClient - Agent - Multi-tab request manager."""
|
||
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QTabWidget, QPushButton, QTabBar
|
||
from PyQt6.QtCore import pyqtSignal, Qt
|
||
|
||
from app.ui.request_panel import RequestPanel
|
||
from app.models import HttpRequest
|
||
|
||
|
||
class RequestTab(QWidget):
|
||
send_requested = pyqtSignal(object)
|
||
|
||
def __init__(self, parent=None):
|
||
super().__init__(parent)
|
||
layout = QVBoxLayout(self)
|
||
layout.setContentsMargins(0, 0, 0, 0)
|
||
layout.setSpacing(0)
|
||
self.request_panel = RequestPanel()
|
||
self.request_panel.send_requested.connect(self.send_requested)
|
||
layout.addWidget(self.request_panel)
|
||
|
||
def load_request(self, req: HttpRequest):
|
||
self.request_panel.load_request(req)
|
||
|
||
def get_request(self) -> HttpRequest:
|
||
return self.request_panel.get_request()
|
||
|
||
|
||
class TabsManager(QWidget):
|
||
send_requested = pyqtSignal(object)
|
||
current_tab_changed = pyqtSignal()
|
||
|
||
def __init__(self, parent=None):
|
||
super().__init__(parent)
|
||
layout = QVBoxLayout(self)
|
||
layout.setContentsMargins(0, 0, 0, 0)
|
||
layout.setSpacing(0)
|
||
|
||
self.tab_widget = QTabWidget()
|
||
self.tab_widget.setTabsClosable(False) # we manage close buttons ourselves
|
||
self.tab_widget.setMovable(True)
|
||
self.tab_widget.currentChanged.connect(lambda _: self.current_tab_changed.emit())
|
||
|
||
# "+" new tab button in the corner
|
||
new_btn = QPushButton("+")
|
||
new_btn.setObjectName("ghost")
|
||
new_btn.setFixedSize(28, 28)
|
||
new_btn.setToolTip("New Tab (Ctrl+T)")
|
||
new_btn.clicked.connect(lambda: self.new_tab())
|
||
self.tab_widget.setCornerWidget(new_btn, Qt.Corner.TopRightCorner)
|
||
|
||
layout.addWidget(self.tab_widget)
|
||
self._tab_counter = 0
|
||
self.new_tab()
|
||
|
||
# ── Public API ────────────────────────────────────────────────────────────
|
||
|
||
def new_tab(self, req: HttpRequest = None) -> RequestTab:
|
||
tab = RequestTab()
|
||
tab.send_requested.connect(self.send_requested)
|
||
if req:
|
||
tab.load_request(req)
|
||
self._tab_counter += 1
|
||
label = req.name if (req and req.name) else f"Request {self._tab_counter}"
|
||
idx = self.tab_widget.addTab(tab, label)
|
||
self.tab_widget.setCurrentIndex(idx)
|
||
self._add_close_button(idx, tab)
|
||
return tab
|
||
|
||
def _add_close_button(self, idx: int, tab: RequestTab):
|
||
btn = QPushButton("×")
|
||
btn.setObjectName("tabCloseBtn")
|
||
btn.setFixedSize(18, 18)
|
||
btn.setToolTip("Close Tab")
|
||
btn.clicked.connect(lambda: self._close_tab(self.tab_widget.indexOf(tab)))
|
||
self.tab_widget.tabBar().setTabButton(idx, QTabBar.ButtonPosition.RightSide, btn)
|
||
|
||
def close_current_tab(self):
|
||
self._close_tab(self.tab_widget.currentIndex())
|
||
|
||
def _close_tab(self, index: int):
|
||
if self.tab_widget.count() > 1:
|
||
self.tab_widget.removeTab(index)
|
||
|
||
def current_tab(self) -> RequestTab | None:
|
||
w = self.tab_widget.currentWidget()
|
||
return w if isinstance(w, RequestTab) else None
|
||
|
||
def load_request_in_new_tab(self, req: HttpRequest):
|
||
self.new_tab(req)
|
||
|
||
def load_request_in_current_tab(self, req: HttpRequest):
|
||
tab = self.current_tab()
|
||
if tab:
|
||
tab.load_request(req)
|
||
|
||
def rename_current_tab(self, name: str):
|
||
self.tab_widget.setTabText(self.tab_widget.currentIndex(), name)
|