9#include "moc_MainWindow.cpp"
10#include "ui_MainWindow.h"
14#include "QGVSubGraph.h"
17#include <QtPrintSupport/QPrinter>
18#include <QInputDialog>
44 stringModel.setStringList(messages);
45 ui->messageView->setModel(&stringModel);
46 ui->messageView->setVisible(
false);
51 connect(ui->actionProfile_YARP_network,
SIGNAL(
triggered()),
this,
SLOT(onProfileYarpNetwork()));
64 SLOT(onNodesTreeItemClicked(QTreeWidgetItem *,
int)));
68 connect(ui->actionExport_connections_list,
SIGNAL(
triggered()),
this,
SLOT(onExportConList()));
69 connect(ui->actionConfigure_connections_QOS,
SIGNAL(
triggered()),
this,
SLOT(onConfigureConsQos()));
70 connect(ui->actionUpdateConnectionQosStatus,
SIGNAL(
triggered()),
this,
SLOT(onUpdateQosStatus()));
77 layoutStyle =
"ortho";
78 ui->actionOrthogonal->setChecked(
true);
79 layoutSubgraph =
true;
80 ui->actionSubgraph->setChecked(
true);
81 ui->actionMessageBox->setChecked(
false);
82 ui->actionItemswindow->setChecked(
true);
84 ui->actionHighlight_Loops->setEnabled(
false);
85 ui->actionHidePorts->setEnabled(
false);
86 ui->actionHideDisconnectedPorts->setEnabled(
false);
87 ui->actionHideConnectionsLable->setEnabled(
false);
88 ui->actionDebugMode->setEnabled(
false);
89 ui->actionUpdateConnectionQosStatus->setEnabled(
false);
91 ui->action_Save_project->setEnabled(
false);
92 ui->action_Load_project->setEnabled(
false);
93 ui->actionDocumentaion->setEnabled(
false);
94 ui->actionProfilePortsRate->setEnabled(
false);
95 moduleParentItem =
new QTreeWidgetItem( ui->nodesTreeWidget,
QStringList(
"Modules"));
96 portParentItem =
new QTreeWidgetItem( ui->nodesTreeWidget,
QStringList(
"Ports"));
97 machinesParentItem =
new QTreeWidgetItem( ui->nodesTreeWidget,
QStringList(
"Machines"));
98 moduleParentItem->setIcon(0,
QIcon(
":icons/resources/module.svg"));
99 portParentItem->setIcon(0,
QIcon(
":icons/resources/port.svg"));
100 machinesParentItem->setIcon(0,
QIcon(
":icons/resources/computer_B.svg"));
109void MainWindow::initScene() {
115 sceneNodeMap.clear();
116 sceneSubGraphMap.clear();
117 ui->graphicsView->setBackgroundBrush(
QBrush(
QColor(
"#2e3e56"), Qt::SolidPattern));
118 ui->graphicsView->setScene(
scene);
128 progressDlg->setValue(percentage);
139 layoutSubgraph = ui->actionSubgraph->isChecked();
144 scene->setGraphAttribute(
"splines", layoutStyle.c_str());
145 scene->setGraphAttribute(
"rankdir",
"LR");
146 scene->setGraphAttribute(
"bgcolor",
"#2e3e56");
148 scene->setGraphAttribute(
"nodesep",
"0.4");
149 scene->setGraphAttribute(
"ranksep",
"0.5");
151 scene->setNodeAttribute(
"style",
"filled");
152 scene->setNodeAttribute(
"fillcolor",
"gray");
153 scene->setNodeAttribute(
"height",
"1.0");
154 scene->setEdgeAttribute(
"minlen",
"2.0");
165 for(
itr = vertices.begin();
itr!=vertices.end();
itr++) {
167 const Property& prop = (*itr)->property;
171 std::string hostname = prop.
find(
"hostname").
asString();
173 std::stringstream key;
175 if(sceneSubGraphMap[key.str()] ==
nullptr)
178 sceneSubGraphMap[key.str()] =
sgraph;
182 sgraph->setAttribute(
"color",
"#FFFFFF");
190 if (host ==
"Linux") {
191 sgraph->setIcon(
QImage(
":/icons/resources/os-linux.png"));
192 }
else if (host ==
"Windows") {
193 sgraph->setIcon(
QImage(
":/icons/resources/os-windows.png"));
194 }
else if (host ==
"Mac") {
195 sgraph->setIcon(
QImage(
":/icons/resources/os-macos.png"));
197 sgraph->setIcon(
QImage(
":/icons/resources/system-run.png"));
201 node->setAttribute(
"shape",
"circle");
202 node->setAttribute(
"height",
"0.0000000000001");
203 node->setAttribute(
"fixedsize",
"true");
204 node->setAttribute(
"label",
"");
205 node->setAttribute(
"fillcolor",
"#2e3e56");
206 node->setAttribute(
"color",
"#2e3e56");
207 node->setAttribute(
"node_type",
"end");
208 node->setAttribute(
"rawname",
endNodeName.c_str());
218 for(
itr = vertices.begin();
itr!=vertices.end();
itr++) {
220 const Property& prop = (*itr)->property;
231 std::stringstream key;
234 if(
sgraphParent ==
nullptr || (!ui->actionDebugMode->isChecked() && name.find(
"yarplogger") != std::string::npos))
253 sgraph->setAttribute(
"shape",
"box");
254 sgraph->setAttribute(
"label", label.c_str());
255 if(prop.
check(
"color")) {
259 sgraph->setAttribute(
"fillcolor",
"#a5cf80");
260 sgraph->setAttribute(
"color",
"#a5cf80");
270 node->setAttribute(
"shape",
"circle");
271 node->setAttribute(
"height",
"0.0000000000001");
272 node->setAttribute(
"fixedsize",
"true");
273 node->setAttribute(
"label",
"");
274 node->setAttribute(
"fillcolor",
"#2e3e56");
275 node->setAttribute(
"color",
"#2e3e56");
276 node->setAttribute(
"node_type",
"end");
277 node->setAttribute(
"rawname",
endNodeName.c_str());
288 for(
itr = vertices.begin();
itr!=vertices.end();
itr++) {
289 const Property& prop = (*itr)->property;
294 if (ui->actionHideDisconnectedPorts->isChecked() &&
pv->property.find(
"orphan").asBool()) {
297 if (!ui->actionDebugMode->isChecked() && (portName.find(
"/log") != std::string::npos || portName.find(
"/yarplogger") != std::string::npos)) {
300 std::stringstream key;
301 if(v->property.find(
"hidden").asBool())
303 pv->property.put(
"hidden",
true);
304 updateNodeWidgetItems();
317 key<<v->property.find(
"hostname").asString()<<v->property.find(
"pid").asInt32();
321 node =
sgraph->addNode(nodeName.c_str());
322 if(ui->actionColorMode->isChecked())
324 QColor color(
sgraph->getAttribute(
"colorOfTheProcess"));
325 if (color.lightness() < 100) {
326 node->setAttribute(
"labelfontcolor",
"#ffffff");
331 node =
scene->addNode(nodeName.c_str());
334 node =
scene->addNode(nodeName.c_str());
336 node->setAttribute(
"shape",
"ellipse");
337 if(prop.
check(
"color")) {
338 node->setAttribute(
"fillcolor", prop.
find(
"color").
asString().c_str());
339 node->setAttribute(
"color", prop.
find(
"color").
asString().c_str());
347 node->setAttribute(
"fillcolor",
"#edad56");
348 node->setAttribute(
"color",
"#edad56");
352 node->setVertex(*
itr);
359 scene->setGraphAttribute(
"nodesep",
"0.5");
360 scene->setGraphAttribute(
"ranksep",
"1.5");
363 for(
itr = vertices.begin();
itr!=vertices.end();
itr++) {
365 for(
const auto& edge :
v1.outEdges()) {
367 std::string targetName =
v2.property.find(
"name").asString();
368 if (!ui->actionDebugMode->isChecked() && targetName.find(
"/yarplogger") != std::string::npos) {
373 if(!
v1.property.find(
"hidden").asBool() && !
v2.property.find(
"hidden").asBool()) {
374 if(edge.property.find(
"type").asString() ==
"ownership" &&
375 edge.property.find(
"dir").asString() !=
"unknown") {
379 if(edge.property.find(
"type").asString() ==
"connection") {
383 if(!ui->actionHideConnectionsLable->isChecked())
385 label = edge.property.find(
"carrier").asString();
386 int blankLength = std::max(
int(label.length()/2.5),4);
398 gve->setAttribute(
"color",
"white");
401 gve->setAttribute(
"color",
"orange");
404 gve->setAttribute(
"color",
"red");
407 gve->setAttribute(
"color",
"yellow");
410 gve->setAttribute(
"color",
"white");
421 scene->applyLayout();
424 ui->graphicsView->fitInView(
scene->sceneRect(), Qt::KeepAspectRatio);
431void MainWindow::edgeContextMenu(
QGVEdge* edge) {
432 const Edge*
e = (
const Edge*)edge->getEdge();
441 menu.addAction(
tr(
"Information..."));
442 menu.addAction(
tr(
"Configure Qos..."));
445 if (action ==
nullptr) {
448 if(action->text().toStdString() ==
"Information...") {
454 else if(action->text().toStdString() ==
"Configure Qos...") {
461void MainWindow::nodeContextMenu(
QGVNode *node)
465 if (v->property.find(
"type").asString() ==
"port") {
466 onNodeContextMenuPort(node, v);
468 yWarning() <<
"nodeContextMenu(): Unknown node!";
483 menu.addAction(
tr(
"Information..."));
484 menu.addAction(
tr(
"Hide"));
486 if (action ==
nullptr) {
489 if(action->text().toStdString() ==
"Information...") {
495 else if(action->text().toStdString() ==
"Hide") {
497 updateNodeWidgetItems();
502void MainWindow::onAbout() {
503 QMessageBox::about(
this,
"yarpviz (version 2.0.0)",
504 "A graphical tool for a graphical tool for profiling and visualizing YARP network!");
511 menu.addAction(
tr(
"Information..."));
512 menu.addAction(
tr(
"Hide"));
514 if (action ==
nullptr) {
517 if(action->text().toStdString() ==
"Information...") {
523 else if(action->text().toStdString() ==
"Hide") {
525 updateNodeWidgetItems();
531void MainWindow::nodeDoubleClick(
QGVNode *node)
533 QMessageBox::information(
this,
tr(
"Node double clicked"),
tr(
"Node %1").arg(node->label()));
536void MainWindow::onProfileYarpNetwork() {
539 QMessageBox::StandardButton reply;
540 reply = QMessageBox::question(
this,
"Profiling: clear current project",
"Running profiler will clear the current project.\n Are you sure?",
541 QMessageBox::Yes|QMessageBox::No);
542 if (reply == QMessageBox::No) {
553 float timeout =
inputDialog->getDouble(
nullptr ,
"Profiling: yarp clean",
554 "Do you want to run yarp clean before profiling?\n\n"
555 "Be aware that yarp clean with a little timetout could\n"
556 "unregister ports that are actually open.\n\n"
557 "Timeout(seconds):", 0.3, 0, 2147483647, 1, &ok);
560 messages.append(
"Cleaning death ports...");
561 NetworkProfiler::yarpClean(timeout);
564 messages.append(
"Getting the ports list...");
566 NetworkProfiler::getPortsList(
ports);
569 messages.append(
"Getting the ports details...");
573 progressDlg->setLabelText(
"Getting the ports details...");
574 progressDlg->reset();
575 progressDlg->setRange(0,
ports.size());
576 progressDlg->setValue(0);
577 progressDlg->setWindowModality(Qt::WindowModal);
579 for(
size_t i=0; i<
ports.size(); i++) {
582 std::string msg = std::string(
"Checking ") +
portname +
"...";
583 messages.append(
QString(msg.c_str()));
584 if (NetworkProfiler::getPortDetails(
portname, info)) {
587 progressDlg->setValue(i);
588 if (progressDlg->wasCanceled()) {
593 stringModel.setStringList(messages);
594 ui->messageView->update();
597 progressDlg->setLabelText(
"Generating the graph...");
598 progressDlg->setRange(0, 100);
599 progressDlg->setValue(0);
601 progressDlg->
close();
603 progressDlg =
nullptr;
608 moduleParentItem->setExpanded(
true);
609 portParentItem->setExpanded(
true);
610 machinesParentItem->setExpanded(
true);
611 currentGraph = &mainGraph;
614 populateTreeWidget();
617 ui->actionHighlight_Loops->setEnabled(
true);
618 ui->actionHidePorts->setEnabled(
true);
619 ui->actionHideDisconnectedPorts->setEnabled(
true);
620 ui->actionHideConnectionsLable->setEnabled(
true);
621 ui->actionDebugMode->setEnabled(
true);
622 ui->actionUpdateConnectionQosStatus->setEnabled(
true);
623 ui->actionProfilePortsRate->setEnabled(
true);
626void MainWindow::onHighlightLoops() {
631 if(ui->actionHighlight_Loops->isChecked()) {
636 std::uniform_int_distribution<int>
udistH(128, 255);
637 std::uniform_int_distribution<int>
udistL(0, 128);
641 for (
auto&
j :
vset) {
642 j->property.put(
"color", color.name().toStdString());
650 (*itr)->property.unput(
"color");
657void MainWindow::updateNodeWidgetItems() {
660 for (
int i= moduleParentItem->childCount()-1; i>-1; i--) {
663 item->check(!
item->getVertex()->property.find(
"hidden").asBool());
665 for (
int i= portParentItem->childCount()-1; i>-1; i--) {
668 item->check(!
item->getVertex()->property.find(
"hidden").asBool());
670 for (
int i= machinesParentItem->childCount()-1; i>-1; i--) {
673 item->check(!
item->getVertex()->property.find(
"hidden").asBool());
677void MainWindow::populateTreeWidget(){
678 QTreeWidgetItem*
item=
nullptr;
679 for (
int i= moduleParentItem->childCount()-1; i>-1; i--) {
680 item = moduleParentItem->child(i);
683 for (
int i= portParentItem->childCount()-1; i>-1; i--) {
684 item = portParentItem->child(i);
687 for (
int i= machinesParentItem->childCount()-1; i>-1; i--) {
688 item = machinesParentItem->child(i);
694 const Property& prop = (*itr)->property;
697 if(!ui->actionDebugMode->isChecked() &&
processName.find(
"yarplogger") != std::string::npos)
702 moduleItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
705 else if(
dynamic_cast<PortVertex*
>(*
itr) && !ui->actionHidePorts->isChecked()) {
707 if(ui->actionHideDisconnectedPorts->isChecked()){
708 if (prop.
check(
"orphan")) {
712 if (!ui->actionDebugMode->isChecked() && (portName.find(
"/log") != std::string::npos || portName.find(
"/yarplogger") != std::string::npos)) {
716 portItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
725 moduleParentItem->setExpanded(
true);
726 portParentItem->setExpanded(
true);
727 machinesParentItem->setExpanded(
true);
730void MainWindow::onLayoutOrthogonal() {
731 ui->actionPolyline->setChecked(
false);
732 ui->actionLine->setChecked(
false);
733 ui->actionCurved->setChecked(
false);
734 layoutStyle =
"ortho";
740void MainWindow::onLayoutPolyline() {
741 ui->actionOrthogonal->setChecked(
false);
742 ui->actionLine->setChecked(
false);
743 ui->actionCurved->setChecked(
false);
744 layoutStyle =
"polyline";
750void MainWindow::onLayoutLine() {
751 ui->actionOrthogonal->setChecked(
false);
752 ui->actionPolyline->setChecked(
false);
753 ui->actionCurved->setChecked(
false);
754 layoutStyle =
"line";
760void MainWindow::onLayoutCurved() {
761 ui->actionOrthogonal->setChecked(
false);
762 ui->actionPolyline->setChecked(
false);
763 ui->actionLine->setChecked(
false);
764 layoutStyle =
"curved";
769void MainWindow::onUpdateGraph() {
772 if(ui->actionHidePorts->isChecked()){
774 currentGraph = &simpleGraph;
777 currentGraph = &mainGraph;
779 populateTreeWidget();
784void MainWindow::onNodesTreeItemClicked(QTreeWidgetItem *
item,
int column){
789 bool state = (
item->checkState(
column) == Qt::Checked);
798 item->setSelected(
false);
802 graphicItem->setSelected(
true);
804 ui->graphicsView->centerOn(graphicItem);
809void MainWindow::onWindowMessageBox() {
810 ui->messageView->setVisible(ui->actionMessageBox->isChecked());
813void MainWindow::onWindowItem() {
814 ui->nodesTreeWidget->setVisible(ui->actionItemswindow->isChecked());
817void MainWindow::onUpdateQosStatus() {
822void MainWindow::onProfilePortsRate() {
823 yAssert(currentGraph!=
nullptr);
829void MainWindow::onConfigureConsQos() {
835void MainWindow::onExportConList() {
838 QString filename = QFileDialog::getSaveFileName(
nullptr,
"Export connections list",
841 if (filename.size() == 0) {
846 file.open(filename.toStdString().c_str());
847 if(!file.is_open()) {
848 QMessageBox::critical(
nullptr, QObject::tr(
"Error"), QObject::tr(
"Cannot open the file for saving"));
857 for(
const auto& i :
v1.outEdges()) {
860 if(!
v1.property.find(
"hidden").asBool() && !
v2.property.find(
"hidden").asBool()) {
876void MainWindow::onExportScene() {
879 QString filename = QFileDialog::getSaveFileName(
nullptr,
"Export scene",
882 if (filename.size() == 0) {
889 painter.setRenderHint(QPainter::Antialiasing);
891 if (!
image.save(filename)) {
892 yError() <<
"Cannot save scene to" << filename.toStdString();
911void MainWindow::onBackgroundGrid()
913 scene->enableBgGrid(ui->actionBackground_grid->isChecked());
std::vector< pvertex_set > graph_subset
pvertex_set::const_iterator pvertex_const_iterator
std::vector< yarp::profiler::graph::Vertex * > pvertex_set
std::default_random_engine randengine
int SIGNAL(int pid, int signum)
MainWindow(const yarp::os::ResourceFinder &rf, yarp::dev::IBattery *ibat, QWidget *parent=0, double refresh_period=10.0)
void drawGraph(yarp::profiler::graph::Graph &graph)
void onProgress(unsigned int percentage) override
A simple collection of objects that can be described and transmitted in a portable way.
void addString(const char *str)
Places a string in the bottle, at the end of the list.
std::string toString() const override
Gives a human-readable textual representation of the bottle.
A mini-server for performing network communication in the background.
void close() override
Stop port activity.
A class for storing options and configuration information.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
std::string toString() const override
Return a standard text representation of the content of the object.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
PacketPriorityLevel
The PacketPriorityLevel defines the packets quality of service (priority) levels.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
virtual bool asBool() const
Get boolean value.
virtual std::int32_t asInt32() const
Get 32-bit integer value.
std::string toString() const override
Return a standard text representation of the content of the object.
virtual std::string asString() const
Get string value.
std::vector< PortDetails > ports_detail_set
std::vector< PortInfo > ports_name_set
static bool updateConnectionQosStatus(yarp::profiler::graph::Graph &graph)
static bool creatNetworkGraph(ports_detail_set details, yarp::profiler::graph::Graph &graph)
creatNetworkGraph
static bool creatSimpleModuleGraph(yarp::profiler::graph::Graph &graph, yarp::profiler::graph::Graph &subgraph)
static void setProgressCallback(ProgressCallback *callback)
static bool calcSCC(yarp::profiler::graph::Graph &graph, graph_subset &scc)
calcSCC
The yarp::profiler::graph::Edge class.
const yarp::profiler::graph::Vertex & second() const
yarp::os::Property property
The yarp::profiler::graph::Graph class.
const pvertex_set & vertices()
void setGraphicItem(void *item)
The yarp::profiler::graph::Vertex class.
yarp::os::Property property
const yarp::sig::VectorOf< std::pair< int, int > > vertices
An interface to the operating system, including Port based communication.