#ifndef ORBITHUB_SESSION_TAB_H #define ORBITHUB_SESSION_TAB_H #include "profile_repository.h" #include "session_backend.h" #include #include #include #include #include #include class QPlainTextEdit; class QThread; class SessionBackend; class TerminalView; class RdpDisplayWidget; class QToolButton; class QLineEdit; class QComboBox; class QLabel; class QPushButton; class KodoTerm; struct SessionUiPreferences { QString terminalThemeName = QStringLiteral("Dark"); bool eventsPanelExpanded = false; int terminalFontPointSize = 0; }; class SessionTab : public QWidget { Q_OBJECT public: explicit SessionTab(const Profile& profile, const SessionUiPreferences& preferences, QWidget* parent = nullptr); ~SessionTab() override; QString tabTitle() const; void connectSession(); void disconnectSession(); void reconnectSession(); void clearTerminal(); void setTerminalThemeName(const QString& themeName); QString terminalThemeName() const; bool supportsThemeSelection() const; bool supportsClearAction() const; bool supportsZoom() const; void zoomIn(); void zoomOut(); void resetZoom(); void setTerminalFontPointSize(int pointSize); int terminalFontPointSize() const; bool isEventsPanelExpanded() const; void setEventsPanelExpanded(bool expanded); void clearEvents(); void copyEvents() const; void exportEventsToFile(); signals: void tabTitleChanged(const QString& title); void tabStateChanged(SessionState state); void terminalThemeChanged(const QString& themeName); void terminalFontSizeChanged(int pointSize); void eventsPanelVisibilityChanged(bool expanded); void requestConnect(const SessionConnectOptions& options); void requestDisconnect(); void requestReconnect(const SessionConnectOptions& options); void requestInput(const QString& input); void requestHostKeyConfirmation(bool trustHost); void requestTerminalSize(int columns, int rows); void requestDisplayScale(qreal devicePixelRatio); void requestKeyEvent(int key, quint32 nativeScanCode, const QString& text, bool pressed, int modifiers); void requestMouseMoveEvent(int x, int y); void requestMouseButtonEvent(int x, int y, int button, bool pressed); void requestMouseWheelEvent(int x, int y, int deltaX, int deltaY); void requestSetClipboardText(const QString& text); private slots: void onBackendStateChanged(SessionState state, const QString& message); void onBackendEventLogged(const QString& message); void onBackendConnectionError(const QString& displayMessage, const QString& rawMessage); void onBackendOutputReceived(const QString& text); void onBackendHostKeyConfirmationRequested(const QString& prompt); void onBackendRemoteClipboardTextChanged(const QString& text); void onSystemClipboardChanged(); private: Profile m_profile; QThread* m_backendThread; SessionBackend* m_backend; bool m_useKodoTermForSsh; SessionState m_state; QString m_lastError; SessionConnectOptions m_lastConnectOptions; QString m_terminalThemeName; int m_terminalFontPointSize; QString m_lastSyncedClipboardText; bool m_clipboardSyncSupported; KodoTerm* m_sshTerminal; RdpDisplayWidget* m_rdpDisplay; TerminalView* m_terminalOutput; QPlainTextEdit* m_eventLog; QToolButton* m_toggleEventsButton; QLineEdit* m_eventFilterInput; QComboBox* m_eventSeverityFilterInput; QToolButton* m_clearEventsButton; QToolButton* m_exportEventsButton; QWidget* m_eventsPanel; QWidget* m_passwordPromptBar; QLabel* m_passwordPromptLabel; QLineEdit* m_passwordPromptInput; QPushButton* m_passwordPromptConnectButton; QPushButton* m_passwordPromptCancelButton; std::function)> m_passwordPromptCallback; enum class EventSeverity { Info, Warning, Error, }; struct EventEntry { QString line; EventSeverity severity; }; std::vector m_eventEntries; QString m_eventFilter; EventSeverity m_eventSeverityFilter; bool m_eventsPanelExpanded; void setupUi(); void requestConnectOptions(std::function)> callback); void showPasswordPrompt(const QString& labelText, std::function)> callback); void hidePasswordPrompt(); bool validateProfileForConnect(); void appendEvent(const QString& message); void setState(SessionState state, const QString& message); QString stateSuffix() const; void refreshActionButtons(); void setPanelExpanded(QToolButton* button, QWidget* panel, const QString& name, bool expanded); bool startSshTerminal(const SessionConnectOptions& options); void applyTerminalTheme(const QString& themeName); void refreshEventLogView(); static EventSeverity classifyEventSeverity(const QString& message); }; #endif