- bool changed = false;
- do {
- changed = false;
- for (BasicBlockWidget * widget : widgets) {
- QPointF out(std::get<0>(widget->getExits()));
- BasicBlockWidget ** next = widget->getNext();
-
- if (NULL != next[0]
- && (next[0]->getEntry() - widget->getEntry()).y() > 0
- && (next[0]->getEntry() - out).y() < 50) {
- next[0]->moveBy(0, 1);
- changed = true;
- }
- if (NULL != next[1]
- && (next[1]->getEntry() - widget->getEntry()).y() > 0
- && (next[1]->getEntry() - out).y() < 50) {
- next[1]->moveBy(0, 1);
- changed = true;
- }
- }
- } while (changed);
+ bool changed = false;
+
+ /* While some BasicBlockWidget overlaps with a direct predecessor,
+ * move that widget down one step. Move each widget at most once
+ * per iteration so that widgets with severall incoming edges
+ * don't outrun these with less -- preserving order by address
+ * where appropriate.
+ */
+ do {
+ changed = false;
+ for (BasicBlockWidget * widget : widgets) {
+ QPointF out(std::get<0>(widget->getExits()));
+ BasicBlockWidget ** next = widget->getNext();
+
+ if (NULL != next[0]
+ && (next[0]->getEntry() - widget->getEntry()).y() > 0
+ && (next[0]->getEntry() - out).y() < 50) {
+ widget->moveBy(0, -1);
+ changed = true;
+ } else if (NULL != next[1]
+ && (next[1]->getEntry() - widget->getEntry()).y() > 0
+ && (next[1]->getEntry() - out).y() < 50) {
+ widget->moveBy(0, -1);
+ changed = true;
+ }
+ }
+ } while (changed);
+
+ /* If there are still BasicBlockWidgets overlapping (BasicBlocks
+ * that don't have a direct edge) spread them sideways.
+ */
+ for (BasicBlockWidget * widget : widgets) {
+ QRectF relevantRect = widget->boundingRect();
+ relevantRect.moveTo(widget->scenePos());
+ relevantRect.adjust(-20, -20, 20, 20);
+ for (QGraphicsItem * item : items(relevantRect)) {
+ if (item == widget) continue;
+ if (std::find(widgets.begin(), widgets.end(), item) == widgets.end()) continue;
+ QRectF itemrect = item->boundingRect();
+ itemrect.moveTo(item->scenePos());
+ while (relevantRect.intersects(itemrect)) {
+ if (widget->scenePos().x() > item->scenePos().x()) {
+ widget->moveBy(1, 0);
+ relevantRect.moveTo(widget->scenePos());
+ } else {
+ item->moveBy(1, 0);
+ itemrect.moveTo(item->scenePos());
+ }
+ }
+ }
+ }
+}
+
+void CFGScene::highlightBlock(BasicBlockWidget* block) {
+ QGraphicsView* view = *(views().begin());
+ if (highlightedBlock) {
+ highlightedBlock->setColor(highlightedBlock->defaultColor);
+ update(highlightedBlock->boundingRect());
+ }
+ highlightedBlock = block;
+ view->centerOn(block);
+ block->setColor(block->highlightColor);
+ update(block->boundingRect());