/*
 * 此类的封装参考了：博客网址：http://blog.csdn.net/u011417605,并在此基础上进行修改
 * 1.连续输入
 * 2.连续删除
 * 3.任意位置插入
 * 4.自适应大小变化
 * 5.正则匹配，每个值不大于255.设置IP值时，有正则验证是否是IP格式
 * 实现方法：使用一个大的QLineEdit嵌套四个小的QLineEdit，中间的点是使用paintEvent画出来的。操作是使用eventFilter来进行分发实现的
 * 修改：
 * 用QWidget替换原先的__super
 * 修改构造函数中的正则匹配
 * 修改小圆点位置和大小
 * 两个QLineEdit之间的空隙，在绘制小圆点之前，把空气用白色背景填充
 * 修改样式表加边框
 * 当输入类似192时，焦点自动跳转到下一个QLineEdit出
 * 修改text()的输出，使输出由原来的1921680127变为192.168.0.127
 * */

#include "qiplineedit.h"
#include <QRegExpValidator>
#include <QPainter>
#include <QKeyEvent>
#include <QMessageBox>
#include <QDebug>

QIPLineEdit::QIPLineEdit(QWidget *parent)
    : QLineEdit(parent)
{
    QRegExp rx("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
    pHBox = new QHBoxLayout(this);
    pHBox->setSpacing(SPACE);
    pHBox->setContentsMargins(0, 0, 0, 0);
    for (int i = 0; i < 4; i++)
    {
        m_lineEidt[i] = new QLineEdit(this);
        m_lineEidt[i]->setFrame(false);
        m_lineEidt[i]->setMaxLength(3);
        m_lineEidt[i]->setAlignment(Qt::AlignCenter);
        m_lineEidt[i]->installEventFilter(this);
        m_lineEidt[i]->setValidator(new QRegExpValidator(rx, this));
        m_lineEidt[i]->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

        switch (i)
        {
        case 0:
            m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(0, 0, 0);\n"
            "border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n"
            "border-right-color: rgbl(255, 255, 255,0);" "border-radius:0px"));
            break;
        case 1:
            m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n"
            "border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n" "border-left: 0px;\n"
            "border-right-color: rgb(255, 255, 255);" "border-radius:0px"));
            break;
        case 2:
            m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n"
            "border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-right: 0px;\n" "border-left: 0px;\n"
            "border-right-color: rgb(255, 255, 255);" "border-radius:0px"));
            break;
        case 3:
            m_lineEidt[i]->setStyleSheet(QLatin1String( "border:1px solid #536874;\n" "border-left-color: rgb(255, 255, 255);\n"
            "border-top-color: rgb(0, 0, 0);\n" "border-bottom-color: rgb(0, 0, 0);\n" "border-left: 0px;\n"
            "border-right-color: rgb(0, 0, 0);" "border-radius:0px"));
            break;
        default:
            break;
       }
        pHBox->addWidget(m_lineEidt[i]);
    }
    this->setReadOnly(true);
    m_Color=Qt::white;
    connect(m_lineEidt[0],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit1TextChanged(const QString &)));
    connect(m_lineEidt[1],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit2TextChanged(const QString &)));
    connect(m_lineEidt[2],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit3TextChanged(const QString &)));
    connect(m_lineEidt[3],SIGNAL(textChanged(const QString &)),this,SLOT(OnLineEdit4TextChanged(const QString &)));

}

QIPLineEdit::~QIPLineEdit()
{
    m_lineEidt[0]->deleteLater();
    m_lineEidt[1]->deleteLater();
    m_lineEidt[2]->deleteLater();
    m_lineEidt[3]->deleteLater();
    pHBox->deleteLater();
//    delete pHBox;
//    delete m_lineEidt[1];
//    delete m_lineEidt[2];
//    delete m_lineEidt[3];
//    delete m_lineEidt[4];
}
void QIPLineEdit::MySetColor(QColor cr)
{
    m_Color=cr;
}
void QIPLineEdit::OnLineEdit1TextChanged(const QString & strtemp)
{
    if(strtemp.right(1)=="."||strtemp.right(1)=="。")
    {
        m_lineEidt[0]->setText(strtemp.left(strtemp.length()-1));
        m_lineEidt[0 + 1]->setFocus();
        m_lineEidt[0 + 1]->setCursorPosition(0);
    }
}
void QIPLineEdit::OnLineEdit2TextChanged(const QString & strtemp)
{
    if(strtemp.right(1)=="."||strtemp.right(1)=="。")
    {
        m_lineEidt[1]->setText(strtemp.left(strtemp.length()-1));
        m_lineEidt[1 + 1]->setFocus();
        m_lineEidt[1 + 1]->setCursorPosition(0);
    }
}
void QIPLineEdit::OnLineEdit3TextChanged(const QString & strtemp)
{
    if(strtemp.right(1)=="."||strtemp.right(1)=="。")
    {
        m_lineEidt[2]->setText(strtemp.left(strtemp.length()-1));
        m_lineEidt[2 + 1]->setFocus();
        m_lineEidt[2 + 1]->setCursorPosition(0);
    }
}
void QIPLineEdit::OnLineEdit4TextChanged(const QString & strtemp)
{
    if(strtemp.right(1)=="."||strtemp.right(1)=="。")
    {
        m_lineEidt[3]->setText(strtemp.left(strtemp.length()-1));
    }
}
void QIPLineEdit::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);
    QPainter painter(this);
    QBrush brush;

    int width = 0;
    for (int i = 0; i < 3; i++)
    {
        brush.setStyle(Qt::BrushStyle::SolidPattern);

        //将两个lineEdit之间的空隙绘制成白色
        brush.setColor(m_Color);
        painter.setPen(m_Color);
        painter.setBrush(brush);
        painter.drawRect(m_lineEidt[i]->x() + m_lineEidt[i]->width(), m_lineEidt[i]->y(), SPACE, height());

        //绘制空隙的边框
        painter.setPen(Qt::black);
        painter.drawLine(0, 0, this->width(), 0);
        painter.drawLine(0, this->height() - 1, this->width(), this->height() - 1);

        //绘制小黑点
        brush.setColor(Qt::black);
        painter.setPen(QPen());
        painter.setBrush(brush);
        width += m_lineEidt[i]->width() + (i == 0 ? 2 : SPACE);//布局的间隔
        painter.drawEllipse(width, height() / 2 + 4, 1, 1);
    }
}

int QIPLineEdit::getIndex(QLineEdit *pEdit)
{
    int index = -1;
    for (int i = 0; i < 4; i++)
    {
        if (pEdit == m_lineEidt[i])
            index = i;
    }
    return index;
}

bool QIPLineEdit::eventFilter(QObject *obj, QEvent *ev)
{
    if (children().contains(obj) && QEvent::KeyPress == ev->type())
    {
        QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(ev);
        QLineEdit *pEdit = qobject_cast<QLineEdit *>(obj);
        switch (keyEvent->key())
        {
        case Qt::Key_0:
        case Qt::Key_1:
        case Qt::Key_2:
        case Qt::Key_3:
        case Qt::Key_4:
        case Qt::Key_5:
        case Qt::Key_6:
        case Qt::Key_7:
        case Qt::Key_8:
        case Qt::Key_9:
        {
            QString strText = pEdit->text();
            if (pEdit->selectedText().length())
            {
                pEdit->text().replace(pEdit->selectedText(), QChar(keyEvent->key()));
            }
            else if (strText.length() == 2 || (strText.length() < 2 && strText.toInt() * 10 > 255))
            {
                int index = getIndex(pEdit);
                if (index != -1 && index != 3)
                {
                    m_lineEidt[index + 1]->setFocus();
                    m_lineEidt[index + 1]->selectAll();
                }
            }
            else if (strText.length() == 1 && strText.toInt() * 10 < 255)
            {
                if (Qt::Key_0 == keyEvent->key() && strText.toInt())
                {
                    pEdit->setText(strText.insert(pEdit->cursorPosition(), QChar(Qt::Key_0)));
                }
            }
            return QWidget::eventFilter(obj, ev);
        }
            break;
        case Qt::Key_Backspace:
        {
            QString strText = pEdit->text();
            if (!strText.length() || (strText.length() && !pEdit->cursorPosition()))
            {
                int index = getIndex(pEdit);
                if (index != -1 && index != 0)
                {
                    m_lineEidt[index - 1]->setFocus();
                    int length = m_lineEidt[index - 1]->text().length();
                    m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
                }
            }
            return QWidget::eventFilter(obj, ev);
        }
            break;
        case Qt::Key_Left:
        {
            if (!pEdit->cursorPosition())
            {
                int index = getIndex(pEdit);
                if (index != -1 && index != 0)
                {
                    m_lineEidt[index - 1]->setFocus();
                    int length = m_lineEidt[index - 1]->text().length();
                    m_lineEidt[index - 1]->setCursorPosition(length ? length : 0);
                }
            }
            return QWidget::eventFilter(obj, ev);
        }
            break;
        case Qt::Key_Right:
        {
            if (pEdit->cursorPosition() == pEdit->text().length())
            {
                int index = getIndex(pEdit);
                if (index != -1 && index != 3)
                {
                    m_lineEidt[index + 1]->setFocus();
                    m_lineEidt[index + 1]->setCursorPosition(0);
                }
            }
            return QWidget::eventFilter(obj, ev);
        }
            break;
//        case Qt::Key_Period:
//        {
//                        if (pEdit->cursorPosition() == pEdit->text().length())
//                        {
//                            int index = getIndex(pEdit);
//                            if (index != -1 && index != 3)
//                            {
//                                m_lineEidt[index + 1]->setFocus();
//                                m_lineEidt[index + 1]->setCursorPosition(0);
//                                pEdit->setText(pEdit->text().left(pEdit->text().length()-1));
//                            }
//                        }
//            return QWidget::eventFilter(obj, ev);
//        }
            break;
        default:
            break;
        }
    }
    return false;
}

//void QIPLineEdit::keyPressEvent(QKeyEvent *e)
//{
//    int  key=e->key();
//    QMessageBox::warning(this, "Attention", "Your IP Address is Invalid!", QMessageBox::StandardButton::Ok);
//    if(key==Qt::Key_Period )
//    {
//        //  QLineEdit::keyPressEvent(e);    //调用父类键盘事件处理函数
//        QMessageBox::warning(this, "Attention", "Your IP Address is Invalid!", QMessageBox::StandardButton::Ok);

//    }
//    else
//    {
//        QLineEdit::keyPressEvent(e);
//    }
//}
void QIPLineEdit::setText(const QString &strIP)
{
    if (!isTextValid(strIP))
    {
        QMessageBox::warning(this, "Attention", "Your IP Address is Invalid!["+strIP+"]", QMessageBox::StandardButton::Ok);
        return;
    }
    else
    {
        int i = 0;
        QStringList ipList = strIP.split(".");
        foreach (QString ip, ipList)
        {
            m_lineEidt[i]->setText(ip);
            i++;
        }
    }
}

bool QIPLineEdit::isTextValid(const QString &strIP)
{
    QRegExp rx2("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b");
    if (!rx2.exactMatch(strIP))
        return false;
    return true;
}

QString QIPLineEdit::text() const
{
    QString strIP;
    for (int i = 0; i < 4; i++)
    {
        strIP.append(m_lineEidt[i]->text());
        if (i < 3)
        {
            strIP.append(".");
        }
    }
    return strIP;
}
void QIPLineEdit::MyClear()
{
    m_lineEidt[0]->clear();
    m_lineEidt[1]->clear();
    m_lineEidt[2]->clear();
    m_lineEidt[3]->clear();
}
