diff --git a/Software/PC_Application/LibreVNA-GUI/appwindow.cpp b/Software/PC_Application/LibreVNA-GUI/appwindow.cpp index 8688164..a2dc6d7 100644 --- a/Software/PC_Application/LibreVNA-GUI/appwindow.cpp +++ b/Software/PC_Application/LibreVNA-GUI/appwindow.cpp @@ -138,7 +138,8 @@ AppWindow::AppWindow(QWidget *parent) } modeHandler = new ModeHandler(this); - new ModeWindow(modeHandler, this); + auto modeWindow = new ModeWindow(modeHandler, this); + ui->menubar->insertMenu(ui->menuHelp->menuAction(), modeWindow->getMenu()); central = new QStackedWidget; setCentralWidget(central); diff --git a/Software/PC_Application/LibreVNA-GUI/modewindow.cpp b/Software/PC_Application/LibreVNA-GUI/modewindow.cpp index 178b939..12bf87a 100644 --- a/Software/PC_Application/LibreVNA-GUI/modewindow.cpp +++ b/Software/PC_Application/LibreVNA-GUI/modewindow.cpp @@ -7,6 +7,7 @@ #include #include #include +#include ModeWindow::ModeWindow(ModeHandler* handler, AppWindow* aw): QWidget(nullptr), @@ -22,6 +23,10 @@ ModeWindow::ModeWindow(ModeHandler* handler, AppWindow* aw): connect(tabBar, &QTabBar::currentChanged, handler, &ModeHandler::setCurrentIndex); connect(tabBar, &QTabBar::tabCloseRequested, handler, &ModeHandler::closeMode); connect(tabBar, &QTabBar::tabMoved, handler, &ModeHandler::currentModeMoved); + connect(tabBar, &QTabBar::tabMoved, this, [=](int from, int to) { + std::swap(menuActions[from], menuActions[to]); + updateMenuActions(); + }); } ModeWindow::~ModeWindow() @@ -55,25 +60,53 @@ void ModeWindow::SetupUi() bAdd->setMaximumHeight(aw->menuBar()->height()); bAdd->setMaximumWidth(40); + auto createNew = [=](Mode::Type type) { + bool ok; + QString text = QInputDialog::getText(aw, + "Create new "+Mode::TypeToName(type)+" tab", + "Name:", QLineEdit::Normal, + Mode::TypeToName(type), &ok); + if(ok) { + if(!handler->nameAllowed(text)) { + InformationBox::ShowError("Name collision", "Unable to create tab, " \ + "no duplicate names allowed"); + } else { + handler->createMode(text, type); + } + } + }; + + menu = new QMenu("Mode"); + menu->setContextMenuPolicy(Qt::CustomContextMenu); + connect(menu, &QMenu::customContextMenuRequested, this, [=](const QPoint &p) { + auto action = menu->actionAt(p); + if(menuActions.contains(action)) { + QMenu contextMenu(tr("Context menu"), this); + QAction del("Delete", this); + connect(&del, &QAction::triggered, this, [=](){ + handler->closeMode(menuActions.indexOf(action)); + }); + contextMenu.addAction(&del); + contextMenu.exec(menu->mapToGlobal(p)); + } + }); + modeMenuGroup = new QActionGroup(menu); + menu->addSeparator(); + auto submenuAdd = new QMenu("Create new"); + menu->addMenu(submenuAdd); + auto mAdd = new QMenu(); for(unsigned int i=0;i<(int) Mode::Type::Last;i++) { auto type = (Mode::Type) i; auto action = new QAction(Mode::TypeToName(type)); mAdd->addAction(action); - connect(action, &QAction::triggered, [=](){ - bool ok; - QString text = QInputDialog::getText(aw, - "Create new "+Mode::TypeToName(type)+" tab", - "Name:", QLineEdit::Normal, - Mode::TypeToName(type), &ok); - if(ok) { - if(!handler->nameAllowed(text)) { - InformationBox::ShowError("Name collision", "Unable to create tab, " \ - "no duplicate names allowed"); - } else { - handler->createMode(text, type); - } - } + connect(action, &QAction::triggered, this, [=](){ + createNew(type); + }); + auto action2 = new QAction(Mode::TypeToName(type)); + submenuAdd->addAction(action2); + connect(action2, &QAction::triggered, this, [=](){ + createNew(type); }); } bAdd->setMenu(mAdd); @@ -83,6 +116,24 @@ void ModeWindow::SetupUi() aw->menuBar()->setCornerWidget(cornerWidget); } +void ModeWindow::updateMenuActions() +{ + // remove currently assigned actions from menu + while(!menu->actions()[0]->isSeparator()) { + menu->removeAction(menu->actions()[0]); + } + // add actions in correct order + auto before = menu->actions()[0]; + for(auto a : menuActions) { + menu->insertAction(before, a); + } +} + +QMenu *ModeWindow::getMenu() const +{ + return menu; +} + void ModeWindow::ModeCreated(int modeIndex) { auto mode = handler->getMode(modeIndex); @@ -91,6 +142,18 @@ void ModeWindow::ModeCreated(int modeIndex) { const auto name = mode->getName(); + auto action = new QAction(name, modeMenuGroup); + action->setCheckable(true); + action->setChecked(true); + menuActions.insert(modeIndex, action); + updateMenuActions(); + connect(action, &QAction::triggered, this, [=](){ + auto index = menuActions.indexOf(action); + if(index >= 0) { + tabBar->setCurrentIndex(index); + } + }); + tabBar->blockSignals(true); tabBar->insertTab(modeIndex, name); tabBar->blockSignals(false); @@ -104,6 +167,9 @@ void ModeWindow::ModeClosed(int modeIndex) tabBar->blockSignals(true); tabBar->removeTab(modeIndex); tabBar->blockSignals(false); + + delete menuActions.takeAt(modeIndex); + updateMenuActions(); } @@ -113,4 +179,5 @@ void ModeWindow::CurrentModeChanged(int modeIndex) { tabBar->setCurrentIndex(modeIndex); } + menuActions[modeIndex]->setChecked(true); } diff --git a/Software/PC_Application/LibreVNA-GUI/modewindow.h b/Software/PC_Application/LibreVNA-GUI/modewindow.h index 842f20e..eb468ad 100644 --- a/Software/PC_Application/LibreVNA-GUI/modewindow.h +++ b/Software/PC_Application/LibreVNA-GUI/modewindow.h @@ -3,6 +3,8 @@ #include "modehandler.h" +#include + class ModeWindow: public QWidget { Q_OBJECT @@ -10,11 +12,18 @@ public: explicit ModeWindow(ModeHandler* handler, AppWindow* aw); ~ModeWindow(); + QMenu *getMenu() const; + private: ModeHandler* handler; void SetupUi(); + + void updateMenuActions(); AppWindow* aw; QTabBar* tabBar; + QMenu *menu; + QList menuActions; + QActionGroup *modeMenuGroup; private slots: void ModeCreated(int modeIndex);