Beispiel #1
0
void wizImageButton::paintEvent(QPaintEvent* event)
{
    Q_UNUSED(event);

    QStylePainter p(this);
    QStyleOptionButton opt;
    initStyleOption(&opt);

    p.setRenderHint(QPainter::Antialiasing);
    QRect arcRect(opt.rect.topLeft(), QSize(opt.rect.height(), opt.rect.height()));
    QPixmap pxIco(m_currentIcon);
    p.drawPixmap(arcRect, pxIco);
}
Beispiel #2
0
void EarthquakeItem::paint( GeoPainter *painter, ViewportParams *viewport,
                            const QString& renderPos, GeoSceneLayer * layer )
{
    Q_UNUSED( viewport )
    Q_UNUSED( renderPos )
    Q_UNUSED( layer )

    // Save the old painter state.
    painter->save();
    painter->autoMapQuality();

    // Draw the arch into the given rect.
    qreal width = magnitude() * 10;
    qreal height = magnitude() * 10;

    // Draws the circle with circles' center as rectangle's top-left corner.
    QRect arcRect( 0, 0, width, height );
    QColor color = oxygenBrickRed4;
    if ( magnitude() < 5.0 ) {
        color = oxygenSunYellow6;
    } else if ( magnitude() < 6.0 ) {
        color = oxygenHotOrange4;
    }
    painter->setPen( QPen( Qt::NoPen ) );
    QBrush brush( color );
    brush.setColor( color );
    painter->setBrush( brush );
    painter->drawEllipse( arcRect );

    // Draws the seismograph
    if ( m_seismograph.isNull() ) {
        m_seismograph = QPixmap( width, height );
        QSvgRenderer renderer( QString( ":/seismograph.svg" ) );
        m_seismograph.fill( Qt::transparent );
        QPainter pixmapPainter( &m_seismograph );
        renderer.render( &pixmapPainter, QRectF( 0.0, 0.0, width, height ) );
    }
    painter->drawPixmap( 0, 0, m_seismograph );

    // Draws magnitude of the earthquake
    QFontMetrics metrics( s_font );
    QString magnitudeText = QString::number( magnitude() );
    QRect magnitudeRect = metrics.boundingRect( magnitudeText );
    painter->setBrush( QBrush() );
    painter->setPen( QPen() );
    painter->setFont( s_font );
    painter->drawText( QPoint( (arcRect.width() - magnitudeRect.width()) / 2, (arcRect.height() - magnitudeRect.height()) / 2 + metrics.ascent() ), magnitudeText );

    // Restore the old painter state.
    painter->restore();
}
GraphicsPath* GdipCreateRoundRect( RectF& rect, int nRadius )
{
	GraphicsPath roundRect;
	float fDiameter = nRadius * 2.f;
	RectF arcRect( 0.f, 0.f, fDiameter, fDiameter );

	arcRect.X = rect.GetLeft();
	arcRect.Y = rect.GetTop();
	roundRect.AddArc(arcRect, 180, 90);
	arcRect.X = rect.GetRight() - fDiameter;
	roundRect.AddArc(arcRect, 270, 90);
	arcRect.Y = rect.GetBottom() - fDiameter;
	roundRect.AddArc(arcRect, 0, 90);
	arcRect.X = rect.GetLeft();
	roundRect.AddArc(arcRect, 90, 90);
	roundRect.CloseFigure();

	return roundRect.Clone();
}
GraphicsPath* GdipCreateRoundRect( Rect& rect, int nRadius )
{
	GraphicsPath roundRect;
	int nDiameter = nRadius << 1;
	Rect arcRect( 0, 0, nDiameter, nDiameter );

	arcRect.X = rect.GetLeft();
	arcRect.Y = rect.GetTop();
	roundRect.AddArc(arcRect, 180, 90);
	arcRect.X = rect.GetRight() - nDiameter;
	roundRect.AddArc(arcRect, 270, 90);
	arcRect.Y = rect.GetBottom() - nDiameter;
	roundRect.AddArc(arcRect, 0, 90);
	arcRect.X = rect.GetLeft();
	roundRect.AddArc(arcRect, 90, 90);
	roundRect.CloseFigure();

	return roundRect.Clone();
}
Beispiel #5
0
void QPaintWidget::paintEvent(QPaintEvent *) {

    QPainter ppainter(this);
    ppainter.setPen(QPen(Qt::blue, kDrawPenWidth));
    ppainter.setBrush(QBrush(Qt::transparent));

    if (showShapeCenter)
    {
        ppainter.save();
        ppainter.setPen(QPen(Qt::blue, kDrawPenWidth));
        ppainter.drawEllipse(QPointF(paintStates.last().center.x(), paintStates.last().center.y()), 3, 3);

        ppainter.restore();
    }

    if (showShapeCenter && paintStates.last().center != paintStates.last().rotateCenter)
    {
        ppainter.save();
        ppainter.setPen(QPen(Qt::darkCyan, kDrawPenWidth));
        ppainter.drawEllipse(QPointF(paintStates.last().rotateCenter.x(), paintStates.last().rotateCenter.y()), 3, 3);

        ppainter.restore();
    }
    if (showShapeCenter && paintStates.last().center != paintStates.last().scaleCenter)
    {
        ppainter.save();
        ppainter.setPen(QPen(Qt::darkYellow, kDrawPenWidth));
        ppainter.drawEllipse(QPointF(paintStates.last().scaleCenter.x(), paintStates.last().scaleCenter.y()), 3, 3);

        ppainter.restore();
    }

    ppainter.setPen(QPen(Qt::black, kDrawPenWidth));

    ppainter.drawPoints( circle() );
    ppainter.drawPoints( arcRect() );
    ppainter.drawPoints( twoRects() );

}
Beispiel #6
0
void EarthquakeItem::paint( QPainter *painter )
{
    // Save the old painter state.
    painter->save();

    // Draw the arch into the given rect.
    qreal width = magnitude() * 10;
    qreal height = magnitude() * 10;

    // Draws the circle with circles' center as rectangle's top-left corner.
    QRect arcRect( 0, 0, width, height );
    QColor color = Oxygen::brickRed4;
    if ( magnitude() < 5.0 ) {
        color = Oxygen::sunYellow6;
    } else if ( magnitude() < 6.0 ) {
        color = Oxygen::hotOrange4;
    }
    painter->setPen( QPen( Qt::NoPen ) );
    QBrush brush( color );
    brush.setColor( color );
    painter->setBrush( brush );
    painter->drawEllipse( arcRect );

    // Draws the seismograph
    QSvgRenderer renderer( QString( ":/seismograph.svg" ) );
    renderer.render( painter, QRectF( 0.0, 0.0, width, height ) );

    // Draws magnitude of the earthquake
    QFontMetrics metrics( s_font );
    QString magnitudeText = QString::number( magnitude() );
    QRect magnitudeRect = metrics.boundingRect( magnitudeText );
    painter->setBrush( QBrush() );
    painter->setPen( QPen() );
    painter->setFont( s_font );
    painter->drawText( QPoint( (arcRect.width() - magnitudeRect.width()) / 2, (arcRect.height() - magnitudeRect.height()) / 2 + metrics.ascent() ), magnitudeText );

    // Restore the old painter state.
    painter->restore();
}
void QColorTabBar::paintEvent(QPaintEvent *)
{
    //QTabBar::paintEvent(evt);

    QPainter painter;
    painter.begin( this );

    int nDiameter = 3 << 1;
    for( int i=0 ;i<count(); i++ )
    {
        QRect rectTab( tabRect(i).adjusted( 0, 0, -1, 0 ) );

        bool bActive = (m_nActiveIndex == i);
        if( bActive ) rectTab.adjust( 0, 0, 0, 1 );
        bool bHover = (m_nHoverIndex == i);
        bool bNotify = (m_nNotifyIndex == i);

        QPainterPath tabPath;
        QPainterPath tabS;

        QRectF arcRect( 0, 0, nDiameter, nDiameter );

        if (m_bHorz)
        {
            // Horz-Tab
            tabPath.moveTo( rectTab.bottomLeft() );
            tabPath.lineTo( rectTab.left(), rectTab.top()+nDiameter/2);
            tabS.moveTo( rectTab.left(), rectTab.top()+nDiameter/2 );
            arcRect.moveTo( rectTab.topLeft() );
            tabPath.arcTo( arcRect, 180, -90 );
            tabS.arcTo( arcRect, 180, -90 );
            tabPath.lineTo( rectTab.right()-nDiameter/2, rectTab.top() );
            tabS.lineTo( rectTab.right()-nDiameter/2, rectTab.top() );
            arcRect.moveTo( rectTab.right()-nDiameter, rectTab.top() );
            tabPath.arcTo( arcRect, 90, -90 );
            tabS.arcTo( arcRect, 90, -90 );
            tabPath.lineTo( rectTab.bottomRight() );
            //tabS.closeSubpath();
        }
        else
        {
            // Vert-Tab
            tabPath.moveTo( rectTab.right(), rectTab.y() );
            tabPath.lineTo( rectTab.x()+nDiameter, rectTab.y() );
            tabS.moveTo( rectTab.x()+nDiameter, rectTab.y() );
            arcRect.moveTo(rectTab.topLeft());
            tabPath.arcTo( arcRect, -270, 90 );
            tabS.arcTo( arcRect, -270, 90 );
            arcRect.moveTo(rectTab.x(), rectTab.bottom()-nDiameter);
            tabPath.arcTo( arcRect, -180, 90 );
            tabS.arcTo( arcRect, -180, 90 );
            tabPath.moveTo( rectTab.left()+nDiameter, rectTab.bottom() );
            tabPath.lineTo( rectTab.right(), rectTab.bottom() );
            //tabS.closeSubpath();
        }


        QColor colorBody;

        if (bNotify && (m_nBlinkCount % 2 == 0))
        {
            colorBody = QColor(252, 209, 211);
        }
        else
        {
            if (bActive)
                colorBody = QColor(255, 255, 255);
            else
                colorBody = QColor(0xF5, 0xF5, 0xF5);
        }

        painter.fillPath( tabPath, QBrush(colorBody) );

        QColor colorStart = bActive ? g_TabDefaultColor[i] : (bHover ? QColor(255, 190, 60, 200) : QColor(255, 255, 255, 200));
        QColor colorEnd(255, 255, 255, 200);
        QRectF rectTabTip;
        rectTabTip = tabS.boundingRect();
        QLinearGradient gradTip;
        if (m_bHorz)
        {
            gradTip.setStart(rectTabTip.center().x(), rectTabTip.top());
            gradTip.setFinalStop(rectTabTip.center().x(), rectTabTip.bottom());
        }
        else
        {
            gradTip.setStart(rectTabTip.left(), rectTabTip.center().y());
            gradTip.setFinalStop(rectTabTip.right(), rectTabTip.center().y());
        }
        gradTip.setColorAt( 0, colorStart );
        gradTip.setColorAt( 1.f, colorEnd );

        painter.setBrush(Qt::NoBrush);
        painter.setPen( QPen(QColor(160,160,160,100), 2.f) );
        painter.drawPath( tabPath );
        painter.setPen( QPen(QColor(160,160,160)) );
        painter.drawPath( tabPath );
        painter.setPen( Qt::white );
        if( bActive )
            painter.drawLine( rectTab.bottomLeft(), rectTab.bottomRight() );

        painter.fillPath( tabS, QBrush(gradTip) );
        if (bActive || bHover)
        {
            painter.setPen( colorStart );
            painter.drawPath( tabS );
        }

        QRectF rectText;

        float fTextOffset = 0.f;

        if (m_bHorz)
        {
            rectText.setX((float)rectTab.x() + fTextOffset);
            rectText.setY((float)rectTab.y() + nDiameter/2);
            rectText.setWidth((float)rectTab.width() - fTextOffset);
            rectText.setHeight((float)rectTab.height() - nDiameter/2);
        }
        else
        {
            rectText.setX((float)rectTab.x() + nDiameter/2 + fTextOffset);
            rectText.setY((float)rectTab.y());
            rectText.setWidth((float)rectTab.width() - nDiameter/2 - fTextOffset);
            rectText.setHeight((float)rectTab.height());
        }

        QFont fnt( font() );

        fnt.setBold(bActive);

        painter.setFont( fnt );

        int flags = Qt::AlignCenter|Qt::AlignVCenter|Qt::TextSingleLine;
        painter.setPen( QColor(80,80,80) );
        painter.drawText( rectText, flags, tabText(i) );

        if( m_nBlinkIndex == i && m_bBlinkFalg )
        {
            painter.fillPath( tabPath, QColor(240,240,0,128) );
        }
    }

    painter.end();
}
/* draw an angle from the current point to b and then to c,
 * with a rounded corner of the given radius.
 */
void
KeyboardLayoutWidget::roundedCorner (QPainterPath& path,
        QPointF b, QPointF c, double radius)
{
    /* we may have 5 point here
     * a is the current point
     * c is the end point
     * and b is the corner
     * we will have a rounded corner with radious (maybe adjust by a,b,c position)
     *
     * a1 is on a-b, and c1 is on b-c
     */

    QPointF a = path.currentPosition();

    //qDebug() << "current" << a << b << c;

    /* make sure radius is not too large */
    double dist1 = distance (a, b);
    double dist2 = distance (b, c);

    //qDebug() << "dist" << dist1 << dist2 << radius;

    radius = qMin (radius, qMin (dist1, dist2));

    QPointF ba = a - b;
    QPointF bc = c - b;
    QVector2D na(ba);
    QVector2D nc(bc);
    na.normalize();
    nc.normalize();

    qreal cosine = QVector2D::dotProduct(na, nc);
    qreal halfcosine = qSqrt((1 + cosine) / 2);
    qreal halfsine = qSqrt( 1- halfcosine * halfcosine);
    qreal halftan = halfsine / halfcosine;
    QPointF a1 = b + na.toPointF() * (radius / halftan);
    QPointF c1 = b + nc.toPointF() * (radius / halftan);

    QVector2D n = na + nc;
    n.normalize();
    QPointF ctr = b + n.toPointF() * radius / halfsine;
    QRectF arcRect(ctr.x() - radius, ctr.y() - radius, 2 * radius, 2 * radius);

    qreal phiA, phiC;
    //qDebug() << c1 << ctr << a1;
    QVector2D ctra = QVector2D(a1 - ctr);
    QVector2D ctrc = QVector2D(c1 - ctr);
    ctra.normalize();
    ctrc.normalize();
    phiA = angle(ctra);
    phiC = angle(ctrc);

    qreal delta = phiC - phiA;
    while (delta > 0)
        delta -= 360;

    while (delta < -360)
        delta += 360;

    if (delta <- 180)
        delta += 360;

    //qDebug() << arcRect << ctra << ctrc << ctr << "degree" << phiA << phiC;

    path.lineTo(a1);
    path.arcTo(arcRect, phiA, delta);
    path.lineTo(c1);
    path.lineTo(c);
}
void QColorTabWidget::drawTab( QPainter& p, QRect& rectTab, const TabInfo& ti, bool bHover, bool bActive, bool bNotify )
{
    QPainterPath tabPath;
    QPainterPath tabS;

    int nDiameter = 3 << 1;
    QRectF arcRect( 0, 0, nDiameter, nDiameter );

    if (isHorzTab())
    {
        // Horz-Tab
        tabPath.moveTo( rectTab.bottomLeft() );
        tabPath.lineTo( rectTab.left(), rectTab.top()+nDiameter/2);
        tabS.moveTo( rectTab.left(), rectTab.top()+nDiameter/2 );
        arcRect.moveTo( rectTab.topLeft() );
        tabPath.arcTo( arcRect, 180, -90 );
        tabS.arcTo( arcRect, 180, -90 );
        tabPath.lineTo( rectTab.right()-nDiameter/2, rectTab.top() );
        tabS.lineTo( rectTab.right()-nDiameter/2, rectTab.top() );
        arcRect.moveTo( rectTab.right()-nDiameter, rectTab.top() );
        tabPath.arcTo( arcRect, 90, -90 );
        tabS.arcTo( arcRect, 90, -90 );
        tabPath.lineTo( rectTab.bottomRight() );
        tabS.closeSubpath();
        //tabPath.closeSubpath();
    }
    else
    {
        // Vert-Tab
        tabPath.moveTo( rectTab.right(), rectTab.y() );
        tabPath.lineTo( rectTab.x()+nDiameter, rectTab.y() );
        tabS.moveTo( rectTab.x()+nDiameter, rectTab.y() );
        arcRect.moveTo(rectTab.topLeft());
        tabPath.arcTo( arcRect, -270, 90 );
        tabS.arcTo( arcRect, -270, 90 );
        arcRect.moveTo(rectTab.x(), rectTab.bottom()-nDiameter);
        tabPath.arcTo( arcRect, -180, 90 );
        tabS.arcTo( arcRect, -180, 90 );
        tabPath.moveTo( rectTab.left()+nDiameter, rectTab.bottom() );
        tabPath.lineTo( rectTab.right(), rectTab.bottom() );
        tabS.closeSubpath();
        //tabPath.closeSubpath();
    }

    QColor colorBody;

    if (bNotify && (m_nBlinkCount % 2 == 0))
    {
        colorBody = QColor(252, 209, 211);
    }
    else
    {
        if (bActive)
            colorBody = QColor(255, 255, 255);
        else
            colorBody = QColor(0xF5, 0xF5, 0xF5);
    }

    p.fillPath( tabPath, QBrush(colorBody) );

    QColor colorStart = bActive ? ti.clrTab : (bHover ? QColor(255, 190, 60, 200) : QColor(255, 255, 255, 200));
    QColor colorEnd(255, 255, 255, 200);
    QRectF rectTabTip;
    rectTabTip = tabS.boundingRect();
    QLinearGradient gradTip;
    if (!isHorzTab())
    {
        gradTip.setStart(rectTabTip.left(), rectTabTip.center().y());
        gradTip.setFinalStop(rectTabTip.right(), rectTabTip.center().y());
    }
    else
    {
        gradTip.setStart(rectTabTip.center().x(), rectTabTip.top());
        gradTip.setFinalStop(rectTabTip.center().x(), rectTabTip.bottom());
    }
    gradTip.setColorAt( 0, colorStart );
    gradTip.setColorAt( 1.f, colorEnd );

    p.setBrush(Qt::NoBrush);
    p.setPen( QPen(QColor(160,160,160,100), 2.f) );
    p.drawPath( tabPath );
    p.setPen( QPen(QColor(160,160,160)) );
    p.drawPath( tabPath );

    p.fillPath( tabS, QBrush(gradTip) );
    if (bActive || bHover)
    {
        p.setPen( colorStart );
        p.drawPath( tabS );
    }

    QRectF rectText;

    float fTextOffset = ti.pIconImage ? ti.pIconImage->width()+5.f : 0.f;

    if (isHorzTab())
    {
        rectText.setX((float)rectTab.x() + fTextOffset);
        rectText.setY((float)rectTab.y() + nDiameter/2);
        rectText.setWidth((float)rectTab.width() - fTextOffset);
        rectText.setHeight((float)rectTab.height() - nDiameter/2);
    }
    else
    {
        rectText.setX((float)rectTab.x() + nDiameter/2 + fTextOffset);
        rectText.setY((float)rectTab.y());
        rectText.setWidth((float)rectTab.width() - nDiameter/2 - fTextOffset);
        rectText.setHeight((float)rectTab.height());
    }

    m_fntTab.setBold(bActive);

    p.setFont( m_fntTab );

    if (ti.pIconImage)
    {
        int nIW = ti.pIconImage->width();
        int nIH = ti.pIconImage->height();
        p.drawImage( (int)(rectText.x()-fTextOffset), (int)(rectText.y()), *ti.pIconImage, 0, 0, nIW, nIH );
    }

    int flags = Qt::AlignCenter|Qt::AlignVCenter|Qt::TextSingleLine;
    p.setPen( QColor(80,80,80) );
    p.drawText( rectText, flags, ti.strCaption );
}
void ConnectionItem::updateArrowPositions(const QPointF& start, const QPointF& end)
{
    static const qreal ARROW_LENGTH = 2 * ConnectorItem::SIZE;
    const qreal RADIUS = 1.5 * ConnectorItem::SIZE;
    const qreal ARC_RECT_SIZE = 2*RADIUS;
    QRectF arcRect(0, 0, ARC_RECT_SIZE, ARC_RECT_SIZE);
    qreal xDiff = end.x() - start.x();
    qreal yDiff = end.y() - start.y();
    qreal yOffset = 0;
    
    
    if(yDiff <= 0)
        yOffset = yDiff;
    else
        yOffset = 0;
    
    // hide all arrows
    m_startArrow->setVisible(false);
    m_endArrow->setVisible(false);
    m_centerArrow->setVisible(false);
    
    if(xDiff > 0) // the connections points forward
    {
        if(xDiff > 2*RADIUS)
        {
            // start and end are so far from each other that the can
            // be directly connected (without loop)
            if(xDiff > 2*RADIUS + 2*ARROW_LENGTH) 
            {
                m_startArrow->setVisible(true);
                m_startArrow->setPos(start.x() + (xDiff - 2*RADIUS)/4, start.y());
                m_startArrow->setRotation(0);
                
                m_endArrow->setVisible(true);
                m_endArrow->setPos(end.x() - (xDiff - 2*RADIUS)/4, end.y());
                m_endArrow->setRotation(0);
            }
            
            if(fabs(yDiff) > 2*RADIUS + ARROW_LENGTH)
            {
                // start and end point are so far from each other that a
                // center arrow can be drawn
                m_centerArrow->setVisible(true);
                m_centerArrow->setPos(start.x() + xDiff/2, start.y() + yDiff/2);
                
                if(yDiff > 0) // the connection points downwards
                    m_centerArrow->setRotation(90);
                else // the connection points upwards
                    m_centerArrow->setRotation(-90);
            }
        }
        else
        {
            // start and end are so close to each other to each other
            // that the connections must have loop
            if(fabs(yDiff) > ARROW_LENGTH)
            {
                if(yOffset < 0)
                {
                    m_startArrow->setVisible(true);
                    m_startArrow->setPos(start.x() + xDiff/2 + RADIUS, start.y() - RADIUS + yDiff/2);
                    m_startArrow->setRotation(-90);
                }
                else
                {
                    m_endArrow->setVisible(true);
                    m_endArrow->setPos(start.x() + xDiff/2 - RADIUS, start.y() - RADIUS + yDiff/2);
                    m_endArrow->setRotation(90);
                }
            }
        }
    }
    else // the connections points backward
    {
        // the backward section is long enough to display an arrow
        if(fabs(xDiff) > ARROW_LENGTH)
        {
            m_centerArrow->setVisible(true);
            m_centerArrow->setRotation(180);
        }
        
        if(fabs(yDiff) > 4*RADIUS)
        {            
            // start and end are so far from each other that the can
            // be directly with a line between the to operators
            if(fabs(yDiff) > 4*RADIUS + 2*ARROW_LENGTH)
            {
                m_startArrow->setVisible(true);
                m_endArrow->setVisible(true);
                m_startArrow->setPos(start.x() + RADIUS, start.y() + yDiff/4);
                m_endArrow->setPos(end.x() - RADIUS, end.y() - yDiff/4);
                if(yDiff > 0)
                {
                    m_startArrow->setRotation(90);
                    m_endArrow->setRotation(90);
                }
                else
                {
                    m_startArrow->setRotation(-90);
                    m_endArrow->setRotation(-90);
                }
            }
            
            m_centerArrow->setPos(start.x() + xDiff/2, start.y() + yDiff/2);
        }
        else
        {
            // start and end are so close to each other to each other
            // that the connection must run around one of the operators
            m_startArrow->setVisible(true);
            m_endArrow->setVisible(true);
            m_startArrow->setPos(start.x() + RADIUS, start.y() + (yOffset - EXTRA_HEIGHT)/2 - RADIUS);
            m_endArrow->setPos(end.x() - RADIUS, end.y() - RADIUS - ((yDiff - yOffset) + EXTRA_HEIGHT)/2);
            m_startArrow->setRotation(-90);
            m_endArrow->setRotation(90);
            
            m_centerArrow->setPos(start.x() + xDiff/2, start.y() + yOffset - EXTRA_HEIGHT - ARC_RECT_SIZE);
        }
    }
}
QPainterPath ConnectionItem::drawPath(const QPointF& start, const QPointF& end)
{
    const qreal RADIUS = 1.5 * ConnectorItem::SIZE;
    const qreal ARC_RECT_SIZE = 2*RADIUS;
    QRectF arcRect(0, 0, ARC_RECT_SIZE, ARC_RECT_SIZE);
    qreal xDiff = end.x() - start.x();
    qreal yDiff = end.y() - start.y();
    qreal yOffset = 0;
    
    if(yDiff <= 0)
        yOffset = yDiff;
    else
        yOffset = 0;
    
    QPainterPath path;
    
    path.moveTo(start);
    if(xDiff > 0)
    {
        // the connections points forward
        if(xDiff > 2*RADIUS)
        {
            // start and end are so far from each other that the can
            // be directly connected (without loop)
            if(yDiff > 0)
            {
                // the connection points downwards
                if(fabs(yDiff) < 2*RADIUS)
                {
                    // start and end point are so close too each other that
                    // the arcs must be less than 90 degrees
                    qreal angle = computeAngle(RADIUS, yDiff/2);
                    qreal width = computeWidth(yDiff/2, angle);
                    
                    arcRect.moveTo(start.x() + xDiff/2 - width - RADIUS, start.y());
                    path.arcTo(arcRect, 90, -angle);
                    arcRect.moveTo(start.x() + xDiff/2 + width - RADIUS, end.y() - ARC_RECT_SIZE);
                    path.arcTo(arcRect, -90 - angle, angle);
                }
                else
                {
                    // two 90 degree arcs are possible
                    arcRect.moveTo(start.x() + xDiff/2 - ARC_RECT_SIZE, start.y());
                    path.arcTo(arcRect, 90, -90);
                    arcRect.moveTo(start.x() + xDiff/2, end.y() - ARC_RECT_SIZE);
                    path.arcTo(arcRect, 180, 90);
                }
            }
            else
            {
                // the connection points upwards
                if(fabs(yDiff) < 2*RADIUS)
                {
                    // start and end point are so close too each other that
                    // the arcs must be less than 90 degrees
                    qreal angle = computeAngle(RADIUS, yDiff/2);
                    qreal width = computeWidth(yDiff/2, angle);
                    
                    arcRect.moveTo(start.x() + xDiff/2 - width - RADIUS, start.y() - ARC_RECT_SIZE);
                    path.arcTo(arcRect, 270, angle);
                    arcRect.moveTo(start.x() + xDiff/2 + width - RADIUS, end.y());
                    path.arcTo(arcRect, 90 + angle, -angle);
                }
                else
                {
                    // two 90 degree arcs are possible
                    arcRect.moveTo(start.x() + xDiff/2 - ARC_RECT_SIZE, start.y() - ARC_RECT_SIZE);
                    path.arcTo(arcRect, 270, 90);
                    arcRect.moveTo(start.x() + xDiff/2, end.y());
                    path.arcTo(arcRect, 180, -90);
                }
            }
        }
        else
        {
            // start and end are so close to each other to each other
            // that the connections must have loop
            arcRect.moveTo(start.x() + xDiff/2 - RADIUS, start.y() - ARC_RECT_SIZE);
            path.arcTo(arcRect, -90, 90);
            arcRect.moveTo(start.x() + xDiff/2 - RADIUS, start.y() + yOffset - 2*RADIUS);
            path.arcTo(arcRect, 0, 90);
            arcRect.moveTo(start.x() + xDiff/2 - RADIUS, start.y() + yOffset - 2*RADIUS);
            path.arcTo(arcRect, 90, 90);
            arcRect.moveTo(start.x() + xDiff/2 - RADIUS, end.y() - ARC_RECT_SIZE);
            path.arcTo(arcRect, 180, 90);
        }
    }
    else
    {
        // the connections points backward
        if(fabs(yDiff) > 4 * RADIUS)
        {            
            // start and end are so far from each other that the can
            // be directly with a line between the to operators
            if(yDiff > 0)
            {
                // the connection points downwards
                arcRect.moveTo(start.x() - RADIUS, start.y());
                path.arcTo(arcRect, 90, -90);
                arcRect.moveTo(start.x() - RADIUS, start.y() + yDiff/2 - ARC_RECT_SIZE);
                path.arcTo(arcRect, 0, -90);
                arcRect.moveTo(end.x() - RADIUS, start.y() + yDiff/2);
                path.arcTo(arcRect, 90, 90);
                arcRect.moveTo(end.x() - RADIUS, end.y() - ARC_RECT_SIZE);
                path.arcTo(arcRect, 180, 90);
            }
            else
            {
                // the connection points upwards
                arcRect.moveTo(start.x() - RADIUS, start.y() - ARC_RECT_SIZE);
                path.arcTo(arcRect, 270, 90);
                arcRect.moveTo(start.x() - RADIUS, start.y() + yDiff/2);
                path.arcTo(arcRect, 0, 90);
                arcRect.moveTo(end.x() - RADIUS, start.y() + yDiff/2 - ARC_RECT_SIZE);
                path.arcTo(arcRect, 270, -90);
                arcRect.moveTo(end.x() - RADIUS, end.y());
                path.arcTo(arcRect, 180, -90);
            }
        }
        else
        {
            // start and end are so close to each other to each other
            // that the connection must run around one of the operators
            arcRect.moveTo(start.x() - RADIUS, start.y() - ARC_RECT_SIZE);
            path.arcTo(arcRect, -90, 90);
            arcRect.moveTo(start.x() - RADIUS, start.y() - ARC_RECT_SIZE + yOffset - EXTRA_HEIGHT);
            path.arcTo(arcRect, 0, 90);
            arcRect.moveTo(end.x() - RADIUS, start.y() - ARC_RECT_SIZE + yOffset - EXTRA_HEIGHT);
            path.arcTo(arcRect, 90, 90);
            arcRect.moveTo(end.x() - RADIUS, end.y() - ARC_RECT_SIZE);
            path.arcTo(arcRect, 180, 90);
        }
    }
    path.lineTo(end);
    
    return path;
}