void QtMenuBar::addAction(IAction& action, const char* path) { auto qAction = getQAction(action); if (qAction == nullptr) { qAction = createQAction(action); } assert(qAction != nullptr); path = relativePath(path); if (path == nullptr || strlen(path) == 0) { path = action.text(); } auto tok = strchr(path, '.'); auto menuPath = tok != nullptr ? QString::fromUtf8(path, tok - path) : path; QMenu* menu = qMenuBar_.findChild<QMenu*>(menuPath, Qt::FindDirectChildrenOnly); if (menu == nullptr) { menu = qMenuBar_.addMenu(menuPath); menu->setObjectName(menuPath); } path = tok != nullptr ? tok + 1 : nullptr; QtMenu::addMenuAction(*menu, *qAction, path); qMenuBar_.repaint(); }
void QtMenuBar::removeAction(IAction& action) { auto qAction = getQAction(action); if (qAction == nullptr) { NGT_ERROR_MSG("Target action '%s' '%s' does not exist\n", action.text(), StringUtils::join(action.paths(), ';').c_str()); return; } auto menus = qMenuBar_.findChildren<QMenu*>(QString(), Qt::FindDirectChildrenOnly); for (auto& menu : menus) { QtMenu::removeMenuAction(*menu, *qAction); if (menu->isEmpty()) { delete menu; } } destroyQAction(action); }
QSharedPointer<QAction> QtMenu::createSharedQAction(IAction& action) { auto qAction = getSharedQAction(action); if (qAction) { return qAction; } qAction.reset(new QForwardingAction(action.text(), QApplication::instance()), &QObject::deleteLater); sharedQActions_[&action] = qAction; qAction->setProperty("order", action.order()); qAction->setEnabled(action.enabled()); qAction->setVisible(action.visible()); if (action.isSeparator()) { qAction->setSeparator(true); } else { std::vector<QIcon> qIcons; auto icons = StringUtils::split(std::string(action.icon()), '|'); for(auto& icon : icons) { StringUtils::trim_string(icon); qIcons.push_back(QtMenu_Locals::generateIcon(icon.c_str())); } if(!qIcons.empty()) { qAction->setIcon(qIcons[0]); } qAction->setShortcut(QKeySequence(action.shortcut())); if (action.isCheckable()) { qAction->setCheckable(true); qAction->setChecked(action.checked()); } QObject::connect(qAction.data(), &QAction::triggered, [&action]() { if (!action.enabled()) { return; } action.execute(); }); connections_[&action] = action.signalShortcutChanged.connect([qAction](const char* shortcut) { TF_ASSERT(qAction != nullptr); qAction->setShortcut(QKeySequence(shortcut)); }); connections_[&action] = action.signalTextChanged.connect([qAction](const char* text) { TF_ASSERT(qAction != nullptr); qAction->setText(text); }); connections_[&action] = action.signalVisibilityChanged.connect([qAction](bool visible) { TF_ASSERT(qAction != nullptr); qAction->setVisible(visible); }); connections_[&action] = action.signalIconChanged.connect([qAction, qIcons](int index) { TF_ASSERT(qAction != nullptr); if(index >= 0 && index < (int)qIcons.size()) { qAction->setIcon(qIcons[index]); } }); const std::string groupID(action.group()); if (!groupID.empty()) { auto itr = groups_.find(groupID); if (itr == groups_.end()) { groups_[groupID].reset(new QActionGroup(&menu_)); } groups_.at(groupID)->addAction(qAction.data()); TF_ASSERT(qAction->actionGroup()); } } return qAction; }