GCC Code Coverage Report


Directory: ./
File: src/hpp-manipulation-graph.cc
Date: 2024-12-13 15:45:52
Exec Total Coverage
Lines: 0 342 0.0%
Branches: 0 776 0.0%

Line Branch Exec Source
1 // BSD 2-Clause License
2
3 // Copyright (c) 2015 - 2018, hpp-plot
4 // Authors: Heidy Dallard, Joseph Mirabel
5 // All rights reserved.
6
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in
16 // the documentation and/or other materials provided with the
17 // distribution.
18
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 // COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 // OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 #include "hpp/plot/hpp-manipulation-graph.hh"
33
34 #include <QGVEdge.h>
35 #include <QGVNode.h>
36 #include <QtGui/qtextdocument.h>
37 #include <assert.h>
38
39 #include <QDebug>
40 #include <QDir>
41 #include <QInputDialog>
42 #include <QLayout>
43 #include <QMap>
44 #include <QMenu>
45 #include <QMessageBox>
46 #include <QPushButton>
47 #include <QTemporaryFile>
48 #include <QTimer>
49 #include <iostream>
50 #include <limits>
51
52 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
53 #define ESCAPE(q) Qt::escape(q)
54 #else
55 #define ESCAPE(q) q.toHtmlEscaped()
56 #endif
57
58 namespace hpp {
59 namespace plot {
60 namespace {
61 ✗ void initConfigProjStat(::hpp::ConfigProjStat& p) {
62 ✗ p.success = 0;
63 ✗ p.error = 0;
64 ✗ p.nbObs = 0;
65 }
66 } // namespace
67 ✗ GraphAction::GraphAction(HppManipulationGraphWidget* parent)
68 ✗ : QAction(parent), gw_(parent) {
69 ✗ connect(this, SIGNAL(triggered()), SLOT(transferSignal()));
70 }
71
72 ✗ void GraphAction::transferSignal() {
73 hpp::ID id;
74 ✗ if (gw_->selectionID(id)) emit activated(id);
75 }
76
77 ✗ HppManipulationGraphWidget::HppManipulationGraphWidget(
78 ✗ corbaServer::manipulation::Client* hpp_, QWidget* parent)
79 : GraphWidget("Manipulation graph", parent),
80 ✗ manip_(hpp_),
81 ✗ showWaypoints_(new QPushButton(QIcon::fromTheme("view-refresh"),
82 ✗ "&Show waypoints", buttonBox_)),
83 ✗ statButton_(new QPushButton(QIcon::fromTheme("view-refresh"),
84 ✗ "&Statistics", buttonBox_)),
85 ✗ updateStatsTimer_(new QTimer(this)),
86 ✗ currentId_(-1),
87 ✗ showNodeId_(-1),
88 ✗ showEdgeId_(-1) {
89 ✗ graphInfo_.id = -1;
90 ✗ statButton_->setCheckable(true);
91 ✗ showWaypoints_->setCheckable(true);
92 ✗ showWaypoints_->setChecked(false);
93 ✗ buttonBox_->layout()->addWidget(statButton_);
94 ✗ buttonBox_->layout()->addWidget(showWaypoints_);
95 ✗ updateStatsTimer_->setInterval(1000);
96 ✗ updateStatsTimer_->setSingleShot(false);
97
98 ✗ connect(updateStatsTimer_, SIGNAL(timeout()), SLOT(updateStatistics()));
99 ✗ connect(statButton_, SIGNAL(clicked(bool)), SLOT(startStopUpdateStats(bool)));
100 ✗ connect(scene_, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
101 }
102
103 ✗ HppManipulationGraphWidget::~HppManipulationGraphWidget() {
104 ✗ qDeleteAll(nodeContextMenuActions_);
105 ✗ qDeleteAll(edgeContextMenuActions_);
106 ✗ delete updateStatsTimer_;
107 }
108
109 ✗ void HppManipulationGraphWidget::addNodeContextMenuAction(GraphAction* action) {
110 ✗ nodeContextMenuActions_.append(action);
111 }
112
113 ✗ void HppManipulationGraphWidget::addEdgeContextMenuAction(GraphAction* action) {
114 ✗ edgeContextMenuActions_.append(action);
115 }
116
117 ✗ void HppManipulationGraphWidget::client(
118 corbaServer::manipulation::Client* hpp) {
119 ✗ manip_ = hpp;
120 }
121
122 ✗ bool hpp::plot::HppManipulationGraphWidget::selectionID(ID& id) {
123 ✗ id = currentId_;
124 ✗ return currentId_ != -1;
125 }
126
127 ✗ void HppManipulationGraphWidget::fillScene() {
128 ✗ if (manip_ == NULL) return;
129 ✗ hpp::GraphComp_var graph = new hpp::GraphComp;
130 ✗ hpp::GraphElements_var elmts = new hpp::GraphElements;
131 try {
132 ✗ manip_->graph()->getGraph(graph.out(), elmts.out());
133
134 ✗ graphName_ = graph->name;
135 ✗ scene_->setGraphAttribute("label", QString(graph->name));
136
137 ✗ scene_->setGraphAttribute("splines", "spline");
138 // scene_->setGraphAttribute("rankdir", "LR");
139 ✗ scene_->setGraphAttribute("outputorder", "edgesfirst");
140 ✗ scene_->setGraphAttribute("nodesep", "0.5");
141 ✗ scene_->setGraphAttribute("esep", "0.8");
142 ✗ scene_->setGraphAttribute("sep", "1");
143
144 ✗ scene_->setNodeAttribute("shape", "circle");
145 ✗ scene_->setNodeAttribute("style", "filled");
146 ✗ scene_->setNodeAttribute("fillcolor", "white");
147 // scene_->setNodeAttribute("height", "1.2");
148 // scene_->setEdgeAttribute("minlen", "3");
149
150 ✗ graphInfo_.id = graph->id;
151 ✗ graphInfo_.constraintStr = getConstraints(graphInfo_.id);
152
153 // Add the nodes
154 ✗ nodes_.clear();
155 ✗ edges_.clear();
156 ✗ bool hideW = !showWaypoints_->isChecked();
157 ✗ QMap<hpp::ID, bool> nodeIsWaypoint;
158 ✗ QMap<hpp::ID, bool> edgeVisible;
159
160 // initialize node counters.
161 ✗ for (std::size_t i = 0; i < elmts->nodes.length(); ++i) {
162 ✗ if (elmts->nodes[(CORBA::ULong)i].id > graph->id) {
163 ✗ ::hpp::ID id = elmts->nodes[(CORBA::ULong)i].id;
164 ✗ nodeIsWaypoint[id] = false;
165 }
166 }
167
168 // Find what edge are visible and count the nodes accordingly.
169 ✗ for (std::size_t i = 0; i < elmts->edges.length(); ++i) {
170 ✗ if (elmts->edges[(CORBA::ULong)i].id > graph->id) {
171 ✗ ::hpp::ID id = elmts->edges[(CORBA::ULong)i].id;
172 ✗ ::CORBA::Long weight = manip_->graph()->getWeight(id);
173
174 ✗ for (std::size_t k = 0;
175 ✗ k < elmts->edges[(CORBA::ULong)i].waypoints.length(); ++k)
176 ✗ nodeIsWaypoint[elmts->edges[(CORBA::ULong)i]
177 ✗ .waypoints[(CORBA::ULong)k]] = true;
178
179 bool hasWaypoints =
180 ✗ elmts->edges[(CORBA::ULong)i].waypoints.length() > 0;
181 // If show Waypoint and this is not a waypoint edge
182 // or hide Waypoint and this is not a transition inside a
183 // WaypointEdge
184 ✗ edgeVisible[id] = (!hideW && !hasWaypoints) || (hideW && weight >= 0);
185 }
186 }
187
188 ✗ for (std::size_t i = 0; i < elmts->nodes.length(); ++i) {
189 ✗ if (elmts->nodes[(CORBA::ULong)i].id > graph->id) {
190 ✗ Q_ASSERT(nodeIsWaypoint.contains(elmts->nodes[(CORBA::ULong)i].id));
191
192 ✗ if (hideW && nodeIsWaypoint[elmts->nodes[(CORBA::ULong)i].id]) {
193 ✗ qDebug() << "Ignoring node" << elmts->nodes[(CORBA::ULong)i].name;
194 ✗ continue;
195 }
196 ✗ QString nodeName(elmts->nodes[(CORBA::ULong)i].name);
197 ✗ nodeName.replace(" : ", "\n");
198 ✗ QGVNode* n = scene_->addNode(nodeName);
199 ✗ if (i == 0) scene_->setRootNode(n);
200 ✗ NodeInfo ni;
201 ✗ ni.id = elmts->nodes[(CORBA::ULong)i].id;
202 ✗ ni.node = n;
203 ✗ ni.constraintStr = getConstraints(ni.id);
204 ✗ nodeInfos_[n] = ni;
205 ✗ n->setFlag(QGraphicsItem::ItemIsMovable, true);
206 ✗ n->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
207 ✗ nodes_[elmts->nodes[(CORBA::ULong)i].id] = n;
208
209 ✗ if (nodeIsWaypoint[ni.id]) n->setAttribute("shape", "hexagon");
210 }
211 }
212 ✗ for (std::size_t i = 0; i < elmts->edges.length(); ++i) {
213 ✗ if (elmts->edges[(CORBA::ULong)i].id > graph->id) {
214 ✗ Q_ASSERT(edgeVisible.contains(elmts->edges[(CORBA::ULong)i].id) &&
215 nodeIsWaypoint.contains(elmts->edges[(CORBA::ULong)i].start) &&
216 nodeIsWaypoint.contains(elmts->edges[(CORBA::ULong)i].end));
217 ✗ if (!edgeVisible[elmts->edges[(CORBA::ULong)i].id]) {
218 ✗ qDebug() << "Ignoring edge" << elmts->edges[(CORBA::ULong)i].name;
219 ✗ continue;
220 }
221 ✗ EdgeInfo ei;
222 QGVEdge* e =
223 ✗ scene_->addEdge(nodes_[elmts->edges[(CORBA::ULong)i].start],
224 ✗ nodes_[elmts->edges[(CORBA::ULong)i].end], "");
225 ✗ ei.name = QString::fromLocal8Bit(elmts->edges[(CORBA::ULong)i].name);
226 ✗ ei.id = elmts->edges[(CORBA::ULong)i].id;
227 ✗ CORBA::String_var cnname = manip_->graph()->getContainingNode(ei.id);
228 ✗ ei.containingNodeName = QString::fromLocal8Bit((char*)cnname);
229 ✗ ei.edge = e;
230 ✗ updateWeight(ei, true);
231
232 ✗ if (elmts->edges[(CORBA::ULong)i].waypoints.length() > 0) {
233 ei.constraintStr =
234 ✗ tr("<p><h4>Waypoint transition</h4>"
235 "This transition has %1 waypoints.<br/>"
236 "To see the constraints of the transition inside,<br/>"
237 "re-draw the graph after enabling \"Show waypoints\"</p>")
238 ✗ .arg(elmts->edges[(CORBA::ULong)i].waypoints.length());
239 ✗ ei.shortStr = "";
240 } else {
241 ✗ ei.constraintStr = getConstraints(ei.id);
242
243 ✗ if (manip_->graph()->isShort(ei.id)) ei.shortStr = "<h4>Short</h4>";
244 }
245
246 // If this is a transition inside a WaypointEdge
247 ✗ if (ei.weight < 0) {
248 ✗ e->setAttribute("weight", "3");
249 ✗ if (elmts->edges[(CORBA::ULong)i].start >=
250 ✗ elmts->edges[(CORBA::ULong)i].end)
251 ✗ e->setAttribute("constraint", "false");
252 }
253
254 ✗ edgeInfos_[e] = ei;
255 ✗ edges_[ei.id] = e;
256 }
257 }
258 ✗ } catch (const hpp::Error& e) {
259 ✗ qDebug() << e.msg;
260 }
261 }
262
263 ✗ void HppManipulationGraphWidget::updateStatistics() {
264 ✗ if (manip_ == NULL) {
265 ✗ updateStatsTimer_->stop();
266 ✗ statButton_->setChecked(false);
267 ✗ return;
268 }
269 try {
270 ✗ foreach (QGraphicsItem* elmt, scene_->items()) {
271 ✗ QGVNode* node = dynamic_cast<QGVNode*>(elmt);
272 ✗ if (node) {
273 ✗ NodeInfo& ni = nodeInfos_[node];
274 ✗ manip_->graph()->getConfigProjectorStats(ni.id, ni.configStat,
275 ✗ ni.pathStat);
276 ✗ ni.freq = manip_->graph()->getFrequencyOfNodeInRoadmap(
277 ni.id, ni.freqPerCC.out());
278 ✗ float sr = (ni.configStat.nbObs > 0) ? (float)ni.configStat.success /
279 ✗ (float)ni.configStat.nbObs
280 : 0.f / 0.f;
281 QString colorcode =
282 ✗ (ni.configStat.nbObs > 0)
283 ✗ ? QColor(255, (int)(sr * 255), (int)(sr * 255)).name()
284 ✗ : "white";
285 ✗ const QString& fillcolor = node->getAttribute("fillcolor");
286 ✗ if (!(fillcolor == colorcode)) {
287 ✗ node->setAttribute("fillcolor", colorcode);
288 ✗ node->updateLayout();
289 }
290 ✗ continue;
291 }
292 ✗ QGVEdge* edge = dynamic_cast<QGVEdge*>(elmt);
293 ✗ if (edge) {
294 ✗ EdgeInfo& ei = edgeInfos_[edge];
295 ✗ manip_->graph()->getConfigProjectorStats(ei.id, ei.configStat,
296 ✗ ei.pathStat);
297 ✗ manip_->graph()->getEdgeStat(ei.id, ei.errors.out(), ei.freqs.out());
298 ✗ float sr = (ei.configStat.nbObs > 0) ? (float)ei.configStat.success /
299 ✗ (float)ei.configStat.nbObs
300 : 0.f / 0.f;
301 ✗ QString colorcode = (ei.configStat.nbObs > 0)
302 ✗ ? QColor(255 - (int)(sr * 255), 0, 0).name()
303 ✗ : "";
304 ✗ const QString& color = edge->getAttribute("color");
305 ✗ if (!(color == colorcode)) {
306 ✗ edge->setAttribute("color", colorcode);
307 ✗ edge->updateLayout();
308 }
309 ✗ continue;
310 }
311 }
312 ✗ scene_->update();
313 ✗ selectionChanged();
314 ✗ } catch (const CORBA::Exception&) {
315 ✗ updateStatsTimer_->stop();
316 ✗ statButton_->setChecked(false);
317 ✗ throw;
318 }
319 }
320
321 ✗ void HppManipulationGraphWidget::showNodeOfConfiguration(
322 const hpp::floatSeq& cfg) {
323 static bool lastlog = false;
324 ✗ if (manip_ == NULL) return;
325 ✗ if (showNodeId_ >= 0) {
326 // Do unselect
327 ✗ nodes_[showNodeId_]->setAttribute("fillcolor", "white");
328 ✗ nodes_[showNodeId_]->updateLayout();
329 }
330 try {
331 ✗ manip_->graph()->getNode(cfg, showNodeId_);
332 // Do select
333 ✗ if (nodes_.contains(showNodeId_)) {
334 ✗ nodes_[showNodeId_]->setAttribute("fillcolor", "green");
335 ✗ nodes_[showNodeId_]->updateLayout();
336 ✗ scene_->update();
337 } else {
338 ✗ qDebug() << "Node" << showNodeId_
339 ✗ << "does not exist. Refer the graph may solve the issue.";
340 ✗ showNodeId_ = -1;
341 }
342 ✗ lastlog = false;
343 ✗ } catch (const hpp::Error& e) {
344 ✗ if (!lastlog)
345 ✗ qDebug() << "HppManipulationGraphWidget::showNodeOfConfiguration"
346 ✗ << e.msg;
347 ✗ lastlog = true;
348 }
349 }
350
351 ✗ void HppManipulationGraphWidget::showEdge(const hpp::ID& edgeId) {
352 ✗ if (showEdgeId_ >= 0) {
353 // Do unselect
354 ✗ edges_[showEdgeId_]->setAttribute("color", "");
355 ✗ edges_[showEdgeId_]->updateLayout();
356 }
357 ✗ showEdgeId_ = edgeId;
358 // Do select
359 ✗ if (edges_.contains(showEdgeId_)) {
360 ✗ edges_[showEdgeId_]->setAttribute("color", "green");
361 ✗ edges_[showEdgeId_]->updateLayout();
362 ✗ scene_->update();
363 } else {
364 ✗ showEdgeId_ = -1;
365 }
366 }
367
368 ✗ void HppManipulationGraphWidget::nodeContextMenu(QGVNode* node) {
369 ✗ const NodeInfo& ni = nodeInfos_[node];
370 ✗ hpp::ID id = currentId_;
371 ✗ currentId_ = ni.id;
372
373 ✗ QMenu cm("Node context menu", this);
374 ✗ foreach (GraphAction* action, nodeContextMenuActions_) {
375 ✗ cm.addAction(action);
376 }
377 ✗ cm.exec(QCursor::pos());
378
379 ✗ currentId_ = id;
380 }
381
382 ✗ void HppManipulationGraphWidget::nodeDoubleClick(QGVNode* node) {
383 ✗ const NodeInfo& ni = nodeInfos_[node];
384 ✗ displayNodeConstraint(ni.id);
385 }
386
387 ✗ void HppManipulationGraphWidget::displayNodeConstraint(hpp::ID id) {
388 ✗ if (manip_ == NULL) return;
389 ✗ CORBA::String_var str;
390 ✗ manip_->graph()->displayNodeConstraints(id, str.out());
391 ✗ QString nodeStr(str);
392 ✗ constraintInfo_->setText(nodeStr);
393 }
394
395 ✗ void HppManipulationGraphWidget::displayEdgeConstraint(hpp::ID id) {
396 ✗ if (manip_ == NULL) return;
397 ✗ CORBA::String_var str;
398 ✗ manip_->graph()->displayEdgeConstraints(id, str.out());
399 ✗ QString nodeStr(str);
400 ✗ constraintInfo_->setText(nodeStr);
401 }
402
403 ✗ void HppManipulationGraphWidget::displayEdgeTargetConstraint(hpp::ID id) {
404 ✗ if (manip_ == NULL) return;
405 ✗ CORBA::String_var str;
406 ✗ manip_->graph()->displayEdgeTargetConstraints(id, str.out());
407 ✗ QString nodeStr(str);
408 ✗ constraintInfo_->setText(nodeStr);
409 }
410
411 ✗ void HppManipulationGraphWidget::edgeContextMenu(QGVEdge* edge) {
412 ✗ const EdgeInfo& ei = edgeInfos_[edge];
413 ✗ hpp::ID id = currentId_;
414 ✗ currentId_ = ei.id;
415
416 ✗ QMenu cm("Edge context menu", this);
417 ✗ foreach (GraphAction* action, edgeContextMenuActions_) {
418 ✗ cm.addAction(action);
419 }
420 ✗ cm.exec(QCursor::pos());
421
422 ✗ currentId_ = id;
423 }
424
425 ✗ void HppManipulationGraphWidget::edgeDoubleClick(QGVEdge* edge) {
426 ✗ EdgeInfo& ei = edgeInfos_[edge];
427 bool ok;
428 ✗ ::CORBA::Long w = QInputDialog::getInt(
429 ✗ this, "Update edge weight", tr("Edge %1 weight").arg(ei.name), ei.weight,
430 0, std::numeric_limits<int>::max(), 1, &ok);
431 ✗ if (ok) {
432 ✗ updateWeight(ei, w);
433 ✗ edge->updateLayout();
434 }
435 }
436
437 ✗ void HppManipulationGraphWidget::selectionChanged() {
438 ✗ QList<QGraphicsItem*> items = scene_->selectedItems();
439 ✗ currentId_ = -1;
440
441 ✗ QString type, name;
442 ::hpp::ID id;
443 ✗ QString end;
444 ✗ QString constraints;
445 ✗ QString weight;
446
447 ✗ if (items.size() == 0) {
448 ✗ if (graphInfo_.id < 0) {
449 ✗ elmtInfo_->setText("No info");
450 ✗ return;
451 }
452 ✗ type = "Graph";
453 ✗ id = graphInfo_.id;
454 ✗ constraints = graphInfo_.constraintStr;
455 ✗ } else if (items.size() == 1) {
456 ✗ QGVNode* node = dynamic_cast<QGVNode*>(items.first());
457 ✗ QGVEdge* edge = dynamic_cast<QGVEdge*>(items.first());
458 ✗ if (node) {
459 ✗ type = "Node";
460 ✗ name = node->label();
461 ✗ const NodeInfo& ni = nodeInfos_[node];
462 ✗ id = ni.id;
463 ✗ currentId_ = id;
464 ✗ constraints = ni.constraintStr;
465 ✗ end = QString("<p><h4>Nb node in roadmap:</h4> %1</p>").arg(ni.freq);
466 ✗ end.append("<p><h4>Nb node in roadmap per connected component</h4>\n");
467 ✗ for (std::size_t i = 0; i < ni.freqPerCC->length(); ++i) {
468 ✗ end.append(QString(" %1,").arg(ni.freqPerCC.in()[(CORBA::ULong)i]));
469 }
470 ✗ end.append("</p>");
471 ✗ } else if (edge) {
472 ✗ type = "Edge";
473 ✗ const EdgeInfo& ei = edgeInfos_[edge];
474 ✗ name = ei.name;
475 ✗ id = ei.id;
476 ✗ currentId_ = id;
477 ✗ weight = QString("<li>Weight: %1</li>").arg(ei.weight);
478 ✗ end = "<p>Extension results<ul>";
479 ✗ for (std::size_t i = 0;
480 ✗ i < std::min(ei.errors->length(), ei.freqs->length()); ++i) {
481 ✗ end.append(QString("<li>%1: %2</li>")
482 ✗ .arg(QString(ei.errors.in()[(CORBA::ULong)i]))
483 ✗ .arg(ei.freqs.in()[(CORBA::ULong)i]));
484 }
485 ✗ end.append("</ul></p>");
486 ✗ end.append(QString("<p><h4>Containing node</h4>\n%1</p>")
487 ✗ .arg(ei.containingNodeName));
488 ✗ constraints = ei.constraintStr;
489 } else {
490 ✗ return;
491 }
492 }
493 ✗ elmtInfo_->setText(QString("<h4>%1 %2</h4><ul>"
494 "<li>Id: %3</li>"
495 "%4"
496 "</ul>%5%6")
497 ✗ .arg(type)
498 ✗ .arg(ESCAPE(name))
499 ✗ .arg(id)
500 ✗ .arg(weight)
501 ✗ .arg(end)
502 ✗ .arg(constraints));
503 }
504
505 ✗ void HppManipulationGraphWidget::startStopUpdateStats(bool start) {
506 ✗ if (start)
507 ✗ updateStatsTimer_->start();
508 else
509 ✗ updateStatsTimer_->stop();
510 }
511
512 ✗ HppManipulationGraphWidget::NodeInfo::NodeInfo()
513 ✗ : id(-1), freq(0), freqPerCC(new ::hpp::intSeq()) {
514 ✗ initConfigProjStat(configStat);
515 ✗ initConfigProjStat(pathStat);
516 }
517
518 ✗ HppManipulationGraphWidget::EdgeInfo::EdgeInfo() : id(-1), edge(NULL) {
519 ✗ initConfigProjStat(configStat);
520 ✗ initConfigProjStat(pathStat);
521 ✗ errors = new Names_t();
522 ✗ freqs = new intSeq();
523 }
524
525 ✗ void HppManipulationGraphWidget::updateWeight(EdgeInfo& ei, bool get) {
526 ✗ if (manip_ == NULL) return;
527 ✗ if (get) ei.weight = manip_->graph()->getWeight(ei.id);
528 ✗ if (ei.edge == NULL) return;
529 ✗ if (ei.weight <= 0) {
530 ✗ ei.edge->setAttribute("style", "dashed");
531 ✗ ei.edge->setAttribute("penwidth", "1");
532 } else {
533 ✗ ei.edge->setAttribute("style", "filled");
534 ✗ ei.edge->setAttribute("penwidth", QString::number(1 + (ei.weight - 1 / 5)));
535 }
536 }
537
538 ✗ void HppManipulationGraphWidget::updateWeight(EdgeInfo& ei,
539 const ::CORBA::Long w) {
540 ✗ if (manip_ == NULL) return;
541 ✗ manip_->graph()->setWeight(ei.id, w);
542 ✗ ei.weight = w;
543 ✗ updateWeight(ei, false);
544 }
545
546 ✗ QString HppManipulationGraphWidget::getConstraints(hpp::ID id) {
547 ✗ assert(manip_ != NULL);
548 ✗ QString ret;
549 ✗ hpp::Names_t_var c = new hpp::Names_t;
550 ✗ manip_->graph()->getNumericalConstraints(id, c);
551 ✗ ret.append("<p><h4>Applied constraints</h4>");
552 ✗ if (c->length() > 0) {
553 ✗ ret.append("<ul>");
554 ✗ for (unsigned i = 0; i < c->length(); i++) {
555 ✗ ret.append(QString("<li>%1</li>").arg(c[i].in()));
556 }
557 ✗ ret.append("</ul></p>");
558 } else
559 ✗ ret.append("No constraints applied</p>");
560 ✗ return ret;
561 }
562 } // namespace plot
563 } // namespace hpp
564