#include "blockview.h" #include BlockBusItem::BlockBusItem(bool temp): QGraphicsObject(), PropertyStorage() { temp_ = temp; _init(); if (!temp) setData(bvidType, bvitBus); else hide(); } BlockBusItem::BlockBusItem(const BlockBusItem & other): QGraphicsObject(), PropertyStorage() { temp_ = false; _init(); setData(bvidType, bvitBus); setPen(other.pen()); setBrush(other.brush()); setBusType(other.busType()); square_node = other.square_node; max_ep = other.max_ep; pol = other.pol; segments = other.segments; im_bus = other.im_bus; im_end = other.im_end; im_bus_scale = other.im_bus_scale; im_end_scale = other.im_end_scale; updateGeometry(); } void BlockBusItem::_init() { setZValue(1.); setBusType(-1); setAcceptHoverEvents(true); ph.setColor(Qt::blue); ph.setJoinStyle(Qt::MiterJoin); bh.setColor(Qt::blue); bh.setStyle(Qt::SolidPattern); pu = pa = pr = ph; bu = ba = br = bh; grid_step = 10.; pu.setWidth(1); pu.setColor(Qt::black); bu.setColor(Qt::black); pa.setColor(Qt::darkGreen); ba.setColor(Qt::darkGreen); pr.setColor(Qt::darkRed); br.setColor(Qt::darkRed); pn.setColor(Qt::gray); pn.setStyle(Qt::DashLine); if (temp_) { pu.setStyle(Qt::DashLine); pu.setColor(Qt::darkGray); bu.setColor(Qt::darkGray); } setPen(pu); setBrush(bu); square_node = false; max_ep = 0; selPoint = selSegment = state_ = -1; pen_width = 2.; point_size = 3.; im_bus_scale = im_end_scale = 1.; moved = deleted = mark_in = mark_out = new_segment = mm_cancel = lm_point = false; anim_point_size.setTargetObject(this); anim_point_size.setPropertyName("pointSize"); anim_point_size.setStartValue(0); anim_point_size.setEasingCurve(QEasingCurve::OutQuad); anim_point_size.setEndValue(point_size); anim_point_size.setDuration(200); } void BlockBusItem::reconnect() { if (temp_) return; if (!scene()) return; if (scene()->views().isEmpty()) return; qobject_cast(scene()->views().back())->reconnectAll(); } bool BlockBusItem::sceneEvent(QEvent * e) { if (temp_) return QGraphicsObject::sceneEvent(e); switch (e->type()) { case QEvent::GraphicsSceneHoverEnter: hoverEnterEvent((QGraphicsSceneHoverEvent *)e); break; case QEvent::GraphicsSceneHoverMove: hoverMoveEvent((QGraphicsSceneHoverEvent *)e); break; case QEvent::GraphicsSceneHoverLeave: hoverLeaveEvent((QGraphicsSceneHoverEvent *)e); break; case QEvent::GraphicsSceneMousePress: mousePressEvent((QGraphicsSceneMouseEvent *)e); break; case QEvent::GraphicsSceneMouseMove: mouseMoveEvent((QGraphicsSceneMouseEvent *)e); break; case QEvent::GraphicsSceneMouseRelease: mouseReleaseEvent((QGraphicsSceneMouseEvent *)e); break; default: break; } return QGraphicsObject::sceneEvent(e); } int BlockBusItem::addPoint(const QPointF & point, bool update) { int ei = pol.indexOf(point); if (ei >= 0) return ei; if (selSegment < 0 || selSegment >= pol.size() - 1) return -1; pol << quantize(nearestPointOnLine(pol[segments[selSegment].first], pol[segments[selSegment].second], point), grid_step); selPoint = pol.size() - 1; segments << QPair(selPoint, segments[selSegment].second); segments[selSegment].second = selPoint; selSegment = -1; updateGeometry(); if (scene() != 0 && update) scene()->update(); return pol.size() - 1; } int BlockBusItem::segmentPointPair(int point, int * seg) const { for (int i = 0; i < segments.size(); ++i) { if (segments[i].first == point) { if (seg) *seg = i; return segments[i].second; } if (segments[i].second == point) { if (seg) *seg = i; return segments[i].first; } } if (seg) *seg = -1; return -1; } void BlockBusItem::removePoint(int index) { if (index < 0 || index > pol.size() - 1) return; int sc = 0, fs = -1, ss = -1; for (int i = 0; i < segments.size(); ++i) if (segments[i].first == index || segments[i].second == index) { sc++; if (fs < 0) fs = i; else ss = i; } int ei(0); switch (sc) { case 1: segments.removeAt(fs); break; case 2: if (segments[ss].first == index) ei = segments[ss].second; else ei = segments[ss].first; if (segments[fs].first == index) segments[fs].first = ei; else segments[fs].second = ei; segments.removeAt(ss); break; default: return; } pol.remove(index); for (int i = 0; i < segments.size(); ++i) { if (segments[i].first >= index) segments[i].first--; if (segments[i].second >= index) segments[i].second--; } selPoint = -1; checkDelete(); updateGeometry(); if (scene() != 0) scene()->update(); } void BlockBusItem::removeSegment(int index) { if (index < 0 || index > segments.size() - 1) return; int pif = segments[index].first, pis = segments[index].second; if (pif > pis) qSwap(pif, pis); int scf = 0, scs = 0; for (int i = 0; i < segments.size(); ++i) { if (segments[i].first == pif || segments[i].second == pif) scf++; if (segments[i].first == pis || segments[i].second == pis) scs++; } if (scs <= 2) removePoint(pis); if (scf <= 2) removePoint(pif); if (scs <= 2 || scf <= 2) selSegment = -1; if (scene() != 0) scene()->update(); } void BlockBusItem::appendPoint(const QPointF & p) { pol << p; if (pol.size() > 1) segments << QPair(pol.size() - 2, pol.size() - 1); updateGeometry(); } void BlockBusItem::appendPoint(qreal x, qreal y) { appendPoint(QPointF(x, y)); } void BlockBusItem::clear() { pol.clear(); segments.clear(); updateGeometry(); } void BlockBusItem::movePolyline(const QPointF & dp) { pol.translate(dp); prepareGeometryChange(); } void BlockBusItem::movePoint(int index, const QPointF & dp) { pol[index] += dp; prepareGeometryChange(); } void BlockBusItem::setWidth(const double & w) { pen_width = w; update(); } void BlockBusItem::setColor(const QColor & c) { pu.setColor(c); bu.setColor(c); update(); } void BlockBusItem::setSquareNodes(bool yes) { square_node = yes; update(); } void BlockBusItem::markAsInput() { mark_in = true; mark_out = false; } void BlockBusItem::markAsOutput() { mark_in = false; mark_out = true; } void BlockBusItem::unmark() { mark_in = mark_out = false; } void BlockBusItem::simplify(bool full) { int pcnt = pol.size(); for (int s = 0; s < segments.size(); ++s) { if (pol[segments[s].first] != pol[segments[s].second]) continue; int ti = segments[s].first, fi = segments[s].second; segments.removeAt(s); pol.remove(fi); for (int i = 0; i < segments.size(); ++i) { if (segments[i].first == fi) segments[i].first = ti; if (segments[i].second == fi) segments[i].second = ti; if (segments[i].first > fi) segments[i].first--; if (segments[i].second > fi) segments[i].second--; } } if (full) { QList segs; for (int p = 0; p < pol.size(); ++p) { if (pointSegmentsCount(p, &segs) != 2) continue; int s0 = segs[0], s1 = segs[1]; QPointF cp = pol[p], sp[2]; for (int i = 0; i < 2; ++i) { if (segments[segs[i]].first == p) sp[i] = pol[segments[segs[i]].second]; else sp[i] = pol[segments[segs[i]].first]; } QLineF l0(sp[0], cp), l1(cp, sp[1]); if (qAbs(l0.angle() - l1.angle()) > 0.1) continue; if (segments[s0].first == p) { if (segments[s1].first == p) segments[s0].first = segments[s1].second; else segments[s0].first = segments[s1].first; } else { if (segments[s1].first == p) segments[s0].second = segments[s1].second; else segments[s0].second = segments[s1].first; } segments.removeAt(s1); pol.remove(p); for (int i = 0; i < segments.size(); ++i) { if (segments[i].first >= p) segments[i].first--; if (segments[i].second >= p) segments[i].second--; } p = -1; } } if (pcnt == pol.size()) return; updateGeometry(); } bool BlockBusItem::hasNullSegment() const { for (int s = 0; s < segments.size(); ++s) { if (pol[segments[s].first] == pol[segments[s].second]) return true; } return false; } void BlockBusItem::adjustLine() {} int BlockBusItem::endpointCount() const { return endpoints().size(); } QList BlockBusItem::connectedBlocks() const { QList pins = connections_.values(); QSet ret; foreach(BlockItemPin * p, pins) ret << p->parent(); return ret.values(); } QList BlockBusItem::connectedPins() const { return connections_.values(); } BlockBusItem::PointInfo BlockBusItem::pointInfo(QPointF pos) const { PointInfo ret; int pi = -1, si = -1; testPoint(pos, &pi, &si); if (pi < 0 && si < 0) return ret; if (si >= 0) { ret.type = PointInfo::Type::Segment; } else { if (endpoints().contains(pi)) { ret.type = PointInfo::Type::Endpoint; ret.pin = connections_.value(pi, nullptr); } else ret.type = PointInfo::Type::Node; } return ret; } void BlockBusItem::setBusState(bool state) { int s = state ? 1 : 0; if (state_ == s) return; state_ = s; update(); } void BlockBusItem::clearBusState() { if (state_ == -1) return; state_ = -1; update(); } QByteArray BlockBusItem::save() const { ChunkStream cs; cs << cs.chunk(1, busType()) << cs.chunk(2, busName()) << cs.chunk(3, width()) << cs.chunk(4, pen()) << cs.chunk(5, brush()) << cs.chunk(6, pol) << cs.chunk(7, segments) << cs.chunk(8, props) << cs.chunk(9, im_bus_scale) << cs.chunk(10, im_end_scale); return cs.data(); } void BlockBusItem::load(const QByteArray & data) { clear(); if (data.isEmpty()) return; ChunkStream cs(data); while (!cs.atEnd()) { switch (cs.read()) { case 1: setBusType(cs.getData()); break; case 2: setBusName(cs.getData()); break; case 3: setWidth(cs.getData()); break; case 4: setPen(cs.getData()); break; case 5: setBrush(cs.getData()); break; case 6: pol = cs.getData(); break; case 7: segments = cs.getData>>(); break; case 8: props = cs.getData>(); break; case 9: im_bus_scale = cs.getData(); break; case 10: im_end_scale = cs.getData(); break; } } updateGeometry(); } BlockBusItem * BlockBusItem::copy() const { return new BlockBusItem(*this); } void BlockBusItem::saveState() { segments_s = segments; ends_ind_s = ends_ind; ends_s = ends; pol_s = pol; } void BlockBusItem::restoreState() { segments = segments_s; ends_ind = ends_ind_s; ends = ends_s; pol = pol_s; } void BlockBusItem::updateGeometry() { ends = endpoints(); ends_ind.clear(); for (int e = 0; e < ends.size(); ++e) { int ce = ends[e]; for (int s = 0; s < segments.size(); ++s) { if (segments[s].first == ce) { ends_ind << QPair(segments[s].first, segments[s].second); break; } if (segments[s].second == ce) { ends_ind << QPair(segments[s].second, segments[s].first); break; } } } reconnect(); prepareGeometryChange(); } bool BlockBusItem::checkDelete() { if (pol.size() >= 2 && segments.size() >= 1) return false; deleteLater(); return true; } void BlockBusItem::emitAction(BlockItemBase::Action a) { qobject_cast(scene()->views().back())->schemeAction(a, QList() << this); qobject_cast(scene()->views().back())->connectionsChanged(); } QVector BlockBusItem::endpoints() const { QVector counts(pol.size(), 0), ret; for (int i = 0; i < segments.size(); ++i) { counts[segments[i].first]++; counts[segments[i].second]++; } for (int i = 0; i < counts.size(); ++i) { if (counts[i] == 1) ret << i; } return ret; } QVector BlockBusItem::endpointLine(int ep, double angle) const { QVector ret; int seg = -1; int np = segmentPointPair(ep, &seg), pp = np; if (ep < 0 || np < 0) return ret; if (pol[np] == pol[ep]) return ret; QLineF l(pol[ep], pol[np]); // qDebug() << "first" << l.angle() << angle << (l.angle() != angle); if (qAbs(l.angle() - angle) > 0.1) return ret; // qDebug() << "check next" << segments.size(); for (int i = 0; i < segments.size(); ++i) { // qDebug() << i << np << pointSegmentsCount(np); if (np < 0) break; if (pointSegmentsCount(np) != 2) break; if (i > 0) { QLineF l(pol[pp], pol[np]); // qDebug() << i << l.angle() << angle; if (qAbs(l.angle() - angle) > 0.1) break; } ret << np; pp = np; np = neighborSegmentPoint(np, &seg); } return ret; } int BlockBusItem::pointSegmentsCount(int point, QList * segs) const { int ret = 0; if (segs) segs->clear(); for (int i = 0; i < segments.size(); ++i) if (segments[i].first == point || segments[i].second == point) { ret++; if (segs) segs->append(i); } return ret; } int BlockBusItem::neighborSegmentPoint(int point, int * seg) const { if (point < 0 || !seg) return -1; for (int i = 0; i < segments.size(); ++i) { if (i == *seg) continue; if (segments[i].first == point) { *seg = i; return segments[i].second; } if (segments[i].second == point) { *seg = i; return segments[i].first; } } return -1; } void BlockBusItem::testPoint(QPointF pos, int * sel_point, int * sel_segment, bool for_trace) const { for (int i = 0; i < pol.size(); ++i) { if ((pol[i] - pos).manhattanLength() <= (for_trace ? 5. : 10.)) { // Point *sel_point = i; *sel_segment = -1; return; } } for (int i = 0; i < segments.size(); ++i) { if (distPointToLine(pol[segments[i].first], pol[segments[i].second], pos) <= (for_trace ? 5. : 7.)) { // Segment *sel_point = -1; *sel_segment = i; return; } } *sel_point = -1; *sel_segment = -1; } void BlockBusItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) { tt = bus_name + (bus_name.isEmpty() ? "" : "\n\n") + tr("Add point: Ctrl + LeftClick\n" "Remove point\\segment: Ctrl + RightClick\n" "Remove connection: Shift + RightClick\n" "Move point\\segment: Shift + LeftPress\n" "Change trace mode: press Shift, when mouse move"); } void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) { if (temp_) return; QPointF sp = e->scenePos(); int pp = selPoint; int ps = selSegment; bool empt = !(selPoint >= 0 || selSegment >= 0); testPoint(sp, &selPoint, &selSegment); BlockView * bv = 0; if (!scene()->views().isEmpty()) { bv = qobject_cast(scene()->views().back()); } if ((selPoint >= 0 && pp != selPoint) || (selSegment >= 0 && ps != selSegment)) { if (bv) { if (bv->isBlockAnimationEnabled()) { setPointSize(0); anim_point_size.start(); } } else setPointSize(anim_point_size.endValue().toDouble()); } if (selPoint >= 0 || selSegment >= 0) { if (empt) { QList pins = connectedPins(); foreach(BlockItemPin * p, pins) { p->animAccept(); } } setToolTip(tt); update(); if (bv) bv->cur_bus = this; return; } if (bv) bv->cur_bus = 0; setToolTip(QString()); QList il = scene()->items(sp, Qt::ContainsItemBoundingRect, Qt::DescendingOrder), bil; bil << this; for (int i = 0; i < il.size(); ++i) { QGraphicsItem * b = il[i]; if ((b->data(bvidType).toInt() == bvitBus) && b != this) { int tp = -1, ts = -1; ((BlockBusItem *)b)->testPoint(sp, &tp, &ts); if (tp >= 0 || ts >= 0) { foreach(QGraphicsItem * b2, bil) b2->stackBefore(b); break; } bil << b; } } update(); } void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) { if (temp_) return; selPoint = selSegment = -1; setPen(pu); setBrush(bu); setToolTip(QString()); anim_point_size.stop(); BlockView * bv = 0; if (!scene()->views().isEmpty()) bv = qobject_cast(scene()->views().back()); if (bv && (QApplication::mouseButtons() == 0)) bv->cur_bus = 0; update(); QGraphicsObject::hoverLeaveEvent(e); } void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) { if (temp_) return; lp = quantize(e->scenePos(), grid_step); if (e->button() != Qt::RightButton) bpol = pol; BlockView * bv = 0; if (!scene()->views().isEmpty()) { bv = qobject_cast(scene()->views().back()); } if (bv) { if (selPoint >= 0 || selSegment >= 0) bv->cur_bus = this; } if (new_segment) { qobject_cast(scene()->views().back())->newBranchCancel(); } new_segment = false; if ((selPoint < 0 || selPoint > pol.size() - 1) && (selSegment < 0) && e->modifiers().testFlag(Qt::ShiftModifier)) { QGraphicsObject::mousePressEvent(e); return; } int btncnt = 0; if ((e->button() == Qt::LeftButton) && e->modifiers().testFlag(Qt::ShiftModifier)) { if (endpoints().contains(selPoint)) qobject_cast(scene()->views().back())->startBusPointMove(bus_type); } if (e->buttons().testFlag(Qt::LeftButton)) btncnt++; if (e->buttons().testFlag(Qt::RightButton)) btncnt++; if (e->buttons().testFlag(QT_MID_BUTTON)) btncnt++; if (btncnt > 0) mm_mods = e->modifiers(); if (btncnt >= 2 && e->button() == Qt::RightButton) { // qDebug() << "bus revert"; mm_cancel = true; moved = false; pol = bpol; prepareGeometryChange(); return; } if (e->buttons().testFlag(Qt::LeftButton) && e->modifiers().testFlag(Qt::NoModifier)) { if (selSegment >= 0) press_pos = quantize(nearestPointOnLine(pol[segments[selSegment].first], pol[segments[selSegment].second], e->scenePos()), grid_step); else { if (selPoint >= 0) press_pos = pol[selPoint]; else return; } if (max_ep >= 2) { if (endpointCount() >= max_ep) if (pointSegmentsCount(selPoint) >= 2 || selSegment >= 0) return; } qobject_cast(scene()->views().back())->newBranch(this); new_segment = true; return; } if (e->buttons().testFlag(Qt::RightButton) && e->modifiers().testFlag(Qt::ShiftModifier)) { deleteLater(); } if (e->modifiers().testFlag(Qt::ControlModifier)) { // qDebug() << "remove" << selPoint << selSegment; if (e->buttons().testFlag(Qt::RightButton)) { if (selPoint >= 0 && selPoint <= pol.size() - 1) { removePoint(selPoint); simplify(); if (!checkDelete()) emitAction(BlockItemBase::BusPointRemove); return; } if (selSegment >= 0 && selSegment <= segments.size() - 1) { removeSegment(selSegment); simplify(); if (!checkDelete()) emitAction(BlockItemBase::BusSegmentRemove); return; } } if (e->buttons().testFlag(Qt::LeftButton) && selSegment >= 0) { if (addPoint(e->scenePos()) >= 0) emitAction(BlockItemBase::BusPointAdd); return; } } if (e->buttons().testFlag(Qt::RightButton)) { if (deleted) return; deleted = true; } } void BlockBusItem::mouseMoveEvent(QGraphicsSceneMouseEvent * e) { if (temp_ || mm_cancel) return; if (((selPoint < 0 || selPoint > pol.size() - 1) && (selSegment < 0)) && !new_segment && mm_mods.testFlag(Qt::ShiftModifier)) { QGraphicsObject::mouseMoveEvent(e); return; } BlockView * bv = 0; if (!scene()->views().isEmpty()) { bv = qobject_cast(scene()->views().back()); } qp = quantize(e->scenePos(), grid_step); lp = qp - lp; if (e->buttons().testFlag(Qt::LeftButton) && mm_mods.testFlag(Qt::NoModifier) && new_segment) { if (bv) qobject_cast(scene()->views().back())->newBranchTrace(this, e->scenePos()); return; } if (new_segment) { new_end = qp; prepareGeometryChange(); } else { if (e->buttons().testFlag(Qt::LeftButton)) { lm_point = selPoint >= 0; if (selPoint >= 0 && selPoint <= pol.size() - 1) pol[selPoint] += lp; if (selSegment >= 0 && selSegment <= segments.size() - 1) { pol[segments[selSegment].first] += lp; pol[segments[selSegment].second] += lp; } moved = true; prepareGeometryChange(); } } lp = qp; } void BlockBusItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * e) { mm_mods = Qt::KeyboardModifiers(); int btncnt = 0; if (e->buttons().testFlag(Qt::LeftButton)) btncnt++; if (e->buttons().testFlag(Qt::RightButton)) btncnt++; if (e->buttons().testFlag(QT_MID_BUTTON)) btncnt++; if (btncnt == 0) mm_cancel = false; if (new_segment) { qobject_cast(scene()->views().back())->newBranchAccept(this); simplify(); updateGeometry(); selPoint = selSegment = -1; emitAction(BlockItemBase::BusAdd); } if (moved) { simplify(false); if (lm_point) { emitAction(BlockItemBase::BusPointMove); } else { reconnect(); emitAction(BlockItemBase::BusSegmentMove); } } moved = new_segment = false; QGraphicsObject::mouseReleaseEvent(e); } void BlockBusItem::paint(QPainter * p, const QStyleOptionGraphicsItem * o, QWidget * w) { ph.setWidthF(pen_width + point_size / 2.); pu.setWidthF(pen_width); pa.setWidthF(pen_width); pr.setWidthF(pen_width); pn.setWidthF(pen_width); if (pol.size() < 2) return; if (selPoint >= 0 || selSegment >= 0) { p->setPen(pa); p->setBrush(ba); } else { p->setPen(pu); p->setBrush(bu); } if (im_bus.isNull()) { QPen _pen(p->pen()); for (int i = 0; i < segments.size(); ++i) { _pen.setWidthF(pen_width); _pen.setCapStyle(Qt::SquareCap); p->setPen(_pen); p->drawLine(pol[segments[i].first], pol[segments[i].second]); if (pointSegmentsCount(segments[i].first) > 2) { _pen.setWidthF(pen_width * 1.8 + 2.); _pen.setCapStyle(square_node ? Qt::SquareCap : Qt::RoundCap); p->setPen(_pen); p->drawPoint(pol[segments[i].first]); } } p->setPen(_pen); } else { QBrush br; br.setTextureImage(im_bus); for (int i = 0; i < segments.size(); ++i) { QPointF sp(pol[segments[i].first]), ep(pol[segments[i].second]); QTransform tf; tf.translate(sp.x(), sp.y()); tf.rotate(-QLineF(sp, ep).angle()); tf.translate(0., -im_bus.height() / 2. * im_bus_scale); tf.scale(im_bus_scale, im_bus_scale); p->save(); p->setTransform(tf, true); p->setPen(Qt::NoPen); p->setBrush(br); p->drawRect(QRectF(0., 0., QLineF(sp, ep).length() / qMax(im_bus_scale, 1E-3), im_bus.height())); p->restore(); } } if (!im_end.isNull()) { for (int i = 0; i < ends_ind.size(); ++i) { QPointF sp = pol[ends_ind[i].first], ep = pol[ends_ind[i].second]; QTransform tf; tf.translate(sp.x(), sp.y()); tf.rotate(-QLineF(sp, ep).angle()); tf.translate(-pen_width, -im_end.height() / 2. * im_end_scale); tf.scale(im_end_scale, im_end_scale); p->save(); p->setTransform(tf, true); p->drawImage(0, 0, im_end); p->restore(); } } if (state_ >= 0) { if (state_ == 0) { pr.setWidthF(pen_width + 1.); p->setPen(pr); } else if (state_ == 1) { pa.setWidthF(pen_width + 1.); p->setPen(pa); } p->setOpacity(0.5); for (int i = 0; i < segments.size(); ++i) { p->drawLine(pol[segments[i].first], pol[segments[i].second]); } p->setOpacity(1.); } if (!im_bus.isNull() && (selPoint >= 0 || selSegment >= 0)) { p->setPen(pa); p->setBrush(ba); for (int i = 0; i < segments.size(); ++i) { p->drawLine(pol[segments[i].first], pol[segments[i].second]); } } if (selPoint >= 0) { p->save(); p->setPen(ph); p->setBrush(bh); p->translate(pol[selPoint]); p->drawEllipse(QPointF(0, 0), point_size, point_size); p->restore(); } if (selSegment >= 0) { p->save(); p->setPen(ph); p->drawLine(pol[segments[selSegment].first], pol[segments[selSegment].second]); p->restore(); } } void BlockBusItem::setPointSize(double s) { point_size = s; update(); } QRectF BlockBusItem::boundingRect() const { QPolygonF p(pol); if (new_segment) p << new_end; return enlargedRect(p.boundingRect(), 0, 0, 10.f); }