diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5b77fd7..c684785 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,83 +1,85 @@
cmake_minimum_required(VERSION 3.0)
project(controlflowgraph)
set(QT_MIN_VERSION "5.7.0")
set(KF_MIN_VERSION "5.28.0")
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(FeatureSummary)
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED
Core
Widgets
)
find_package(KF5 ${KF_MIN_VERSION} REQUIRED COMPONENTS
I18n
TextEditor
ThreadWeaver
ConfigWidgets
ItemModels
)
find_package(KDevPlatform 5.3.40 )
set_package_properties(KDevPlatform PROPERTIES
TYPE REQUIRED
)
find_package(GraphViz)
set_package_properties(GraphViz PROPERTIES
TYPE REQUIRED
)
add_definitions(
-DQT_DEPRECATED_WARNINGS
-DQT_DISABLE_DEPRECATED_BEFORE=0x050700
-DQT_NO_SIGNALS_SLOTS_KEYWORDS
-DQT_NO_URL_CAST_FROM_STRING
+ -DQT_NO_CAST_FROM_ASCII
-DQT_NO_CAST_TO_ASCII
-DQT_NO_CAST_FROM_BYTEARRAY
+ -DQT_USE_QSTRINGBUILDER
-DQT_STRICT_ITERATORS
-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT
)
include_directories(
${GraphViz_INCLUDE_DIRECTORIES}
)
set(kdevcontrolflowgraphview_PART_SRCS
kdevcontrolflowgraphviewplugin.cpp
controlflowgraphview.cpp
duchaincontrolflow.cpp
dotcontrolflowgraph.cpp
duchaincontrolflowjob.cpp
duchaincontrolflowinternaljob.cpp
controlflowgraphnavigationcontext.cpp
controlflowgraphnavigationwidget.cpp
controlflowgraphusescollector.cpp
controlflowgraphfiledialog.cpp
)
set(kdevcontrolflowgraphview_PART_UI
controlflowgraphview.ui
controlflowgraphexportconfiguration.ui
)
ki18n_wrap_ui(kdevcontrolflowgraphview_PART_SRCS ${kdevcontrolflowgraphview_PART_UI})
kdevplatform_add_plugin(kdevcontrolflowgraphview JSON kdevcontrolflowgraphview.json SOURCES ${kdevcontrolflowgraphview_PART_SRCS})
target_link_libraries(kdevcontrolflowgraphview
KF5::Parts
KF5::TextEditor
KF5::ThreadWeaver
KDev::Interfaces
KDev::Language
KDev::Project
KDev::Util
gvc cgraph cdt)
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/controlflowgraphfiledialog.cpp b/controlflowgraphfiledialog.cpp
index 93685b9..c06281e 100644
--- a/controlflowgraphfiledialog.cpp
+++ b/controlflowgraphfiledialog.cpp
@@ -1,185 +1,183 @@
/***************************************************************************
* Copyright 2009 Sandro Andrade *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "controlflowgraphfiledialog.h"
#include
#include
#include
#include "ui_controlflowgraphexportconfiguration.h"
using namespace KDevelop;
ControlFlowGraphFileDialog::ControlFlowGraphFileDialog(QWidget *parent, OpeningMode mode) :
QFileDialog(parent, i18n("Export Control Flow Graph")),
m_configurationWidget(nullptr)
{
- QStringList mimeTypes;
- mimeTypes << "image/png"
- << "image/jpeg"
- << "image/gif"
- << "image/svg+xml"
- << "image/svg+xml-compressed"
- << "application/x-dia-diagram"
- << "image/x-xfig"
- << "application/pdf"
- << "text/vnd.graphviz";
+ const QStringList mimeTypes {
+ QStringLiteral("image/png"),
+ QStringLiteral("image/jpeg"),
+ QStringLiteral("image/gif"),
+ QStringLiteral("image/svg+xml"),
+ QStringLiteral("image/svg+xml-compressed"),
+ QStringLiteral("application/x-dia-diagram"),
+ QStringLiteral("image/x-xfig"),
+ QStringLiteral("application/pdf"),
+ QStringLiteral("text/vnd.graphviz"),
+ };
setMimeTypeFilters(mimeTypes);
setAcceptMode(QFileDialog::AcceptSave);
setFileMode(QFileDialog::AnyFile);
if (mode != NoConfigurationButtons)
{
m_configurationWidget = new Ui::ControlFlowGraphExportConfiguration;
QWidget *widget = new QWidget;
m_configurationWidget->setupUi(widget);
- m_configurationWidget->controlFlowFunctionRadioButton->setIcon(QIcon::fromTheme("flag-blue"));
- m_configurationWidget->controlFlowClassRadioButton->setIcon(QIcon::fromTheme("flag-green"));
- m_configurationWidget->controlFlowNamespaceRadioButton->setIcon(QIcon::fromTheme("flag-red"));
- m_configurationWidget->clusteringClassCheckBox->setIcon(QIcon::fromTheme("code-class"));
- m_configurationWidget->clusteringNamespaceCheckBox->setIcon(QIcon::fromTheme("namespace"));
- m_configurationWidget->clusteringProjectCheckBox->setIcon(QIcon::fromTheme("folder-development"));
- m_configurationWidget->limitMaxLevelCheckBox->setIcon(QIcon::fromTheme("zoom-fit-height"));
- m_configurationWidget->drawIncomingArcsCheckBox->setIcon(QIcon::fromTheme("draw-arrow-down"));
- m_configurationWidget->useFolderNameCheckBox->setIcon(QIcon::fromTheme("folder-favorites"));
- m_configurationWidget->useShortNamesCheckBox->setIcon(QIcon::fromTheme("application-x-arc"));
+ m_configurationWidget->controlFlowFunctionRadioButton->setIcon(QIcon::fromTheme(QStringLiteral("flag-blue")));
+ m_configurationWidget->controlFlowClassRadioButton->setIcon(QIcon::fromTheme(QStringLiteral("flag-green")));
+ m_configurationWidget->controlFlowNamespaceRadioButton->setIcon(QIcon::fromTheme(QStringLiteral("flag-red")));
+ m_configurationWidget->clusteringClassCheckBox->setIcon(QIcon::fromTheme(QStringLiteral("code-class")));
+ m_configurationWidget->clusteringNamespaceCheckBox->setIcon(QIcon::fromTheme(QStringLiteral("namespace")));
+ m_configurationWidget->clusteringProjectCheckBox->setIcon(QIcon::fromTheme(QStringLiteral("folder-development")));
+ m_configurationWidget->limitMaxLevelCheckBox->setIcon(QIcon::fromTheme(QStringLiteral("zoom-fit-height")));
+ m_configurationWidget->drawIncomingArcsCheckBox->setIcon(QIcon::fromTheme(QStringLiteral("draw-arrow-down")));
+ m_configurationWidget->useFolderNameCheckBox->setIcon(QIcon::fromTheme(QStringLiteral("folder-favorites")));
+ m_configurationWidget->useShortNamesCheckBox->setIcon(QIcon::fromTheme(QStringLiteral("application-x-arc")));
connect(m_configurationWidget->controlFlowFunctionRadioButton, &QRadioButton::toggled,
this, &ControlFlowGraphFileDialog::setControlFlowMode);
connect(m_configurationWidget->controlFlowClassRadioButton, &QRadioButton::toggled,
this, &ControlFlowGraphFileDialog::setControlFlowMode);
connect(m_configurationWidget->controlFlowNamespaceRadioButton, &QRadioButton::toggled,
this, &ControlFlowGraphFileDialog::setControlFlowMode);
connect(m_configurationWidget->clusteringClassCheckBox, &QCheckBox::stateChanged,
this, &ControlFlowGraphFileDialog::setClusteringModes);
connect(m_configurationWidget->clusteringNamespaceCheckBox, &QCheckBox::stateChanged,
this, &ControlFlowGraphFileDialog::setClusteringModes);
connect(m_configurationWidget->clusteringProjectCheckBox, &QCheckBox::stateChanged,
this, &ControlFlowGraphFileDialog::setClusteringModes);
connect(m_configurationWidget->limitMaxLevelCheckBox, &QCheckBox::stateChanged,
this, &ControlFlowGraphFileDialog::slotLimitMaxLevelChanged);
if (ICore::self()->projectController()->projectCount() > 0)
{
m_configurationWidget->clusteringProjectCheckBox->setEnabled(true);
m_configurationWidget->useFolderNameCheckBox->setEnabled(true);
}
// TODO: care about native non-Qt filedialog
if (layout()) {
layout()->addWidget(widget);
} else {
qWarning() << "No access to layout of QFileDialog, cannot add custom widget";
}
}
}
ControlFlowGraphFileDialog::~ControlFlowGraphFileDialog()
{
delete m_configurationWidget;
}
DUChainControlFlow::ControlFlowMode ControlFlowGraphFileDialog::controlFlowMode() const
{
return (m_configurationWidget->controlFlowFunctionRadioButton->isChecked() ?
DUChainControlFlow::ControlFlowFunction :
((m_configurationWidget->controlFlowClassRadioButton->isChecked()) ?
DUChainControlFlow::ControlFlowClass : DUChainControlFlow::ControlFlowNamespace)
);
}
DUChainControlFlow::ClusteringModes ControlFlowGraphFileDialog::clusteringModes() const
{
DUChainControlFlow::ClusteringModes clusteringModes;
if (m_configurationWidget->clusteringClassCheckBox->isChecked())
clusteringModes |= DUChainControlFlow::ClusteringClass;
if (m_configurationWidget->clusteringNamespaceCheckBox->isChecked())
clusteringModes |= DUChainControlFlow::ClusteringNamespace;
if (m_configurationWidget->clusteringProjectCheckBox->isChecked())
clusteringModes |= DUChainControlFlow::ClusteringProject;
return clusteringModes;
}
int ControlFlowGraphFileDialog::maxLevel() const
{
if (m_configurationWidget->limitMaxLevelCheckBox->isChecked())
return m_configurationWidget->maxLevelSpinBox->value();
else
return 0;
}
bool ControlFlowGraphFileDialog::useFolderName() const
{
return m_configurationWidget->useFolderNameCheckBox->isChecked();
}
bool ControlFlowGraphFileDialog::useShortNames() const
{
return m_configurationWidget->useShortNamesCheckBox->isChecked();
}
bool ControlFlowGraphFileDialog::drawIncomingArcs() const
{
return m_configurationWidget->drawIncomingArcsCheckBox->isChecked();
}
void ControlFlowGraphFileDialog::setControlFlowMode(bool checked)
{
if (checked)
{
QRadioButton *radioButton = qobject_cast(sender());
- if (radioButton->objectName() == "controlFlowFunctionRadioButton")
- {
+ if (radioButton->objectName() == QLatin1String("controlFlowFunctionRadioButton")) {
m_configurationWidget->clusteringClassCheckBox->setEnabled(true);
m_configurationWidget->clusteringNamespaceCheckBox->setEnabled(true);
}
- if (radioButton->objectName() == "controlFlowClassRadioButton")
- {
+ if (radioButton->objectName() == QLatin1String("controlFlowClassRadioButton")) {
m_configurationWidget->clusteringClassCheckBox->setChecked(false);
m_configurationWidget->clusteringClassCheckBox->setEnabled(false);
m_configurationWidget->clusteringNamespaceCheckBox->setEnabled(true);
}
- if (radioButton->objectName() == "controlFlowNamespaceRadioButton")
- {
+ if (radioButton->objectName() == QLatin1String("controlFlowNamespaceRadioButton")) {
m_configurationWidget->clusteringClassCheckBox->setChecked(false);
m_configurationWidget->clusteringClassCheckBox->setEnabled(false);
m_configurationWidget->clusteringNamespaceCheckBox->setChecked(false);
m_configurationWidget->clusteringNamespaceCheckBox->setEnabled(false);
}
}
}
void ControlFlowGraphFileDialog::setClusteringModes(int state)
{
Q_UNUSED(state);
m_configurationWidget->useShortNamesCheckBox->setEnabled(m_configurationWidget->clusteringClassCheckBox->isChecked() ||
m_configurationWidget->clusteringNamespaceCheckBox->isChecked() ||
m_configurationWidget->clusteringProjectCheckBox->isChecked());
}
void ControlFlowGraphFileDialog::slotLimitMaxLevelChanged(int state)
{
m_configurationWidget->maxLevelSpinBox->setEnabled((state == Qt::Checked) ? true:false);
}
diff --git a/controlflowgraphnavigationcontext.cpp b/controlflowgraphnavigationcontext.cpp
index 9d9dcc6..8f8eb92 100644
--- a/controlflowgraphnavigationcontext.cpp
+++ b/controlflowgraphnavigationcontext.cpp
@@ -1,87 +1,87 @@
/***************************************************************************
* Copyright 2009 Sandro Andrade *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "controlflowgraphnavigationcontext.h"
#include
#include
#include
#include
#include
#include
using namespace KDevelop;
ControlFlowGraphNavigationContext::ControlFlowGraphNavigationContext(const QString &label, const ArcUses &arcUses, TopDUContextPointer topContext, AbstractNavigationContext *previousContext)
: AbstractNavigationContext(topContext, previousContext), m_label(label), m_arcUses (arcUses)
{
}
ControlFlowGraphNavigationContext::~ControlFlowGraphNavigationContext()
{
}
QString ControlFlowGraphNavigationContext::name() const
{
return i18n("Control flow graph navigation widget");
}
QString ControlFlowGraphNavigationContext::html(bool shorten)
{
clear();
AbstractNavigationContext::html(shorten);
- modifyHtml() += "";
+ modifyHtml() += QLatin1String("
");
- QStringList nodes = m_label.split("->");
+ QStringList nodes = m_label.split(QLatin1String("->"));
if (nodes.size() < 2)
- return "";
+ return QString();
- modifyHtml() += importantHighlight(i18n("Uses of %1 from %2", nodes[1], nodes[0])) + "
";
+ modifyHtml() += importantHighlight(i18n("Uses of %1 from %2", nodes[1], nodes[0])) + QLatin1String("
");
unsigned int i = m_arcUses.size()-1;
QPair pair;
QListIterator< QPair > iterator(m_arcUses);
iterator.toBack();
DUChainReadLocker lock(DUChain::lock());
while (iterator.hasPrevious())
{
pair = iterator.previous();
CodeRepresentation::Ptr code = createCodeRepresentation(pair.second);
- modifyHtml() += "" + pair.second.toUrl().fileName() + " (" + QString::number(pair.first.start.line+1) + "): " + code->line(pair.first.start.line).trimmed().toHtmlEscaped() + "
";
+ modifyHtml() += QLatin1String("") + pair.second.toUrl().fileName() + QLatin1String(" (") + QString::number(pair.first.start.line+1) + QLatin1String("): ") + code->line(pair.first.start.line).trimmed().toHtmlEscaped() + QLatin1String("
");
}
- modifyHtml() += "
";
+ modifyHtml() += QLatin1String("
");
return currentHtml();
}
void ControlFlowGraphNavigationContext::slotAnchorClicked(const QUrl &link)
{
int position = link.toString().toInt();
QPair pair = m_arcUses[position];
DUChainReadLocker lock(DUChain::lock());
QUrl url(pair.second.toUrl());
CursorInRevision cursor = pair.first.start;
int line = cursor.line;
int column = cursor.column;
lock.unlock();
ICore::self()->documentController()->openDocument(url, KTextEditor::Cursor(line, column));
}
diff --git a/controlflowgraphview.cpp b/controlflowgraphview.cpp
index fc715af..1b8c46a 100644
--- a/controlflowgraphview.cpp
+++ b/controlflowgraphview.cpp
@@ -1,321 +1,321 @@
/***************************************************************************
* Copyright 2009 Sandro Andrade *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "controlflowgraphview.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "duchaincontrolflow.h"
#include "dotcontrolflowgraph.h"
#include "controlflowgraphfiledialog.h"
#include "kdevcontrolflowgraphviewplugin.h"
using namespace KDevelop;
ControlFlowGraphView::ControlFlowGraphView(KDevControlFlowGraphViewPlugin *plugin, QWidget *parent)
:
QWidget(parent),
m_plugin(plugin),
m_part(nullptr),
m_dotControlFlowGraph(new DotControlFlowGraph),
m_duchainControlFlow(new DUChainControlFlow(m_dotControlFlowGraph)),
m_graphLocked(false)
{
setupUi(this);
- KPluginFactory *factory = KPluginLoader("kgraphviewerpart").factory();
+ KPluginFactory *factory = KPluginLoader(QStringLiteral("kgraphviewerpart")).factory();
if (!factory) {
QMessageBox::critical((QWidget *) m_plugin->core()->uiController()->activeMainWindow(),
i18n("Could not load the KGraphViewer KPart"),
i18n("Unable to load KGraphViewer, please verify that a compatible version is installed."));
return;
}
m_part = factory->create(this);
if (!m_part) {
QMessageBox::critical((QWidget *) m_plugin->core()->uiController()->activeMainWindow(),
i18n("Could not load the KGraphViewer KPart"),
i18n("Unable to create a KGraphViewer instance, please verify that a compatible version is installed."));
return;
}
QMetaObject::invokeMethod(m_part, "setReadWrite");
verticalLayout->addWidget(m_part->widget());
- modeFunctionToolButton->setIcon(QIcon::fromTheme("code-function"));
- modeClassToolButton->setIcon(QIcon::fromTheme("code-class"));
- modeNamespaceToolButton->setIcon(QIcon::fromTheme("namespace"));
- clusteringClassToolButton->setIcon(QIcon::fromTheme("code-class"));
- clusteringNamespaceToolButton->setIcon(QIcon::fromTheme("namespace"));
- clusteringProjectToolButton->setIcon(QIcon::fromTheme("folder-development"));
- useFolderNameToolButton->setIcon(QIcon::fromTheme("folder-favorites"));
- drawIncomingArcsToolButton->setIcon(QIcon::fromTheme("draw-arrow-down"));
- maxLevelToolButton->setIcon(QIcon::fromTheme("zoom-fit-height"));
- exportToolButton->setIcon(QIcon::fromTheme("document-export"));
+ modeFunctionToolButton->setIcon(QIcon::fromTheme(QStringLiteral("code-function")));
+ modeClassToolButton->setIcon(QIcon::fromTheme(QStringLiteral("code-class")));
+ modeNamespaceToolButton->setIcon(QIcon::fromTheme(QStringLiteral("namespace")));
+ clusteringClassToolButton->setIcon(QIcon::fromTheme(QStringLiteral("code-class")));
+ clusteringNamespaceToolButton->setIcon(QIcon::fromTheme(QStringLiteral("namespace")));
+ clusteringProjectToolButton->setIcon(QIcon::fromTheme(QStringLiteral("folder-development")));
+ useFolderNameToolButton->setIcon(QIcon::fromTheme(QStringLiteral("folder-favorites")));
+ drawIncomingArcsToolButton->setIcon(QIcon::fromTheme(QStringLiteral("draw-arrow-down")));
+ maxLevelToolButton->setIcon(QIcon::fromTheme(QStringLiteral("zoom-fit-height")));
+ exportToolButton->setIcon(QIcon::fromTheme(QStringLiteral("document-export")));
m_duchainControlFlow->setMaxLevel(2);
- birdseyeToolButton->setIcon(QIcon::fromTheme("edit-find"));
- usesHoverToolButton->setIcon(QIcon::fromTheme("input-mouse"));
- zoominToolButton->setIcon(QIcon::fromTheme("zoom-in"));
- zoomoutToolButton->setIcon(QIcon::fromTheme("zoom-out"));
+ birdseyeToolButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-find")));
+ usesHoverToolButton->setIcon(QIcon::fromTheme(QStringLiteral("input-mouse")));
+ zoominToolButton->setIcon(QIcon::fromTheme(QStringLiteral("zoom-in")));
+ zoomoutToolButton->setIcon(QIcon::fromTheme(QStringLiteral("zoom-out")));
if (ICore::self()->projectController()->projectCount() > 0)
setProjectButtonsEnabled(true);
- useShortNamesToolButton->setIcon(QIcon::fromTheme("application-x-arc"));
+ useShortNamesToolButton->setIcon(QIcon::fromTheme(QStringLiteral("application-x-arc")));
updateLockIcon(lockControlFlowGraphToolButton->isChecked());
// Control flow mode buttons signals
connect(modeFunctionToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setControlFlowFunction);
connect(modeClassToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setControlFlowClass);
connect(modeNamespaceToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setControlFlowNamespace);
// Clustering buttons signals
connect(clusteringClassToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setClusteringClass);
connect(clusteringNamespaceToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setClusteringNamespace);
connect(clusteringProjectToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setClusteringProject);
// Configuration buttons signals
connect(maxLevelSpinBox, static_cast(&QSpinBox::valueChanged),
this, &ControlFlowGraphView::setMaxLevel);
connect(maxLevelToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setUseMaxLevel);
connect(drawIncomingArcsToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setDrawIncomingArcs);
connect(useFolderNameToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setUseFolderName);
connect(useShortNamesToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::setUseShortNames);
connect(lockControlFlowGraphToolButton, &QToolButton::toggled,
this, &ControlFlowGraphView::updateLockIcon);
// Left buttons signals
auto partActionCollection = m_part->actionCollection();
connect(zoomoutToolButton, &QToolButton::clicked,
- partActionCollection->action("view_zoom_out"), &QAction::triggered);
+ partActionCollection->action(QStringLiteral("view_zoom_out")), &QAction::triggered);
connect(zoominToolButton, &QToolButton::clicked,
- partActionCollection->action("view_zoom_in"), &QAction::triggered);
- partActionCollection->action("view_bev_enabled")->setIcon(QIcon::fromTheme("edit-find"));
- partActionCollection->action("view_bev_enabled")->setChecked(false);
- birdseyeToolButton->setDefaultAction(partActionCollection->action("view_bev_enabled"));
+ partActionCollection->action(QStringLiteral("view_zoom_in")), &QAction::triggered);
+ partActionCollection->action(QStringLiteral("view_bev_enabled"))->setIcon(QIcon::fromTheme(QStringLiteral("edit-find")));
+ partActionCollection->action(QStringLiteral("view_bev_enabled"))->setChecked(false);
+ birdseyeToolButton->setDefaultAction(partActionCollection->action(QStringLiteral("view_bev_enabled")));
// TODO: create and use declared extra interface of graphviewer part
// instead of blind string-based connection
connect(m_part, SIGNAL(selectionIs(const QList, const QPoint&)),
m_duchainControlFlow, SLOT(slotGraphElementSelected(QList,QPoint)));
connect(m_part, SIGNAL(hoverEnter(QString)), m_duchainControlFlow, SLOT(slotEdgeHover(QString)));
connect(exportToolButton, &QToolButton::clicked,
this, &ControlFlowGraphView::exportControlFlowGraph);
connect(usesHoverToolButton, &QToolButton::toggled,
m_duchainControlFlow, &DUChainControlFlow::setShowUsesOnEdgeHover);
// Make sure we have a graph before we hook up signals to act on it
m_dotControlFlowGraph->prepareNewGraph();
// Graph generation signals
// TODO: create and use declared extra interface of graphviewer part
// instead of blind string-based connection
connect(m_dotControlFlowGraph, SIGNAL(loadLibrary(graph_t*)), m_part, SLOT(slotLoadLibrary(graph_t*)));
connect(m_duchainControlFlow, &DUChainControlFlow::startingJob,
this, &ControlFlowGraphView::startingJob);
connect(m_duchainControlFlow, static_cast(&DUChainControlFlow::jobDone),
this, &ControlFlowGraphView::graphDone);
m_plugin->registerToolView(this);
}
ControlFlowGraphView::~ControlFlowGraphView()
{
m_plugin->unRegisterToolView(this);
delete m_duchainControlFlow;
delete m_dotControlFlowGraph;
delete m_part;
}
void ControlFlowGraphView::refreshGraph()
{
m_duchainControlFlow->refreshGraph();
}
void ControlFlowGraphView::newGraph()
{
m_duchainControlFlow->newGraph();
}
void ControlFlowGraphView::setProjectButtonsEnabled(bool enabled)
{
useFolderNameToolButton->setEnabled(enabled);
clusteringProjectToolButton->setEnabled(enabled);
}
void ControlFlowGraphView::cursorPositionChanged(KTextEditor::View *view, const KTextEditor::Cursor &cursor)
{
m_duchainControlFlow->cursorPositionChanged(view, cursor);
}
void ControlFlowGraphView::startingJob()
{
setEnabled(false);
}
void ControlFlowGraphView::graphDone()
{
setEnabled(true);
}
void ControlFlowGraphView::exportControlFlowGraph()
{
QPointer fileDialog;
if ((fileDialog = m_plugin->exportControlFlowGraph(ControlFlowGraphFileDialog::NoConfigurationButtons)) && !fileDialog->selectedFiles().isEmpty())
{
m_dotControlFlowGraph->exportGraph(fileDialog->selectedFiles()[0]);
KMessageBox::information(this, i18n("Control flow graph exported"), i18n("Export Control Flow Graph"));
}
}
void ControlFlowGraphView::updateLockIcon(bool checked)
{
- lockControlFlowGraphToolButton->setIcon(QIcon::fromTheme(checked ? "document-encrypt":"document-decrypt"));
+ lockControlFlowGraphToolButton->setIcon(QIcon::fromTheme(checked ? QStringLiteral("document-encrypt"):QStringLiteral("document-decrypt")));
lockControlFlowGraphToolButton->setToolTip(checked ? i18n("Unlock control flow graph"):i18n("Lock control flow graph"));
m_duchainControlFlow->setLocked(checked);
m_graphLocked = checked;
if (!checked)
m_duchainControlFlow->refreshGraph();
}
void ControlFlowGraphView::setControlFlowClass(bool checked)
{
if (checked)
{
m_duchainControlFlow->setControlFlowMode(DUChainControlFlow::ControlFlowClass);
m_duchainControlFlow->refreshGraph();
clusteringClassToolButton->setChecked(false);
clusteringClassToolButton->setEnabled(false);
clusteringNamespaceToolButton->setEnabled(true);
}
}
void ControlFlowGraphView::setControlFlowFunction(bool checked)
{
if (checked)
{
m_duchainControlFlow->setControlFlowMode(DUChainControlFlow::ControlFlowFunction);
m_duchainControlFlow->refreshGraph();
clusteringClassToolButton->setEnabled(true);
clusteringNamespaceToolButton->setEnabled(true);
}
}
void ControlFlowGraphView::setControlFlowNamespace(bool checked)
{
if (checked)
{
m_duchainControlFlow->setControlFlowMode(DUChainControlFlow::ControlFlowNamespace);
m_duchainControlFlow->refreshGraph();
clusteringClassToolButton->setChecked(false);
clusteringClassToolButton->setEnabled(false);
clusteringNamespaceToolButton->setChecked(false);
clusteringNamespaceToolButton->setEnabled(false);
}
}
void ControlFlowGraphView::setClusteringClass(bool checked)
{
Q_UNUSED(checked);
m_duchainControlFlow->setClusteringModes(m_duchainControlFlow->clusteringModes() ^ DUChainControlFlow::ClusteringClass);
m_duchainControlFlow->refreshGraph();
useShortNamesToolButton->setEnabled(m_duchainControlFlow->clusteringModes() ? true:false);
}
void ControlFlowGraphView::setClusteringProject(bool checked)
{
Q_UNUSED(checked);
m_duchainControlFlow->setClusteringModes(m_duchainControlFlow->clusteringModes() ^ DUChainControlFlow::ClusteringProject);
m_duchainControlFlow->refreshGraph();
useShortNamesToolButton->setEnabled(m_duchainControlFlow->clusteringModes() ? true:false);
}
void ControlFlowGraphView::setClusteringNamespace(bool checked)
{
Q_UNUSED(checked);
m_duchainControlFlow->setClusteringModes(m_duchainControlFlow->clusteringModes() ^ DUChainControlFlow::ClusteringNamespace);
m_duchainControlFlow->refreshGraph();
useShortNamesToolButton->setEnabled(m_duchainControlFlow->clusteringModes() ? true:false);
}
void ControlFlowGraphView::setUseMaxLevel(bool checked)
{
maxLevelSpinBox->setEnabled(checked);
setMaxLevel(checked ? maxLevelSpinBox->value():0);
}
void ControlFlowGraphView::setMaxLevel(int value)
{
m_duchainControlFlow->setMaxLevel(value);
m_duchainControlFlow->refreshGraph();
}
void ControlFlowGraphView::setDrawIncomingArcs(bool checked)
{
m_duchainControlFlow->setDrawIncomingArcs(checked);
m_duchainControlFlow->refreshGraph();
}
void ControlFlowGraphView::setUseFolderName(bool checked)
{
m_duchainControlFlow->setUseFolderName(checked);
m_duchainControlFlow->refreshGraph();
}
void ControlFlowGraphView::setUseShortNames(bool checked)
{
m_duchainControlFlow->setUseShortNames(checked);
m_duchainControlFlow->refreshGraph();
}
void ControlFlowGraphView::showEvent(QShowEvent *event)
{
Q_UNUSED(event);
m_plugin->setActiveToolView(this);
}
void ControlFlowGraphView::hideEvent(QHideEvent *event)
{
Q_UNUSED(event);
m_plugin->setActiveToolView(nullptr);
}
diff --git a/dotcontrolflowgraph.cpp b/dotcontrolflowgraph.cpp
index 9e5b52a..b317e09 100644
--- a/dotcontrolflowgraph.cpp
+++ b/dotcontrolflowgraph.cpp
@@ -1,195 +1,197 @@
/***************************************************************************
* Copyright 2009 Sandro Andrade *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "dotcontrolflowgraph.h"
#include
#include
namespace {
// C interface takes char*, so to avoid deprecated cast and/or undefined behaviour,
// defined the needed constants here.
static char SUFFIX[] = "dot";
static char GRAPH_NAME[] = "Root_Graph";
static char LABEL[] = "label";
static char EMPTY[] = "";
static char FILLED[] = "filled";
static char FILLCOLOR[] = "fillcolor";
static char SHAPE[] = "shape";
static char STYLE[] = "style";
static char BOX[] = "box";
}
QMutex DotControlFlowGraph::mutex;
DotControlFlowGraph::DotControlFlowGraph()
: m_rootGraph(nullptr)
{
m_gvc = gvContext();
}
DotControlFlowGraph::~DotControlFlowGraph()
{
gvFreeContext(m_gvc);
}
void DotControlFlowGraph::graphDone()
{
if (m_rootGraph)
{
if (mutex.tryLock())
{
gvLayout(m_gvc, m_rootGraph, SUFFIX);
gvFreeLayout(m_gvc, m_rootGraph);
mutex.unlock();
emit loadLibrary(m_rootGraph);
}
}
}
void DotControlFlowGraph::clearGraph()
{
if (m_rootGraph)
{
gvFreeLayout(m_gvc, m_rootGraph);
agclose(m_rootGraph);
m_rootGraph = nullptr;
}
m_namedGraphs.clear();
m_rootGraph = agopen(GRAPH_NAME, Agdirected, nullptr);
graphDone();
}
void DotControlFlowGraph::exportGraph(const QString &fileName)
{
if (m_rootGraph)
{
gvLayout(m_gvc, m_rootGraph, SUFFIX);
- gvRenderFilename(m_gvc, m_rootGraph, fileName.right(fileName.size()-fileName.lastIndexOf('.')-1).toUtf8().data(), fileName.toUtf8().data());
+ gvRenderFilename(m_gvc, m_rootGraph, fileName.right(fileName.size()-fileName.lastIndexOf(QLatin1Char('.'))-1).toUtf8().data(), fileName.toUtf8().data());
gvFreeLayout(m_gvc, m_rootGraph);
}
}
void DotControlFlowGraph::prepareNewGraph()
{
clearGraph();
}
void DotControlFlowGraph::foundRootNode(const QStringList &containers, const QString &label)
{
Agraph_t *graph = m_rootGraph;
if (!m_rootGraph) {
// This shouldn't happen, as the graph should be generated before this function
// is connected.
Q_ASSERT(false);
return;
}
QString absoluteContainer;
foreach (const QString& container, containers)
{
absoluteContainer += container;
- graph = m_namedGraphs[absoluteContainer] = agsubg(graph, ("cluster_" + absoluteContainer).toUtf8().data(), 1);
+ graph = m_namedGraphs[absoluteContainer] = agsubg(graph, (QLatin1String("cluster_") + absoluteContainer).toUtf8().data(), 1);
agsafeset(graph, LABEL, container.toUtf8().data(), EMPTY);
}
- Agnode_t *node = agnode(graph, (containers.join("") + label).toUtf8().data(), 1);
+ Agnode_t *node = agnode(graph, (containers.join(QString()) + label).toUtf8().data(), 1);
agsafeset(node, SHAPE, BOX, EMPTY);
QColor c = colorFromQualifiedIdentifier(label);
char color[8];
std::sprintf (color, "#%02x%02x%02x", c.red(), c.green(), c.blue());
agsafeset(node, STYLE, FILLED, EMPTY);
agsafeset(node, FILLCOLOR, color, EMPTY);
agsafeset(node, LABEL, label.toUtf8().data(), EMPTY);
}
void DotControlFlowGraph::foundFunctionCall(const QStringList &sourceContainers, const QString &source, const QStringList &targetContainers, const QString &target)
{
if (!m_rootGraph) {
// This shouldn't happen, as the graph should be generated before this function
// is connected.
Q_ASSERT(false);
return;
}
Agraph_t *sourceGraph, *targetGraph, *newGraph;
sourceGraph = targetGraph = m_rootGraph;
QString absoluteContainer;
foreach (const QString& container, sourceContainers)
{
Agraph_t *previousGraph = sourceGraph;
absoluteContainer += container;
if (!m_namedGraphs.contains(absoluteContainer))
{
- newGraph = agsubg(previousGraph, ("cluster_" + absoluteContainer).toUtf8().data(), 1);
+ newGraph = agsubg(previousGraph, (QLatin1String("cluster_") + absoluteContainer).toUtf8().data(), 1);
m_namedGraphs.insert(absoluteContainer, newGraph);
agsafeset(newGraph, LABEL, container.toUtf8().data(), EMPTY);
}
sourceGraph = m_namedGraphs[absoluteContainer];
}
absoluteContainer.clear();
foreach (const QString& container, targetContainers)
{
Agraph_t *previousGraph = targetGraph;
absoluteContainer += container;
if (!m_namedGraphs.contains(absoluteContainer))
{
- Agraph_t *newGraph = agsubg(previousGraph, ("cluster_" + absoluteContainer).toUtf8().data(), 1);
+ Agraph_t *newGraph = agsubg(previousGraph, (QLatin1String("cluster_") + absoluteContainer).toUtf8().data(), 1);
m_namedGraphs.insert(absoluteContainer, newGraph);
agsafeset(newGraph, LABEL, container.toUtf8().data(), EMPTY);
}
targetGraph = m_namedGraphs[absoluteContainer];
}
- Agnode_t* src = agnode(sourceGraph, (sourceContainers.join("") + source).toUtf8().data(), 1);
- Agnode_t* tgt = agnode(targetGraph, (targetContainers.join("") + target).toUtf8().data(), 1);
+ Agnode_t* src = agnode(sourceGraph, (sourceContainers.join(QString()) + source).toUtf8().data(), 1);
+ Agnode_t* tgt = agnode(targetGraph, (targetContainers.join(QString()) + target).toUtf8().data(), 1);
char color[8];
char ID[] = "id";
QColor c = colorFromQualifiedIdentifier(source);
std::sprintf (color, "#%02x%02x%02x", c.red(), c.green(), c.blue());
agsafeset(src, STYLE, FILLED, EMPTY);
agsafeset(src, FILLCOLOR, color, EMPTY);
agsafeset(src, SHAPE, BOX, EMPTY);
agsafeset(src, LABEL, source.toUtf8().data(), EMPTY);
c = colorFromQualifiedIdentifier(target);
std::sprintf (color, "#%02x%02x%02x", c.red(), c.green(), c.blue());
agsafeset(tgt, STYLE, FILLED, EMPTY);
agsafeset(tgt, FILLCOLOR, color, EMPTY);
agsafeset(tgt, SHAPE, BOX, EMPTY);
agsafeset(tgt, LABEL, target.toUtf8().data(), EMPTY);
Agedge_t* edge;
if (sourceGraph == targetGraph)
edge = agedge(sourceGraph, src, tgt, nullptr, 1);
else
edge = agedge(m_rootGraph, src, tgt, nullptr, 1);
- agsafeset(edge, ID, (source + "->" + target).toUtf8().data(), EMPTY);
+ agsafeset(edge, ID, (source + QLatin1String("->") + target).toUtf8().data(), EMPTY);
}
const QColor& DotControlFlowGraph::colorFromQualifiedIdentifier(const QString &label)
{
- if (m_colorMap.contains(label.split("::")[0]))
- return m_colorMap[label.split("::")[0]];
- else
- return m_colorMap[label.split("::")[0]] = QColor::fromHsv(qrand() % 256, 255, 190);
+ const QString qid = label.split(QLatin1String("::")).value(0);
+ auto it = m_colorMap.find(qid);
+ if (it == m_colorMap.end()) {
+ it = m_colorMap.insert(qid, QColor::fromHsv(qrand() % 256, 255, 190));
+ }
+ return *it;
}
diff --git a/duchaincontrolflow.cpp b/duchaincontrolflow.cpp
index 29156e1..e4a23df 100644
--- a/duchaincontrolflow.cpp
+++ b/duchaincontrolflow.cpp
@@ -1,625 +1,629 @@
/***************************************************************************
* Copyright 2009 Sandro Andrade *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "duchaincontrolflow.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "dotcontrolflowgraph.h"
#include "duchaincontrolflowjob.h"
#include "controlflowgraphusescollector.h"
#include "controlflowgraphnavigationwidget.h"
Q_DECLARE_METATYPE(KDevelop::Use)
using namespace KDevelop;
DUChainControlFlow::DUChainControlFlow(DotControlFlowGraph* dotControlFlowGraph)
: m_dotControlFlowGraph(dotControlFlowGraph),
m_previousUppermostExecutableContext(IndexedDUContext()),
m_currentView(nullptr),
m_currentProject(nullptr),
m_currentLevel(1),
m_maxLevel(2),
m_locked(false),
m_drawIncomingArcs(true),
m_useFolderName(true),
m_useShortNames(true),
m_ShowUsesOnEdgeHover(true),
m_controlFlowMode(ControlFlowClass),
m_clusteringModes(ClusteringNamespace),
m_graphThreadRunning(false),
m_abort(false),
m_collector(nullptr)
{
qRegisterMetaType