File indexing completed on 2024-04-28 04:34:21
0001 /*************************************************************************** 0002 * Copyright 2009 Sandro Andrade <sandroandrade@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU Library General Public License as * 0006 * published by the Free Software Foundation; either version 2 of the * 0007 * License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU Library General Public * 0015 * License along with this program; if not, write to the * 0016 * Free Software Foundation, Inc., * 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0018 ***************************************************************************/ 0019 0020 #include "controlflowgraphview.h" 0021 0022 #include <QGraphicsView> 0023 #include <QGraphicsScene> 0024 #include <QFontMetricsF> 0025 0026 #include <KLibLoader> 0027 #include <KMessageBox> 0028 #include <KParts/Part> 0029 #include <KActionCollection> 0030 0031 #include <interfaces/icore.h> 0032 #include <interfaces/iuicontroller.h> 0033 #include <interfaces/iprojectcontroller.h> 0034 0035 #include "duchaincontrolflow.h" 0036 #include "dotcontrolflowgraph.h" 0037 #include "controlflowgraphfiledialog.h" 0038 #include "kdevcontrolflowgraphviewplugin.h" 0039 0040 using namespace KDevelop; 0041 0042 ControlFlowGraphView::ControlFlowGraphView(KDevControlFlowGraphViewPlugin *plugin, QWidget *parent) 0043 : 0044 QWidget(parent), 0045 m_plugin(plugin), 0046 m_part(0), 0047 m_dotControlFlowGraph(new DotControlFlowGraph), 0048 m_duchainControlFlow(new DUChainControlFlow(m_dotControlFlowGraph)), 0049 m_graphLocked(false) 0050 { 0051 setupUi(this); 0052 KLibFactory *factory = KLibLoader::self()->factory("kgraphviewerpart"); 0053 if (factory) 0054 { 0055 m_part = factory->create<KParts::ReadOnlyPart>("kgraphviewerpart", this); 0056 if (m_part) 0057 { 0058 QMetaObject::invokeMethod(m_part, "setReadWrite"); 0059 0060 verticalLayout->addWidget(m_part->widget()); 0061 0062 modeFunctionToolButton->setIcon(KIcon("code-function")); 0063 modeClassToolButton->setIcon(KIcon("code-class")); 0064 modeNamespaceToolButton->setIcon(KIcon("namespace")); 0065 clusteringClassToolButton->setIcon(KIcon("code-class")); 0066 clusteringNamespaceToolButton->setIcon(KIcon("namespace")); 0067 clusteringProjectToolButton->setIcon(KIcon("folder-development")); 0068 useFolderNameToolButton->setIcon(KIcon("folder-favorites")); 0069 drawIncomingArcsToolButton->setIcon(KIcon("draw-arrow-down")); 0070 maxLevelToolButton->setIcon(KIcon("zoom-fit-height")); 0071 exportToolButton->setIcon(KIcon("document-export")); 0072 m_duchainControlFlow->setMaxLevel(2); 0073 0074 birdseyeToolButton->setIcon(KIcon("edit-find")); 0075 usesHoverToolButton->setIcon(KIcon("input-mouse")); 0076 zoominToolButton->setIcon(KIcon("zoom-in")); 0077 zoomoutToolButton->setIcon(KIcon("zoom-out")); 0078 0079 if (ICore::self()->projectController()->projectCount() > 0) 0080 setProjectButtonsEnabled(true); 0081 0082 useShortNamesToolButton->setIcon(KIcon("application-x-arc")); 0083 updateLockIcon(lockControlFlowGraphToolButton->isChecked()); 0084 0085 // Control flow mode buttons signals 0086 connect(modeFunctionToolButton, SIGNAL(toggled(bool)), SLOT(setControlFlowFunction(bool))); 0087 connect(modeClassToolButton, SIGNAL(toggled(bool)), SLOT(setControlFlowClass(bool))); 0088 connect(modeNamespaceToolButton, SIGNAL(toggled(bool)), SLOT(setControlFlowNamespace(bool))); 0089 0090 // Clustering buttons signals 0091 connect(clusteringClassToolButton, SIGNAL(toggled(bool)), SLOT(setClusteringClass(bool))); 0092 connect(clusteringNamespaceToolButton, SIGNAL(toggled(bool)), SLOT(setClusteringNamespace(bool))); 0093 connect(clusteringProjectToolButton, SIGNAL(toggled(bool)), SLOT(setClusteringProject(bool))); 0094 0095 // Configuration buttons signals 0096 connect(maxLevelSpinBox, SIGNAL(valueChanged(int)), SLOT(setMaxLevel(int))); 0097 connect(maxLevelToolButton, SIGNAL(toggled(bool)), SLOT(setUseMaxLevel(bool))); 0098 connect(drawIncomingArcsToolButton, SIGNAL(toggled(bool)), SLOT(setDrawIncomingArcs(bool))); 0099 connect(useFolderNameToolButton, SIGNAL(toggled(bool)), SLOT(setUseFolderName(bool))); 0100 connect(useShortNamesToolButton, SIGNAL(toggled(bool)), SLOT(setUseShortNames(bool))); 0101 connect(lockControlFlowGraphToolButton, SIGNAL(toggled(bool)), SLOT(updateLockIcon(bool))); 0102 0103 // Left buttons signals 0104 connect(zoomoutToolButton, SIGNAL(clicked()), m_part->actionCollection()->action("view_zoom_out"), SIGNAL(triggered())); 0105 connect(zoominToolButton, SIGNAL(clicked()), m_part->actionCollection()->action("view_zoom_in"), SIGNAL(triggered())); 0106 m_part->actionCollection()->action("view_bev_enabled")->setIcon(KIcon("edit-find.png")); 0107 m_part->actionCollection()->action("view_bev_enabled")->setChecked(false); 0108 birdseyeToolButton->setDefaultAction(m_part->actionCollection()->action("view_bev_enabled")); 0109 connect(m_part, SIGNAL(selectionIs(QList<QString>, QPoint&)), 0110 m_duchainControlFlow, SLOT(slotGraphElementSelected(QList<QString>,QPoint))); 0111 connect(m_part, SIGNAL(hoverEnter(QString)), m_duchainControlFlow, SLOT(slotEdgeHover(QString))); 0112 connect(exportToolButton, SIGNAL(clicked()), SLOT(exportControlFlowGraph())); 0113 connect(usesHoverToolButton, SIGNAL(toggled(bool)), m_duchainControlFlow, SLOT(setShowUsesOnEdgeHover(bool))); 0114 0115 // Make sure we have a graph before we hook up signals to act on it 0116 m_dotControlFlowGraph->prepareNewGraph(); 0117 0118 // Graph generation signals 0119 connect(m_dotControlFlowGraph, SIGNAL(loadLibrary(graph_t*)), m_part, SLOT(slotLoadLibrary(graph_t*))); 0120 connect(m_duchainControlFlow, SIGNAL(startingJob()), SLOT(startingJob())); 0121 connect(m_duchainControlFlow, SIGNAL(jobDone()), SLOT(graphDone())); 0122 0123 m_plugin->registerToolView(this); 0124 } 0125 else 0126 KMessageBox::error((QWidget *) m_plugin->core()->uiController()->activeMainWindow(), i18n("Could not load the KGraphViewer kpart")); 0127 } 0128 else 0129 KMessageBox::error((QWidget *) m_plugin->core()->uiController()->activeMainWindow(), i18n("Could not find the KGraphViewer factory") + ": " + KLibLoader::self()->lastErrorMessage()); 0130 } 0131 0132 ControlFlowGraphView::~ControlFlowGraphView() 0133 { 0134 m_plugin->unRegisterToolView(this); 0135 delete m_duchainControlFlow; 0136 delete m_dotControlFlowGraph; 0137 delete m_part; 0138 } 0139 0140 void ControlFlowGraphView::refreshGraph() 0141 { 0142 m_duchainControlFlow->refreshGraph(); 0143 } 0144 0145 void ControlFlowGraphView::newGraph() 0146 { 0147 m_duchainControlFlow->newGraph(); 0148 } 0149 0150 void ControlFlowGraphView::setProjectButtonsEnabled(bool enabled) 0151 { 0152 useFolderNameToolButton->setEnabled(enabled); 0153 clusteringProjectToolButton->setEnabled(enabled); 0154 } 0155 0156 void ControlFlowGraphView::cursorPositionChanged(KTextEditor::View *view, const KTextEditor::Cursor &cursor) 0157 { 0158 m_duchainControlFlow->cursorPositionChanged(view, cursor); 0159 } 0160 0161 void ControlFlowGraphView::startingJob() 0162 { 0163 setEnabled(false); 0164 } 0165 0166 void ControlFlowGraphView::graphDone() 0167 { 0168 setEnabled(true); 0169 } 0170 0171 void ControlFlowGraphView::exportControlFlowGraph() 0172 { 0173 QPointer<ControlFlowGraphFileDialog> fileDialog; 0174 if ((fileDialog = m_plugin->exportControlFlowGraph(ControlFlowGraphFileDialog::NoConfigurationButtons))) 0175 { 0176 m_dotControlFlowGraph->exportGraph(fileDialog->selectedFile()); 0177 KMessageBox::information(this, i18n("Control flow graph exported"), i18n("Export Control Flow Graph")); 0178 } 0179 } 0180 0181 void ControlFlowGraphView::updateLockIcon(bool checked) 0182 { 0183 lockControlFlowGraphToolButton->setIcon(KIcon(checked ? "document-encrypt":"document-decrypt")); 0184 lockControlFlowGraphToolButton->setToolTip(checked ? i18n("Unlock control flow graph"):i18n("Lock control flow graph")); 0185 m_duchainControlFlow->setLocked(checked); 0186 m_graphLocked = checked; 0187 if (!checked) 0188 m_duchainControlFlow->refreshGraph(); 0189 } 0190 0191 void ControlFlowGraphView::setControlFlowClass(bool checked) 0192 { 0193 if (checked) 0194 { 0195 m_duchainControlFlow->setControlFlowMode(DUChainControlFlow::ControlFlowClass); 0196 m_duchainControlFlow->refreshGraph(); 0197 clusteringClassToolButton->setChecked(false); 0198 clusteringClassToolButton->setEnabled(false); 0199 clusteringNamespaceToolButton->setEnabled(true); 0200 } 0201 } 0202 0203 void ControlFlowGraphView::setControlFlowFunction(bool checked) 0204 { 0205 if (checked) 0206 { 0207 m_duchainControlFlow->setControlFlowMode(DUChainControlFlow::ControlFlowFunction); 0208 m_duchainControlFlow->refreshGraph(); 0209 clusteringClassToolButton->setEnabled(true); 0210 clusteringNamespaceToolButton->setEnabled(true); 0211 } 0212 } 0213 0214 void ControlFlowGraphView::setControlFlowNamespace(bool checked) 0215 { 0216 if (checked) 0217 { 0218 m_duchainControlFlow->setControlFlowMode(DUChainControlFlow::ControlFlowNamespace); 0219 m_duchainControlFlow->refreshGraph(); 0220 clusteringClassToolButton->setChecked(false); 0221 clusteringClassToolButton->setEnabled(false); 0222 clusteringNamespaceToolButton->setChecked(false); 0223 clusteringNamespaceToolButton->setEnabled(false); 0224 } 0225 } 0226 0227 void ControlFlowGraphView::setClusteringClass(bool checked) 0228 { 0229 Q_UNUSED(checked); 0230 m_duchainControlFlow->setClusteringModes(m_duchainControlFlow->clusteringModes() ^ DUChainControlFlow::ClusteringClass); 0231 m_duchainControlFlow->refreshGraph(); 0232 useShortNamesToolButton->setEnabled(m_duchainControlFlow->clusteringModes() ? true:false); 0233 } 0234 0235 void ControlFlowGraphView::setClusteringProject(bool checked) 0236 { 0237 Q_UNUSED(checked); 0238 m_duchainControlFlow->setClusteringModes(m_duchainControlFlow->clusteringModes() ^ DUChainControlFlow::ClusteringProject); 0239 m_duchainControlFlow->refreshGraph(); 0240 useShortNamesToolButton->setEnabled(m_duchainControlFlow->clusteringModes() ? true:false); 0241 } 0242 0243 void ControlFlowGraphView::setClusteringNamespace(bool checked) 0244 { 0245 Q_UNUSED(checked); 0246 m_duchainControlFlow->setClusteringModes(m_duchainControlFlow->clusteringModes() ^ DUChainControlFlow::ClusteringNamespace); 0247 m_duchainControlFlow->refreshGraph(); 0248 useShortNamesToolButton->setEnabled(m_duchainControlFlow->clusteringModes() ? true:false); 0249 } 0250 0251 void ControlFlowGraphView::setUseMaxLevel(bool checked) 0252 { 0253 maxLevelSpinBox->setEnabled(checked); 0254 setMaxLevel(checked ? maxLevelSpinBox->value():0); 0255 } 0256 0257 void ControlFlowGraphView::setMaxLevel(int value) 0258 { 0259 m_duchainControlFlow->setMaxLevel(value); 0260 m_duchainControlFlow->refreshGraph(); 0261 } 0262 0263 void ControlFlowGraphView::setDrawIncomingArcs(bool checked) 0264 { 0265 m_duchainControlFlow->setDrawIncomingArcs(checked); 0266 m_duchainControlFlow->refreshGraph(); 0267 } 0268 0269 void ControlFlowGraphView::setUseFolderName(bool checked) 0270 { 0271 m_duchainControlFlow->setUseFolderName(checked); 0272 m_duchainControlFlow->refreshGraph(); 0273 } 0274 0275 void ControlFlowGraphView::setUseShortNames(bool checked) 0276 { 0277 m_duchainControlFlow->setUseShortNames(checked); 0278 m_duchainControlFlow->refreshGraph(); 0279 } 0280 0281 void ControlFlowGraphView::showEvent(QShowEvent *event) 0282 { 0283 Q_UNUSED(event); 0284 m_plugin->setActiveToolView(this); 0285 } 0286 0287 void ControlFlowGraphView::hideEvent(QHideEvent *event) 0288 { 0289 Q_UNUSED(event); 0290 m_plugin->setActiveToolView(0); 0291 }