File indexing completed on 2024-04-28 04:36:29
0001 /* 0002 SPDX-FileCopyrightText: 2008 Andreas Pakulat <apaku@gmx.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "contextmenuextension.h" 0008 0009 #include <QMap> 0010 0011 #include <QMenu> 0012 #include <QAction> 0013 #include <QActionGroup> 0014 0015 #include <KLocalizedString> 0016 0017 namespace KDevelop 0018 { 0019 0020 const QString ContextMenuExtension::FileGroup = QStringLiteral("FileGroup"); 0021 const QString ContextMenuExtension::RefactorGroup = QStringLiteral("RefactorGroup"); 0022 const QString ContextMenuExtension::BuildGroup = QStringLiteral("BuildGroup"); 0023 const QString ContextMenuExtension::RunGroup = QStringLiteral("RunGroup"); 0024 const QString ContextMenuExtension::DebugGroup = QStringLiteral("DebugGroup"); 0025 const QString ContextMenuExtension::EditGroup = QStringLiteral("EditGroup"); 0026 const QString ContextMenuExtension::VcsGroup = QStringLiteral("VcsGroup"); 0027 const QString ContextMenuExtension::ProjectGroup = QStringLiteral("ProjectGroup"); 0028 const QString ContextMenuExtension::OpenEmbeddedGroup = QStringLiteral("OpenEmbeddedGroup"); 0029 const QString ContextMenuExtension::OpenExternalGroup = QStringLiteral("OpenExternalGroup"); 0030 const QString ContextMenuExtension::AnalyzeFileGroup = QStringLiteral("AnalyzeFileGroup"); 0031 const QString ContextMenuExtension::AnalyzeProjectGroup = QStringLiteral("AnalyzeProjectGroup"); 0032 const QString ContextMenuExtension::NavigationGroup = QStringLiteral("NavigationGroup"); 0033 const QString ContextMenuExtension::ExtensionGroup = QStringLiteral("ExtensionGroup"); 0034 0035 class ContextMenuExtensionPrivate 0036 { 0037 public: 0038 QMap<QString,QList<QAction*> > extensions; 0039 }; 0040 0041 ContextMenuExtension::ContextMenuExtension() 0042 : d_ptr(new ContextMenuExtensionPrivate) 0043 { 0044 } 0045 0046 ContextMenuExtension::~ContextMenuExtension() = default; 0047 0048 0049 ContextMenuExtension::ContextMenuExtension( const ContextMenuExtension& rhs ) 0050 : d_ptr(new ContextMenuExtensionPrivate) 0051 { 0052 Q_D(ContextMenuExtension); 0053 0054 d->extensions = rhs.d_func()->extensions; 0055 } 0056 0057 ContextMenuExtension& ContextMenuExtension::operator=( const ContextMenuExtension& rhs ) 0058 { 0059 Q_D(ContextMenuExtension); 0060 0061 if( this == &rhs ) 0062 return *this; 0063 0064 d->extensions = rhs.d_func()->extensions; 0065 return *this; 0066 } 0067 0068 QList<QAction*> ContextMenuExtension::actions( const QString& group ) const 0069 { 0070 Q_D(const ContextMenuExtension); 0071 0072 return d->extensions.value( group, QList<QAction*>() ); 0073 } 0074 0075 void ContextMenuExtension::addAction( const QString& group, QAction* action ) 0076 { 0077 Q_D(ContextMenuExtension); 0078 0079 auto actionGroupIt = d->extensions.find(group); 0080 if (actionGroupIt == d->extensions.end()) { 0081 d->extensions.insert( group, QList<QAction*>() << action ); 0082 } else 0083 { 0084 actionGroupIt->append(action); 0085 } 0086 } 0087 0088 static 0089 void populateMenuWithGroup( 0090 QMenu* menu, 0091 const QList<ContextMenuExtension>& extensions, 0092 const QString& groupName, 0093 const QString& groupDisplayName = QString(), 0094 const QString& groupIconName = QString(), 0095 bool forceAddMenu = false, 0096 bool addSeparator = true) 0097 { 0098 QList<QAction*> groupActions; 0099 for (const ContextMenuExtension& extension : extensions) { 0100 groupActions += extension.actions(groupName); 0101 } 0102 // remove NULL QActions, if any. Those can end up in groupActions if plugins 0103 // like the debugger plugins are not loaded. 0104 groupActions.removeAll(nullptr); 0105 0106 if (groupActions.isEmpty()) { 0107 return; 0108 } 0109 0110 QMenu* groupMenu = menu; 0111 if ((groupActions.count() > 1 && !groupDisplayName.isEmpty()) || 0112 (!groupDisplayName.isEmpty() && forceAddMenu)) { 0113 groupMenu = menu->addMenu(groupDisplayName); 0114 if (!groupIconName.isEmpty()) { 0115 groupMenu->setIcon(QIcon::fromTheme(groupIconName)); 0116 } 0117 } 0118 0119 for (QAction* action : qAsConst(groupActions)) { 0120 groupMenu->addAction(action); 0121 } 0122 0123 if (addSeparator) { 0124 menu->addSeparator(); 0125 } 0126 } 0127 0128 void ContextMenuExtension::populateMenu(QMenu* menu, const QList<ContextMenuExtension>& extensions) 0129 { 0130 populateMenuWithGroup(menu, extensions, BuildGroup); 0131 populateMenuWithGroup(menu, extensions, FileGroup); 0132 populateMenuWithGroup(menu, extensions, EditGroup); 0133 populateMenuWithGroup(menu, extensions, DebugGroup, i18nc("@title:menu", "Debug")); 0134 populateMenuWithGroup(menu, extensions, RefactorGroup, i18nc("@title:menu", "Refactor")); 0135 populateMenuWithGroup(menu, extensions, NavigationGroup); 0136 populateMenuWithGroup(menu, extensions, AnalyzeFileGroup, i18nc("@title:menu", "Analyze Current File With"), QStringLiteral("dialog-ok"), true, false); 0137 populateMenuWithGroup(menu, extensions, AnalyzeProjectGroup, i18nc("@title:menu", "Analyze Current Project With"), QStringLiteral("dialog-ok"), true); 0138 populateMenuWithGroup(menu, extensions, VcsGroup); 0139 populateMenuWithGroup(menu, extensions, ExtensionGroup); 0140 } 0141 0142 }