diff --git a/src/main.cpp b/src/main.cpp index b9e2de3..a6ce793 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ #include "app_icon.h" -#include "profiles_window.h" +#include "session_window.h" #include @@ -12,7 +12,7 @@ int main(int argc, char* argv[]) app.setApplicationName(QStringLiteral("OrbitHub")); app.setWindowIcon(createOrbitHubAppIcon()); - ProfilesWindow window; + SessionWindow window; window.show(); return app.exec(); diff --git a/src/profiles_window.cpp b/src/profiles_window.cpp index 86b76a0..bb8d20e 100644 --- a/src/profiles_window.cpp +++ b/src/profiles_window.cpp @@ -1,10 +1,8 @@ #include "profiles_window.h" -#include "about_dialog.h" #include "profile_dialog.h" #include "profile_repository.h" #include "profiles_tree_widget.h" -#include "session_window.h" #include #include @@ -15,13 +13,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -92,7 +88,7 @@ bool profileHasTag(const Profile& profile, const QString& requestedTag) } ProfilesWindow::ProfilesWindow(QWidget* parent) - : QMainWindow(parent), + : QWidget(parent), m_searchBox(nullptr), m_viewModeBox(nullptr), m_sortBox(nullptr), @@ -104,10 +100,6 @@ ProfilesWindow::ProfilesWindow(QWidget* parent) m_deleteButton(nullptr), m_repository(std::make_unique()) { - setWindowTitle(QStringLiteral("OrbitHub Profiles")); - resize(860, 640); - setWindowIcon(QApplication::windowIcon()); - setupUi(); if (!m_repository->initError().isEmpty()) { @@ -131,36 +123,35 @@ ProfilesWindow::~ProfilesWindow() = default; void ProfilesWindow::setupUi() { - auto* central = new QWidget(this); - auto* rootLayout = new QVBoxLayout(central); + auto* rootLayout = new QVBoxLayout(this); - auto* searchLabel = new QLabel(QStringLiteral("Search"), central); - m_searchBox = new QLineEdit(central); + auto* searchLabel = new QLabel(QStringLiteral("Search"), this); + m_searchBox = new QLineEdit(this); m_searchBox->setPlaceholderText(QStringLiteral("Filter by name, host, folder, or tags...")); - auto* viewModeLabel = new QLabel(QStringLiteral("View"), central); - m_viewModeBox = new QComboBox(central); + auto* viewModeLabel = new QLabel(QStringLiteral("View"), this); + m_viewModeBox = new QComboBox(this); m_viewModeBox->addItem(QStringLiteral("List")); m_viewModeBox->addItem(QStringLiteral("Folders")); - auto* sortLabel = new QLabel(QStringLiteral("Sort"), central); - m_sortBox = new QComboBox(central); + auto* sortLabel = new QLabel(QStringLiteral("Sort"), this); + m_sortBox = new QComboBox(this); m_sortBox->addItem(QStringLiteral("Name"), static_cast(ProfileSortOrder::NameAsc)); m_sortBox->addItem(QStringLiteral("Protocol"), static_cast(ProfileSortOrder::ProtocolAsc)); m_sortBox->addItem(QStringLiteral("Host"), static_cast(ProfileSortOrder::HostAsc)); - auto* protocolFilterLabel = new QLabel(QStringLiteral("Protocol"), central); - m_protocolFilterBox = new QComboBox(central); + auto* protocolFilterLabel = new QLabel(QStringLiteral("Protocol"), this); + m_protocolFilterBox = new QComboBox(this); m_protocolFilterBox->addItem(QStringLiteral("All")); m_protocolFilterBox->addItem(QStringLiteral("SSH")); m_protocolFilterBox->addItem(QStringLiteral("RDP")); m_protocolFilterBox->addItem(QStringLiteral("VNC")); - auto* tagFilterLabel = new QLabel(QStringLiteral("Tag"), central); - m_tagFilterBox = new QComboBox(central); + auto* tagFilterLabel = new QLabel(QStringLiteral("Tag"), this); + m_tagFilterBox = new QComboBox(this); m_tagFilterBox->addItem(QStringLiteral("All")); - m_profilesTree = new ProfilesTreeWidget(central); + m_profilesTree = new ProfilesTreeWidget(this); m_profilesTree->setSelectionMode(QAbstractItemView::SingleSelection); m_profilesTree->setColumnCount(4); m_profilesTree->setHeaderLabels( @@ -179,9 +170,9 @@ void ProfilesWindow::setupUi() m_profilesTree->header()->setSectionResizeMode(3, QHeaderView::Stretch); auto* buttonRow = new QHBoxLayout(); - m_newButton = new QPushButton(QStringLiteral("New"), central); - m_editButton = new QPushButton(QStringLiteral("Edit"), central); - m_deleteButton = new QPushButton(QStringLiteral("Delete"), central); + m_newButton = new QPushButton(QStringLiteral("New"), this); + m_editButton = new QPushButton(QStringLiteral("Edit"), this); + m_deleteButton = new QPushButton(QStringLiteral("Delete"), this); buttonRow->addWidget(m_newButton); buttonRow->addWidget(m_editButton); @@ -204,40 +195,6 @@ void ProfilesWindow::setupUi() rootLayout->addWidget(m_profilesTree, 1); rootLayout->addLayout(buttonRow); - setCentralWidget(central); - - QMenu* fileMenu = menuBar()->addMenu(QStringLiteral("File")); - QAction* newProfileAction = fileMenu->addAction(QStringLiteral("New Profile")); - QAction* newFolderAction = fileMenu->addAction(QStringLiteral("New Folder")); - fileMenu->addSeparator(); - QAction* quitAction = fileMenu->addAction(QStringLiteral("Quit")); - - connect(newProfileAction, - &QAction::triggered, - this, - [this]() { - const QString folderPath = folderPathForItem(m_profilesTree->currentItem()); - createProfile(folderPath); - }); - connect(newFolderAction, - &QAction::triggered, - this, - [this]() { - const QString folderPath = folderPathForItem(m_profilesTree->currentItem()); - createFolderInContext(folderPath); - }); - connect(quitAction, &QAction::triggered, this, [this]() { close(); }); - - QMenu* helpMenu = menuBar()->addMenu(QStringLiteral("Help")); - QAction* aboutAction = helpMenu->addAction(QStringLiteral("About OrbitHub")); - connect(aboutAction, - &QAction::triggered, - this, - [this]() { - AboutDialog dialog(this); - dialog.exec(); - }); - connect(m_searchBox, &QLineEdit::textChanged, this, @@ -959,16 +916,17 @@ void ProfilesWindow::openSessionForItem(QTreeWidgetItem* item) return; } - if (m_sessionWindow.isNull()) { - m_sessionWindow = new SessionWindow(profile.value()); - m_sessionWindow->setAttribute(Qt::WA_DeleteOnClose); - connect(m_sessionWindow, &QObject::destroyed, this, [this]() { m_sessionWindow = nullptr; }); - } else { - m_sessionWindow->openProfile(profile.value()); - } - - m_sessionWindow->setWindowState(m_sessionWindow->windowState() & ~Qt::WindowMinimized); - m_sessionWindow->show(); - m_sessionWindow->raise(); - m_sessionWindow->activateWindow(); + emit connectRequested(profile.value()); +} + +void ProfilesWindow::createProfileInCurrentContext() +{ + const QString folderPath = folderPathForItem(m_profilesTree->currentItem()); + createProfile(folderPath); +} + +void ProfilesWindow::createFolderInCurrentContext() +{ + const QString folderPath = folderPathForItem(m_profilesTree->currentItem()); + createFolderInContext(folderPath); } diff --git a/src/profiles_window.h b/src/profiles_window.h index 63a7198..aacd797 100644 --- a/src/profiles_window.h +++ b/src/profiles_window.h @@ -3,7 +3,7 @@ #include "profile_repository.h" -#include +#include #include #include #include @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -21,10 +20,9 @@ class QLineEdit; class QPushButton; class QComboBox; class QPoint; -class SessionWindow; class ProfilesTreeWidget; -class ProfilesWindow : public QMainWindow +class ProfilesWindow : public QWidget { Q_OBJECT @@ -32,6 +30,12 @@ public: explicit ProfilesWindow(QWidget* parent = nullptr); ~ProfilesWindow() override; + void createProfileInCurrentContext(); + void createFolderInCurrentContext(); + +signals: + void connectRequested(const Profile& profile); + private: QLineEdit* m_searchBox; QComboBox* m_viewModeBox; @@ -42,7 +46,6 @@ private: QPushButton* m_newButton; QPushButton* m_editButton; QPushButton* m_deleteButton; - QPointer m_sessionWindow; std::unique_ptr m_repository; std::unordered_map m_profileCache; QString m_pendingTagFilterPreference; diff --git a/src/session_window.cpp b/src/session_window.cpp index 829ea13..7935d1e 100644 --- a/src/session_window.cpp +++ b/src/session_window.cpp @@ -1,6 +1,7 @@ #include "session_window.h" #include "about_dialog.h" +#include "profiles_window.h" #include #include "session_tab.h" @@ -38,12 +39,12 @@ QStringList terminalThemeNames() } } -SessionWindow::SessionWindow(const Profile& profile, QWidget* parent) - : QMainWindow(parent), m_tabs(new QTabWidget(this)) +SessionWindow::SessionWindow(QWidget* parent) + : QMainWindow(parent), m_tabs(new QTabWidget(this)), m_profilesWidget(nullptr) { loadUiPreferences(); - setWindowTitle(QStringLiteral("OrbitHub Session - %1").arg(profile.name)); + setWindowTitle(QStringLiteral("OrbitHub")); resize(1080, 760); setWindowIcon(QApplication::windowIcon()); @@ -58,8 +59,8 @@ SessionWindow::SessionWindow(const Profile& profile, QWidget* parent) } m_tabs->removeTab(index); delete tab; - if (m_tabs->count() == 0) { - close(); + if (sessionTabCount() == 0) { + setWindowTitle(QStringLiteral("OrbitHub")); } }); m_tabs->tabBar()->setContextMenuPolicy(Qt::CustomContextMenu); @@ -164,6 +165,22 @@ SessionWindow::SessionWindow(const Profile& profile, QWidget* parent) } }); + QMenu* fileMenu = menuBar()->addMenu(QStringLiteral("File")); + QAction* newProfileAction = fileMenu->addAction(QStringLiteral("New Profile")); + QAction* newFolderAction = fileMenu->addAction(QStringLiteral("New Folder")); + fileMenu->addSeparator(); + QAction* quitAction = fileMenu->addAction(QStringLiteral("Quit")); + + connect(newProfileAction, + &QAction::triggered, + this, + [this]() { m_profilesWidget->createProfileInCurrentContext(); }); + connect(newFolderAction, + &QAction::triggered, + this, + [this]() { m_profilesWidget->createFolderInCurrentContext(); }); + connect(quitAction, &QAction::triggered, this, []() { qApp->quit(); }); + QMenu* helpMenu = menuBar()->addMenu(QStringLiteral("Help")); QAction* aboutAction = helpMenu->addAction(QStringLiteral("About OrbitHub")); connect(aboutAction, @@ -175,7 +192,15 @@ SessionWindow::SessionWindow(const Profile& profile, QWidget* parent) }); setCentralWidget(m_tabs); - addSessionTab(profile); + + m_profilesWidget = new ProfilesWindow(this); + const int profilesIndex = m_tabs->addTab(m_profilesWidget, QStringLiteral("Profiles")); + m_tabs->tabBar()->setTabButton(profilesIndex, QTabBar::LeftSide, nullptr); + m_tabs->tabBar()->setTabButton(profilesIndex, QTabBar::RightSide, nullptr); + connect(m_profilesWidget, + &ProfilesWindow::connectRequested, + this, + &SessionWindow::addSessionTab); } void SessionWindow::openProfile(const Profile& profile) @@ -188,8 +213,10 @@ void SessionWindow::addSessionTab(const Profile& profile) auto* tab = new SessionTab(profile, m_preferences, this); const int index = m_tabs->addTab(tab, tab->tabTitle()); m_tabs->setCurrentIndex(index); - if (m_tabs->count() > 1) { + if (sessionTabCount() > 1) { setWindowTitle(QStringLiteral("OrbitHub Sessions")); + } else { + setWindowTitle(QStringLiteral("OrbitHub Session - %1").arg(profile.name)); } m_tabs->tabBar()->setTabTextColor( index, tabColorForState(SessionState::Disconnected, m_tabs->palette())); @@ -248,6 +275,11 @@ void SessionWindow::updateTabTitle(SessionTab* tab, const QString& title) } } +int SessionWindow::sessionTabCount() const +{ + return m_tabs->count() - 1; +} + void SessionWindow::loadUiPreferences() { QSettings settings; diff --git a/src/session_window.h b/src/session_window.h index 9afa305..2ff1b24 100644 --- a/src/session_window.h +++ b/src/session_window.h @@ -7,23 +7,26 @@ #include class QTabWidget; +class ProfilesWindow; class SessionWindow : public QMainWindow { Q_OBJECT public: - explicit SessionWindow(const Profile& profile, QWidget* parent = nullptr); + explicit SessionWindow(QWidget* parent = nullptr); void openProfile(const Profile& profile); private: QTabWidget* m_tabs; + ProfilesWindow* m_profilesWidget; SessionUiPreferences m_preferences; void addSessionTab(const Profile& profile); void updateTabTitle(SessionTab* tab, const QString& title); void loadUiPreferences(); void saveUiPreferences() const; + int sessionTabCount() const; }; #endif