diff --git a/gui/include/Visualization/operations/MenuBuilder.h b/gui/include/Visualization/operations/MenuBuilder.h new file mode 100644 index 0000000..d5ee390 --- /dev/null +++ b/gui/include/Visualization/operations/MenuBuilder.h @@ -0,0 +1,59 @@ +#ifndef SCIQLOP_MENUBUILDER_H +#define SCIQLOP_MENUBUILDER_H + +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(LOG_MenuBuilder) + +/// Helper assigned to build a hierarchical menu +class MenuBuilder { +public: + /** + * Ctor + * @param menu the parent menu + */ + explicit MenuBuilder(QMenu *menu); + + /** + * Adds action to the current menu + * @param actionName the name of the action + * @param actionFunction the function that will be executed when the action is triggered + */ + template + void addAction(const QString &actionName, ActionFun actionFunction); + + /** + * Adds a new menu to the current menu + * @param name the name of the menu + */ + void addMenu(const QString &name); + + /// Adds a separator to the current menu. The separator is added only if the menu already + /// contains entries + void addSeparator(); + + /// Closes the current menu + void closeMenu(); + +private: + /// @return the current menu (i.e. the top menu of the stack), nullptr if there is no menu + QMenu *currentMenu() const; + + /// Stack of all menus currently opened + QStack m_Menus{}; +}; + +template +void MenuBuilder::addAction(const QString &actionName, ActionFun actionFunction) +{ + if (auto currMenu = currentMenu()) { + currMenu->addAction(actionName, actionFunction); + } + else { + qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the action"); + } +} + +#endif // SCIQLOP_MENUBUILDER_H diff --git a/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp b/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp index 6842a59..2bd5ae2 100644 --- a/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp +++ b/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp @@ -1,4 +1,5 @@ #include "Visualization/operations/GenerateVariableMenuOperation.h" +#include "Visualization/operations/MenuBuilder.h" #include "Visualization/VisualizationGraphWidget.h" #include "Visualization/VisualizationTabWidget.h" @@ -11,97 +12,6 @@ Q_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation, "GenerateVariableMenuOperation") -namespace { - -/// Helper assigned to build the hierarchical menu associated with a variable -struct MenuBuilder { - /** - * Ctor - * @param menu the parent menu - */ - explicit MenuBuilder(QMenu *menu) - { - if (menu) { - m_Menus.push(menu); - } - else { - qCCritical(LOG_GenerateVariableMenuOperation()) - << QObject::tr("No parent menu has been defined"); - } - } - - /** - * Adds action to the current menu - * @param actionName the name of the action - * @param actionFunction the function that will be executed when the action is triggered - */ - template - void addAction(const QString &actionName, ActionFun actionFunction) - { - if (auto currMenu = currentMenu()) { - currMenu->addAction(actionName, actionFunction); - } - else { - qCCritical(LOG_GenerateVariableMenuOperation()) - << QObject::tr("No current menu to attach the action"); - } - } - - /** - * Adds a new menu to the current menu - * @param name the name of the menu - */ - void addMenu(const QString &name) - { - if (auto currMenu = currentMenu()) { - m_Menus.push(currMenu->addMenu(name)); - } - else { - qCCritical(LOG_GenerateVariableMenuOperation()) - << QObject::tr("No current menu to attach the new menu"); - } - } - - /// Adds a separator to the current menu. The separator is added only if the menu already - /// contains entries - void addSeparator() - { - if (auto currMenu = currentMenu()) { - if (!currMenu->isEmpty()) { - currMenu->addSeparator(); - } - } - else { - qCCritical(LOG_GenerateVariableMenuOperation()) - << QObject::tr("No current menu to attach the separator"); - } - } - - /// Closes the current menu - void closeMenu() - { - if (!m_Menus.isEmpty()) { - if (auto closedMenu = m_Menus.pop()) { - // Purge menu : if the closed menu has no entries, we remove it from its parent (the - // current menu) - if (auto currMenu = currentMenu()) { - if (closedMenu->isEmpty()) { - currMenu->removeAction(closedMenu->menuAction()); - } - } - } - } - } - - /// @return the current menu (i.e. the top menu of the stack), nullptr if there is no menu - QMenu *currentMenu() const { return !m_Menus.isEmpty() ? m_Menus.top() : nullptr; } - - /// Stack of all menus currently opened - QStack m_Menus{}; -}; - -} // namespace - struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate { explicit GenerateVariableMenuOperationPrivate(QMenu *menu, std::shared_ptr variable) : m_Variable{variable}, m_MenuBuilder{menu} diff --git a/gui/src/Visualization/operations/MenuBuilder.cpp b/gui/src/Visualization/operations/MenuBuilder.cpp new file mode 100644 index 0000000..23b8e01 --- /dev/null +++ b/gui/src/Visualization/operations/MenuBuilder.cpp @@ -0,0 +1,55 @@ +#include "Visualization/operations/MenuBuilder.h" + +Q_LOGGING_CATEGORY(LOG_MenuBuilder, "MenuBuilder") + +MenuBuilder::MenuBuilder(QMenu *menu) +{ + if (menu) { + m_Menus.push(menu); + } + else { + qCCritical(LOG_MenuBuilder()) << QObject::tr("No parent menu has been defined"); + } +} + +void MenuBuilder::addMenu(const QString &name) +{ + if (auto currMenu = currentMenu()) { + m_Menus.push(currMenu->addMenu(name)); + } + else { + qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the new menu"); + } +} + +void MenuBuilder::addSeparator() +{ + if (auto currMenu = currentMenu()) { + if (!currMenu->isEmpty()) { + currMenu->addSeparator(); + } + } + else { + qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the separator"); + } +} + +void MenuBuilder::closeMenu() +{ + if (!m_Menus.isEmpty()) { + if (auto closedMenu = m_Menus.pop()) { + // Purge menu : if the closed menu has no entries, we remove it from its parent (the + // current menu) + if (auto currMenu = currentMenu()) { + if (closedMenu->isEmpty()) { + currMenu->removeAction(closedMenu->menuAction()); + } + } + } + } +} + +QMenu *MenuBuilder::currentMenu() const +{ + return !m_Menus.isEmpty() ? m_Menus.top() : nullptr; +}