/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * Copyright (C) 2024 KylinSoft  Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#include "changeuserpwd.h"

#include "passwdcheckutil.h"

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QKeyEvent>
#include <QDebug>
#include <QMessageBox>

#include <QDBusInterface>
#include <QDBusReply>
#include <QRegularExpressionValidator>
#include <QCoreApplication>

#include <QPainter>
#include <QPainterPath>
#include <QProcess>


#ifdef signals
#undef signals
#endif

#include <glib.h>
#include <unistd.h>

#include "qtdbus/uniauthservice.h"

#include "ukcccommon.h"
using namespace ukcc;

extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);

ChangeUserPwd::ChangeUserPwd(QString n, QWidget *parent) :
    KDialog(parent),
    name(n)
{

    //判断是否是当前用户
    if (QString::compare(name, QString(g_get_user_name())) == 0){
        isCurrentUser = true;
    } else {
        isCurrentUser = false;
    }

    //密码校验状态
    isChecking = false;

    //构造密码校验线程
    thread1ForCheckPwd = new PwdCheckThread(this);

    makeSurePwqualityEnabled();

    initUI();
    setupStatus(name);

    setupConnect();
}

ChangeUserPwd::~ChangeUserPwd()
{
}

void ChangeUserPwd::makeSurePwqualityEnabled()
{
#ifdef ENABLEPQ
    int ret;
    void *auxerror;
    char buf[255];

    settings = pwquality_default_settings();
    if (settings == NULL) {
        enablePwdQuality = false;
        qDebug() << "init pwquality settings failed";
    } else {
        enablePwdQuality = true;
    }

    ret = pwquality_read_config(settings, PWCONF, &auxerror);
    if (ret != 0){
        enablePwdQuality = false;
        qDebug() << "Reading pwquality configuration file failed: " << pwquality_strerror(buf, sizeof(buf), ret, auxerror);
    } else {
        enablePwdQuality = true;
    }

    if (PasswdCheckUtil::getCurrentPamState())
        enablePwdQuality = true;
    else
        enablePwdQuality = false;

#else
    enablePwdQuality = false;
#endif
}

void ChangeUserPwd::initUI()
{
    setWindowTitle(tr("Change password"));
    setWindowIcon("ukui-control-center");

    //当前密码
    currentPwdLabel = new QLabel();
    currentPwdLabel->setFixedSize(100,24);
    setTextDynamicInPwd(currentPwdLabel, tr("Current Pwd"));
    curTipLabel = new QLabel();
    QFont ft;
    ft.setPixelSize(14);
    curTipLabel->setFont(ft);
    curTipLabel->setFixedSize(QSize(322, 24));
    curTipLabel->setStyleSheet("color:red;");
    curTipHorLayout = new QHBoxLayout;
    curTipHorLayout->setContentsMargins(110, 0, 0, 0);
    curTipHorLayout->addStretch();
    curTipHorLayout->addWidget(curTipLabel);
    currentPwdLineEdit = new KPasswordEdit(this);
    currentPwdLineEdit->setFixedSize(QSize(322, 36));
    auto placehoderText = tr("Required");
    currentPwdLineEdit->setPlaceholderText(placehoderText);
    currentPwdLineEdit->setEchoMode(QLineEdit::Password);
    QRegularExpression inputRegExp("^[A-Za-z0-9`~!@#$%^&*()_-+=<>,.\\\/?:;\"'|\{\}\ ]+$");
    QRegularExpressionValidator *inputLimits = new QRegularExpressionValidator(inputRegExp, this);
    currentPwdLineEdit->setValidator(inputLimits);
    currentPwdLineEdit->setTextMargins(0,0,30,0);
    currentPwdLineEdit->setContextMenuPolicy(Qt::NoContextMenu);
    currentPwdLineEdit->installEventFilter(this);
    currentPwdLineEdit->setFocus();

    currentPwdHorLayout = new QHBoxLayout;
    currentPwdHorLayout->setSpacing(8);
    currentPwdHorLayout->setContentsMargins(0, 0, 0, 0);
    currentPwdHorLayout->addWidget(currentPwdLabel);
    currentPwdHorLayout->addWidget(currentPwdLineEdit);

    //新密码
    newPwdLabel = new QLabel();
    newPwdLabel->setFixedSize(100,24);
    setTextDynamicInPwd(newPwdLabel, tr("New Pwd"));
    newTipLabel = new QLabel();
    newTipLabel->setFont(ft);
    newTipLabel->setFixedSize(QSize(322, 24));
    newTipLabel->setStyleSheet("color:red;");
    newTipHorLayout = new QHBoxLayout;
    newTipHorLayout->setContentsMargins(110, 0, 0, 0);
    newTipHorLayout->addStretch();
    newTipHorLayout->addWidget(newTipLabel);
    newPwdLineEdit = new KPasswordEdit(this);
    newPwdLineEdit->setFixedSize(QSize(322, 36));
    newPwdLineEdit->setPlaceholderText(placehoderText);
    newPwdLineEdit->setEchoMode(QLineEdit::Password);
    newPwdLineEdit->setValidator(inputLimits);
    newPwdLineEdit->setTextMargins(0,0,30,0);
    newPwdLineEdit->setContextMenuPolicy(Qt::NoContextMenu);
    newPwdLineEdit->installEventFilter(this);

    newPwdHorLayout = new QHBoxLayout;
    newPwdHorLayout->setSpacing(8);
    newPwdHorLayout->setContentsMargins(0, 0, 0, 0);
    newPwdHorLayout->addWidget(newPwdLabel);
    newPwdHorLayout->addWidget(newPwdLineEdit);

    //确认密码
    surePwdLabel = new QLabel();
    surePwdLabel->setFixedSize(100,24);
    setTextDynamicInPwd(surePwdLabel, tr("Sure Pwd"));

    surePwdLineEdit = new KPasswordEdit(this);
    surePwdLineEdit->setFixedSize(QSize(322, 36));
    auto placehoder = tr("Verification");
    surePwdLineEdit->setPlaceholderText(placehoder);
    surePwdLineEdit->setEchoMode(QLineEdit::Password);
    surePwdLineEdit->setValidator(inputLimits);
    surePwdLineEdit->setTextMargins(0,0,30,0);
    surePwdLineEdit->setContextMenuPolicy(Qt::NoContextMenu);
    surePwdLineEdit->installEventFilter(this);

    surePwdHorLayout = new QHBoxLayout;
    surePwdHorLayout->setSpacing(8);
    surePwdHorLayout->setContentsMargins(0, 0, 0, 0);
    surePwdHorLayout->addWidget(surePwdLabel);
    surePwdHorLayout->addWidget(surePwdLineEdit);

    tipLabel = new QLabel();
    tipLabel->setFont(ft);
    tipLabel->setFixedSize(QSize(322, 30));
    tipLabel->setStyleSheet("color:red;");

    tipHorLayout = new QHBoxLayout;
    tipHorLayout->setSpacing(0);
    tipHorLayout->setContentsMargins(110, 0, 0, 0);
    tipHorLayout->addStretch();
    tipHorLayout->addWidget(tipLabel);

    surePwdWithTipVerLayout = new QVBoxLayout;
    surePwdWithTipVerLayout->setSpacing(8);
    surePwdWithTipVerLayout->setContentsMargins(0, 0, 0, 0);
    surePwdWithTipVerLayout->addLayout(surePwdHorLayout);
    surePwdWithTipVerLayout->addLayout(tipHorLayout);

    // 密码提示
    m_pPasswordPromptLabel = new QLabel();
    m_pPasswordPromptLabel->setFixedSize(100,24);
    setTextDynamicInPwd(m_pPasswordPromptLabel, tr("Password Prompt"));

    m_pPasswordPromptLineedit = new QLineEdit(this);
    m_pPasswordPromptLineedit->setFixedSize(QSize(322, 36));
    m_pPasswordPromptLineedit->setPlaceholderText(tr("Optional(Recommended)"));
    m_pPasswordPromptLineedit->setTextMargins(0,0,30,0);
    m_pPasswordPromptLineedit->setContextMenuPolicy(Qt::NoContextMenu);
    m_pPasswordPromptLineedit->installEventFilter(this);

    QHBoxLayout *pwdPromptHLayout = new QHBoxLayout;
    pwdPromptHLayout->setSpacing(8);
    pwdPromptHLayout->setContentsMargins(0, 0, 0, 0);
    pwdPromptHLayout->addWidget(m_pPasswordPromptLabel);
    pwdPromptHLayout->addWidget(m_pPasswordPromptLineedit);
    m_pPasswordPromptTips = new QLabel();
    m_pPasswordPromptTips->setFont(ft);
    m_pPasswordPromptTips->setFixedSize(QSize(322, 30));
    m_pPasswordPromptTips->setStyleSheet("color:red;");
    QHBoxLayout *passwordPromptTipsHLayout = new QHBoxLayout;
    passwordPromptTipsHLayout->setSpacing(0);
    passwordPromptTipsHLayout->setContentsMargins(110, 0, 0, 0);
    passwordPromptTipsHLayout->addStretch();
    passwordPromptTipsHLayout->addWidget(m_pPasswordPromptTips);

    QVBoxLayout *pwdPromptWithTipVerLayout = new QVBoxLayout;
    pwdPromptWithTipVerLayout->setSpacing(8);
    pwdPromptWithTipVerLayout->setContentsMargins(0, 0, 0, 0);
    pwdPromptWithTipVerLayout->addLayout(pwdPromptHLayout);
    pwdPromptWithTipVerLayout->addLayout(passwordPromptTipsHLayout);


    //中部输入区域
    contentVerLayout = new QVBoxLayout;
    contentVerLayout->setSpacing(0);
    contentVerLayout->setContentsMargins(24, 0, 35, 0);
    if (isCurrentUser) {
        contentVerLayout->addLayout(currentPwdHorLayout);
        contentVerLayout->addLayout(curTipHorLayout);
        setFixedSize(QSize(480, 360));
    } else {
        currentPwdLabel->setVisible(false);
        currentPwdLineEdit->setVisible(false);
        curTipLabel->setVisible(false);
        setFixedSize(480, 310);
    }
    contentVerLayout->addLayout(newPwdHorLayout);
    contentVerLayout->addLayout(newTipHorLayout);
    contentVerLayout->addLayout(surePwdWithTipVerLayout);
    contentVerLayout->addLayout(pwdPromptWithTipVerLayout);

    //底部“取消”、“确定”按钮
    cancelBtn = new QPushButton();
    cancelBtn->setMinimumWidth(96);
    cancelBtn->setText(tr("Cancel"));
    cancelBtn->setFocusPolicy(Qt::FocusPolicy::NoFocus);
    cancelBtn->setProperty("useButtonPalette", true);
    confirmBtn = new QPushButton();
    confirmBtn->setMinimumWidth(96);
    confirmBtn->setText(tr("Confirm"));
    confirmBtn->setFocusPolicy(Qt::FocusPolicy::NoFocus);
    confirmBtn->setProperty("isImportant", true);

    bottomBtnsHorLayout = new QHBoxLayout;
    bottomBtnsHorLayout->setSpacing(16);
    bottomBtnsHorLayout->setContentsMargins(24, 0, 24, 0);
    bottomBtnsHorLayout->addStretch();
    bottomBtnsHorLayout->addWidget(cancelBtn);
    bottomBtnsHorLayout->addWidget(confirmBtn);

    mainVerLayout = new QVBoxLayout;
    mainVerLayout->setContentsMargins(0, 10, 0, 24);
    mainVerLayout->addLayout(contentVerLayout);
    mainVerLayout->addStretch();
    mainVerLayout->addLayout(bottomBtnsHorLayout);

    mainWidget()->setLayout(mainVerLayout);
}

void ChangeUserPwd::setupConnect()
{
    //通用的connect

    connect(cancelBtn, &QPushButton::clicked, this, [=]{
        close();
    });

    connect(newPwdLineEdit, &QLineEdit::textEdited, [=]{
        checkPwdLegality();

        passwordPromptChangedSlot();

        refreshConfirmBtnStatus();
    });

    connect(surePwdLineEdit, &QLineEdit::textEdited, [=](QString txt){
        if (!txt.isEmpty() && txt != newPwdLineEdit->text()){
            surePwdTip = tr("Inconsistency with pwd");
        } else {
            surePwdTip = "";
        }

        updateTipLableInfo(tipLabel,surePwdTip);

        refreshConfirmBtnStatus();
    });

    connect(m_pPasswordPromptLineedit, &QLineEdit::textChanged, this, &ChangeUserPwd::passwordPromptChangedSlot);

    //需要区分的connect
    if (isCurrentUser) {
        connect(thread1ForCheckPwd, &PwdCheckThread::complete, this, &ChangeUserPwd::checkPwdFinishedSlot);

        connect(currentPwdLineEdit, &QLineEdit::textEdited, [=](QString txt){
            if (!txt.isEmpty()){
                curPwdTip = "";
                updateTipLableInfo(curTipLabel, curPwdTip);

                //再次校验新密码，需要保证"与旧密码相同"等条件生效
                checkPwdLegality();

            }

            refreshConfirmBtnStatus();
        });

        connect(confirmBtn, &QPushButton::clicked, [=]{
            //密码校验失败有几秒延时，防止用户重复点击确定按钮
            if (isChecking)
                return;

            thread1ForCheckPwd->setArgs(name, currentPwdLineEdit->text());
            thread1ForCheckPwd->start();

            //开始当前密码校验
            isChecking = true;

            if(m_timer == nullptr)
            {
                m_timer = new QTimer(this);
                m_timer->setInterval(150);
                connect(m_timer, &QTimer::timeout, this, &ChangeUserPwd::updatePixmap);
                m_waitingPixmap = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(24, 24);
                confirmBtn->setIcon(QIcon(m_waitingPixmap));
                confirmBtn->setText(tr(""));
                m_timer->start();
            } else {
                confirmBtn->setIconSize(QSize(24,24));
                confirmBtn->setText(tr(""));
                m_timer->start();
            }
        });
    } else {
        connect(confirmBtn, &QPushButton::clicked, this, [=]{
            //修改其他用户密码
            emit changeOtherUserPwd(newPwdLineEdit->text());

            // 绑定密码提示需要用户id
            if (m_pPasswordPromptTips->text().isEmpty()) {
                emit changeOtherUserPrompt(m_pPasswordPromptLineedit->text());
            }

            this->accept();
        });
    }

}

void ChangeUserPwd::checkPwdFinishedSlot(QString re)
{
    curPwdTip = re;

    //返回值为空，密码校验成功
    if (re.isEmpty()) {
        if (newPwdLineEdit->text().compare(currentPwdLineEdit->text(), Qt::CaseSensitive) == 0 && !newPwdLineEdit->text().isEmpty()) {
            newPwdTip = tr("Same with old pwd");
            updateTipLableInfo(newTipLabel, newPwdTip);
            newPwdLineEdit->setFocus();
            confirmBtn->setIconSize(QSize(0,0));
            confirmBtn->setText(tr("Confirm"));
            m_timer->stop();
            refreshConfirmBtnStatus();

            //密码校验完成
            isChecking = false;
        } else {
            //修改密码
            QString currentPwd = currentPwdLineEdit->text();
            int ci = 0;
            for (ci = 0; ci < currentPwd.count(); ci++){
                if (!(int(currentPwd.at(ci).toLatin1() >= 48 && int(currentPwd.at(ci).toLatin1()) <= 57) ||
                    int(currentPwd.at(ci).toLatin1() >= 65 && int(currentPwd.at(ci).toLatin1()) <= 90) ||
                    int(currentPwd.at(ci).toLatin1() >= 97 && int(currentPwd.at(ci).toLatin1()) <= 122))){

                        currentPwd = currentPwd.insert(ci, QString("\\"));
                        ci++;
                }
            }
            QString newPwd = newPwdLineEdit->text();
            int i = 0;
            for (i = 0; i < newPwd.count(); i++){
                if (!(int(newPwd.at(i).toLatin1() >= 48 && int(newPwd.at(i).toLatin1()) <= 57) ||
                    int(newPwd.at(i).toLatin1() >= 65 && int(newPwd.at(i).toLatin1()) <= 90) ||
                    int(newPwd.at(i).toLatin1() >= 97 && int(newPwd.at(i).toLatin1()) <= 122))){

                        newPwd = newPwd.insert(i, QString("\\"));
                        i++;
                }
            }

            char * cmd = g_strdup_printf("/usr/bin/changeuserpwd %s %s", currentPwd.toLatin1().data(), newPwd.toLatin1().data());

            FILE * stream;
            QString result;
            char output[256];

            if ((stream = popen(cmd, "r")) != NULL){

                while(fgets(output, 256, stream) != NULL){
                    result = QString(output).simplified();
                }
                pclose(stream);
            }

            // 绑定密码提示需要用户id
            if (m_pPasswordPromptTips->text().isEmpty()) {
                UniAuthService *uniauthBackendDbus = new UniAuthService();
                uniauthBackendDbus->deleteLater();
                int ret = uniauthBackendDbus->SetUserPasswordHint(getuid(), m_pPasswordPromptLineedit->text());
                qDebug() << "reply of SetUserPasswordHint in changeUserPwd = " << ret;
            }

            this->accept();

            if (UkccCommon::isDomainUser(g_get_user_name())) {
                QString primaryText;
                primaryText = result.simplified().isEmpty() ? tr("Pwd Changed Succes") : output;
                qDebug() << "output of changeUserpwd = " << result;
                QMessageBox::warning(NULL, "", primaryText, QMessageBox::Yes);
            }
        }
    } else {
        if (re.contains("Failed")){
            curPwdTip = tr("Authentication failed, input authtok again!");
        }

        updateTipLableInfo(curTipLabel,curPwdTip);

        //重置当前密码输入框
        currentPwdLineEdit->setText("");
        currentPwdLineEdit->setFocus();

        confirmBtn->setIconSize(QSize(0,0));
        confirmBtn->setText(tr("Confirm"));
        m_timer->stop();
        refreshConfirmBtnStatus();

        //密码校验完成
        isChecking = false;
    }
}

void ChangeUserPwd::passwordPromptChangedSlot()
{
   if (m_pPasswordPromptLineedit->text().contains(newPwdLineEdit->text())) {
       updateTipLableInfo(m_pPasswordPromptTips, tr("Your password cannot be included in the password prompt."));
   } else {
       updateTipLableInfo(m_pPasswordPromptTips, "");
   }

   refreshConfirmBtnStatus();
}

void ChangeUserPwd::updatePixmap()
{
    QTransform matrix;
    matrix.rotate(90.0);
    m_waitingPixmap = m_waitingPixmap.transformed(matrix, Qt::FastTransformation);
    confirmBtn->setIcon(m_waitingPixmap);
}

void ChangeUserPwd::setupStatus(QString n)
{

    curPwdTip = QString();
    newPwdTip = QString();
    surePwdTip = QString();

    //初始化确定按钮状态
    refreshConfirmBtnStatus();
}

void ChangeUserPwd::updateTipLableInfo(QLabel *Label,QString info){

    if (setTextDynamicInPwd(Label, info)){
        Label->setToolTip(info);
    } else {
        Label->setToolTip("");
    }
}

void ChangeUserPwd::refreshCloseBtnStatus(){
    if (isChecking){
//        closeBtn->setEnabled(false);
        cancelBtn->setEnabled(false);
    } else {
//        closeBtn->setEnabled(true);
        cancelBtn->setEnabled(true);
    }
}

void ChangeUserPwd::refreshConfirmBtnStatus()
{
    if (getuid() && isCurrentUser) {
        if (!tipLabel->text().isEmpty() ||
                currentPwdLineEdit->text().isEmpty() || currentPwdLineEdit->text() == tr("Current Pwd") ||
                newPwdLineEdit->text().isEmpty() || newPwdLineEdit->text() == tr("New Pwd") ||
                surePwdLineEdit->text().isEmpty() || surePwdLineEdit->text() == tr("Sure Pwd") ||
                !curPwdTip.isEmpty() || !newPwdTip.isEmpty() || !surePwdTip.isEmpty()
                || !m_pPasswordPromptTips->text().isEmpty()) {
             confirmBtn->setEnabled(false);
        } else {
            confirmBtn->setEnabled(true);
        }
    } else {
        if (!tipLabel->text().isEmpty() ||
                newPwdLineEdit->text().isEmpty() || newPwdLineEdit->text() == tr("New Pwd") ||
                surePwdLineEdit->text().isEmpty() || surePwdLineEdit->text() == tr("Sure Pwd") ||
                !newPwdTip.isEmpty() || !surePwdTip.isEmpty()
                || !m_pPasswordPromptTips->text().isEmpty()) {
            confirmBtn->setEnabled(false);
        } else {
            confirmBtn->setEnabled(true);
        }
    }
}

bool ChangeUserPwd::isContainLegitimacyChar(QString word)
{
    foreach (QChar ch, word){
        if (int(ch.toLatin1() <= 0 || int(ch.toLatin1()) > 127)){
            return false;
        }
    }
    return true;
}

void ChangeUserPwd::checkPwdLegality()
{
    //判断用户是否输入了非法字符
    if (!isContainLegitimacyChar(newPwdLineEdit->text())){
        newPwdTip = tr("Contains illegal characters!");
    } else {
        if (enablePwdQuality){

#ifdef ENABLEPQ
            void * auxerror;
            int ret;
            const char * msg;
            char buf[256];

            QByteArray ba = newPwdLineEdit->text().toLatin1();
            QByteArray ba1 = currentPwdLineEdit->text().toLatin1();

            if (isCurrentUser){
               ret = pwquality_check(settings, ba.data(), ba1.data(), name.toLatin1().data(), &auxerror);
            } else {
               ret = pwquality_check(settings, ba.data(), NULL, name.toLatin1().data(), &auxerror);
            }

            if (ret == PWQ_ERROR_SAME_PASSWORD) {
                ret = pwquality_check(settings, ba.data(), NULL, name.toLatin1().data(), &auxerror);
            }
            if (ret < 0 && newPwdLineEdit->text().length() > 0){
                msg = pwquality_strerror(buf, sizeof(buf), ret, auxerror);
                newPwdTip = QString(msg);
            } else {
                newPwdTip = "";
            }
#endif

        } else {
            //系统未开启pwdquality模块
            newPwdTip = "";
        }
    }

    //防止先输入确认密码，再输入密码后tipLabel无法刷新
    if (!surePwdLineEdit->text().isEmpty()){
        if (QString::compare(newPwdLineEdit->text(), surePwdLineEdit->text()) == 0){
            surePwdTip = "";
        } else {
            surePwdTip = tr("Inconsistency with pwd");
        }
    }

    //设置新密码的提示
    if (!newPwdLineEdit->text().isEmpty() || newPwdLineEdit->hasFocus()) {
        updateTipLableInfo(newTipLabel,newPwdTip);
    }

    updateTipLableInfo(tipLabel,surePwdTip);

    updateTipLableInfo(curTipLabel,curPwdTip);

}

bool ChangeUserPwd::setTextDynamicInPwd(QLabel *label, QString string)
{
    bool isOverLength = false;
    QFontMetrics fontMetrics(label->font());
    int fontSize = fontMetrics.horizontalAdvance(string);

    QString str = string;
    int pSize = label->width();
    if (fontSize > pSize) {
        str = fontMetrics.elidedText(string, Qt::ElideRight, pSize);
        isOverLength = true;
        label->setToolTip(string);
    } else {
        label->setToolTip("");
    }
    label->setText(str);
    return isOverLength;

}

void ChangeUserPwd::keyPressEvent(QKeyEvent * event){
    switch (event->key())
    {
    case Qt::Key_Enter:
        if (confirmBtn->isEnabled())
            confirmBtn->clicked();
        break;
    case Qt::Key_Return:
        if (confirmBtn->isEnabled())
            confirmBtn->clicked();
        break;
    default:
        QDialog::keyPressEvent(event);
    }
}

//事件过滤如下
//当接收到这些事件时，需要被过滤掉，所以返回true
bool ChangeUserPwd::eventFilter(QObject *target, QEvent *event)
{
    if (target == currentPwdLineEdit || target == newPwdLineEdit || target == surePwdLineEdit) {
        if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);

            if(keyEvent->matches(QKeySequence::Copy) || keyEvent->matches(QKeySequence::Cut))
            {
                qDebug() <<"Copy || Cut";
                return true;
            }
        }
    }
    if (event->type() == QEvent::FocusOut) {
        if (target == currentPwdLineEdit) {
            if (currentPwdLineEdit->text().isEmpty()) {
                curPwdTip = tr("current pwd cannot be empty!");
                updateTipLableInfo(curTipLabel, curPwdTip);
            }
        } else if (target == newPwdLineEdit) {
            if (newPwdLineEdit->text().isEmpty()) {
                newPwdTip = tr("new pwd cannot be empty!");
                updateTipLableInfo(newTipLabel, newPwdTip);
            }
        } else if (target == surePwdLineEdit) {
            if (surePwdLineEdit->text().isEmpty()) {
                surePwdTip = tr("sure pwd cannot be empty!");
                updateTipLableInfo(tipLabel, surePwdTip);
            }
        }
    }

    return KDialog::eventFilter(target, event);
    //继续传递该事件到被观察者，由其本身调用相应的事件。
}

