Click here to Skip to main content
15,885,978 members
Articles / Desktop Programming / QT

A Graphical Documentation System for C/C++ projects

Rate me:
Please Sign up or sign in to vote.
4.93/5 (13 votes)
23 Aug 2012CPOL20 min read 54.4K   1.5K   43  
A concept-tool to create interactive documentations for C/C++ projects
#include "diagramwidget.h"

DiagramWidget::DiagramWidget(QWidget *parent) :
    QWidget(parent)
{
    this->setMinimumHeight(200);
    this->setMinimumWidth(200);
    this->setAutoFillBackground(true);
    m_functionSet = false;

    // Background white
    QPalette pal = this->palette();
    pal.setColor(this->backgroundRole(), Qt::white);
    this->setPalette(pal);
}



void DiagramWidget::drawFunc(QString fun)
{
    if(fun.left(2) != "y=" || !fun.contains(QRegExp("x")))
        return;

    fun = fun.right(fun.length()-2);
    fun = fun.replace(QRegExp(" "), "");

    // find x
    myExp.steps.clear();
    for(int i=0; i<fun.length(); i++)
    {
        QChar c = fun.at(i);
        switch(c.toAscii())
        {
        case 'x':
        {
            operationOrOperand op;
            op.type = X;
            myExp.steps.append(op);
        }break;
        case '+':
        {
            operationOrOperand op;
            op.type = OPERATION;
            op.operation = ADD;
            myExp.steps.append(op);
        }break;
        case '-':
        {
            operationOrOperand op;
            op.type = OPERATION;
            op.operation = SUB;
            myExp.steps.append(op);
        }break;
        case '*':
        {
            operationOrOperand op;
            op.type = OPERATION;
            op.operation = MUL;
            myExp.steps.append(op);
        }break;
        case '/':
        {
            operationOrOperand op;
            op.type = OPERATION;
            op.operation = DIV;
            myExp.steps.append(op);
        }break;
        case '^':
        {
            operationOrOperand op;
            op.type = OPERATION;
            op.operation = POW;
            myExp.steps.append(op);
        }break;
        default:
        {
            // number
            QString number;
            number.append(fun.at(i));
            int newIndex = i+1;
            if(fun.size() > newIndex)
            {
                while(fun.at(newIndex).isDigit())
                {
                    number.append(fun.at(newIndex));
                    newIndex++;
                    i++;
                    if(fun.size() <= newIndex)
                        break;
                }
            }
            operationOrOperand op;
            op.type = OPERAND;
            op.operand = number.toFloat();
            myExp.steps.append(op);
        }break;
        }
    }
    m_functionSet = true;
    repaint();
}

qreal DiagramWidget::applyExp(int index, qreal x)
{
    // Until we find an operand
    operationOrOperand op1 = myExp.steps[index];

    switch(op1.type)
    {
    case X:
    {
        // Other operation
        if(myExp.steps.size() <= index+1)
        {
            // End reached
            return x;
            break;
        }
        operationOrOperand op2 = myExp.steps[index+1];
        switch(op2.operation)
        {
        case ADD:
        {
            // Other operand
            return x + applyExp(index+2, x);

        }break;
        case SUB:
        {
            // Other operand
            return x - applyExp(index+2, x);

        }break;
        case MUL:
        {
            // Other operand
            return x * applyExp(index+2, x);

        }break;
        case DIV:
        {
            // Other operand
            return x / applyExp(index+2, x);

        }break;
        case POW:
        {
            // Other operand
            return pow(x,applyExp(index+2, x));

        }break;
        }
    }break;
    case OPERAND:
    {
        // Other operation
        if(myExp.steps.size() <= index+1)
        {
            // End reached
            return op1.operand;
            break;
        }
        operationOrOperand op2 = myExp.steps[index+1];
        switch(op2.operation)
        {
        case ADD:
        {
            // Other operand
            return op1.operand + applyExp(index+2, x);

        }break;
        case SUB:
        {
            // Other operand
            return op1.operand - applyExp(index+2, x);

        }break;
        case MUL:
        {
            // Other operand
            return op1.operand * applyExp(index+2, x);

        }break;
        case DIV:
        {
            // Other operand
            return op1.operand / applyExp(index+2, x);

        }break;
        case POW:
        {
            // Other operand
            return pow(op1.operand,applyExp(index+2, x));
        }break;
        }
    }break;
    default:
    {
        return 0; // Error
    }break;
    }
}

qreal DiagramWidget::XtoPlanCoords(qreal xcoord)
{
    return xcoord - (this->width() / 2);
}

qreal DiagramWidget::YtoScreenCoords(qreal ycoord)
{
    return this->height() - (ycoord + (this->height() / 2));
}

void DiagramWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing);

    // Border
    painter.setPen(Qt::black);
    painter.drawRect(0,0,this->width(),this->height());

    // Axis
    painter.drawLine(QPointF(this->width()/2, 10), QPointF(this->width()/2, this->height()-10));
    painter.drawLine(QPointF(10, this->height()/2), QPointF(this->width()-10, this->height()/2));

    if(m_functionSet)
    {
        painter.setPen(Qt::red);
        for(int x=0; x<this->width(); x++)
        {
            int xPlan = XtoPlanCoords(x);

            int yPlan = applyExp(0, xPlan);; // Y = X

            int yScreen = YtoScreenCoords(yPlan);

            painter.drawPoint(x, yScreen);
        }
    }
}

DiagramWidget* createWidget()
{
    DiagramWidget *wid = new DiagramWidget();
    return wid;
}


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Italy Italy
I'm a Computer Science Engineer and I've been programming with a large variety of technologies for years. I love writing software with C/C++, CUDA, .NET and playing around with reverse engineering

Comments and Discussions