/*
 * Copyright (C) 2018 Tianjin KYLIN Information Technology 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 3, 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, see <http://www.gnu.org/licenses/>.
 *
**/

#include "lockwidget.h"

#include "powermanager.h"
#include "ui_lockwidget.h"
#include <QDir>
#include <QDateTime>
#include <QTimer>
#include <QDebug>
#include <QPainterPath>
#include <QtConcurrent/QtConcurrentRun>
#include <QScrollArea>
#include <QScrollBar>
#include <QMenu>
#include <QWidgetAction>
#include <imageutil.h>
#include <QtX11Extras/QX11Info>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <QGSettings>
#include "authdialog.h"
#include "virtualkeyboard.h"
#include "users.h"
#include "displaymanager.h"
#include "config.h"
#include "commonfunc.h"
#include "hoverwidget.h"
#include "kylinnm.h"

#include <QtX11Extras/QX11Info>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>

#define TIME_TYPE_SCHEMA "org.ukui.control-center.panel.plugins"
#define CONFIG_FILE "/etc/lightdm/ukui-greeter.conf"
float scale;
LockWidget::LockWidget(QWidget *parent)
    : QWidget(parent),
      ui(new Ui::LockWidget),
      usersMenu(nullptr),
      scrollArea(nullptr),
      users(new Users(this)),
      displayManager(new DisplayManager(this)),
      timeType(24),
      m_kylinNM(nullptr)
{
    scale = 1.0;
    ui->setupUi(this);
   // m_kylinNM->installEventFilter(this);

    UserItem user = users->getUserByName(getenv("USER"));
    authDialog = new AuthDialog(user, this);
    authDialog->installEventFilter(this);
    connect(authDialog, &AuthDialog::authenticateCompete,
            this, &LockWidget::closed);
    connect(authDialog,&AuthDialog::clickPassword,
            this,&LockWidget::hideNetManager);
//    connect(this, &LockWidget::capsLockChanged,
//            authDialog, &AuthDialog::onCapsLockChanged);

//    connect(m_kylinNM, &KylinNM::onConnectChanged, this,[=](){
//        updateNetIcon(m_kylinNM->getConnectStatus());
//    });

    if(QX11Info::isPlatformX11()){
        xEventMonitor = new XEventMonitor(this);
        connect(xEventMonitor, SIGNAL(keyPress(const QString &)), this,
                SLOT(onGlobalKeyPress(const QString &)));
        connect(xEventMonitor, SIGNAL(keyRelease(const QString &)), this,
                SLOT(onGlobalkeyRelease(const QString &)));
        xEventMonitor->start();
    }

    this->installEventFilter(this);
    initUI();

    if(users->getUsers().count() < 2){
        ui->btnSwitchUser->hide();
    }
}

LockWidget::~LockWidget()
{
    delete ui;
}

void LockWidget::closeEvent(QCloseEvent *event)
{
    qDebug() << "LockWidget::closeEvent";
    authDialog->close();
    return QWidget::closeEvent(event);
}

bool LockWidget::eventFilter(QObject *obj, QEvent *event)
{
    if (obj == m_kylinNM)
        return true;

    if(event->type() == 2){
        if(obj == ui->btnPowerManager || obj == ui->btnSwitchUser || obj == ui->btnNetworkManager)
            return false;

        if(scrollArea && scrollArea->isVisible()){
            scrollArea->hide();
	}
 	if(powermanager && powermanager->isVisible()){
        	authDialog->setFocus();
        	authDialog->show();
        	powermanager->hide();
        }
        if(m_kylinNM && m_kylinNM->isVisible()){
            m_kylinNM->hide();
        }
    }

    if (obj == scrollContents ){
        if (event->type() == 76 ) {
            usersMenu->show();
            //qDebug()<<"````````````````````````````````````````````"<<event->type();
        }
    }

    if(event->type() == QEvent::WindowActivate){
        if(!isNetFinished){
	    isNetFinished = true;
            QTimer::singleShot(2000, this, [=](){
	        m_kylinNM = new KylinNM(this);
                m_kylinNM->installEventFilter(this);
		connect(m_kylinNM, &KylinNM::onConnectChanged, this,[=](){
                    updateNetIcon(m_kylinNM->getConnectStatus());
                });
		m_kylinNM->hide();
                QtConcurrent::run([=](){
                    updateNetIcon(getNetStatus());
    		}); 
	    });
        }
    }

    return false;
}

void LockWidget::onGlobalKeyPress(const QString &key)
{
}

void LockWidget::onGlobalkeyRelease(const QString &key)
{
    if (key == "Escape") {

    } else if (key == "Up" || key == "Down" || key == "Return" || key == "KP_Enter") {
        qDebug()<<"  key = "<<key;
        if(scrollArea && scrollArea->isVisible())
            keyBdRelease(key);
    }
}

void LockWidget::keyBdRelease(QString key)
{
    //usersMenu->setFocus();
    QString focus = "focus";
    QString normal = "normal";
    if(key == "Up"){
//        if(nowAt == -1){
//            nowAt = 0;
//            setButtonStyle(focus);
//        }
        for(int i = 0; i < list.count(); i++){
            if(nowAt == i){
                if(i == 0)
                    return ;
                list.at(i)->setStyleSheet("HoverWidget{background-color:transparent;}"
                                                      "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
                list.at(i-1)->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}"
                                          "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
                nowAt = i-1;

                /*else if(i == 0){
                    qDebug()<<"enheng???111"<<list.count();
                    list.last()->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}"
                                              "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
                    nowAt = list.count() -1;
                }*/
            }
        }
    } else if(key == "Down") {
        for(int i = list.count(); i >= 0; i--){
            if(nowAt == i){
                if(i == list.count() - 1)
                    return ;
                list.at(i)->setStyleSheet("HoverWidget{background-color:transparent;}"
                                                      "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
                list.at(i+1)->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}"
                                          "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
                nowAt = i+1;
                /*else if(i == list.count() - 1){
                    qDebug()<<"enheng???111"<<list.count();
                    list.first()->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}"
                                              "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
                    nowAt = 0;
                }*/
            }
        }
    } else if(key == "Return" || key == "KP_Enter"){
        if(authDialog)
        {
            authDialog->stopAuth();
        }
        if(list.at(nowAt)->objectName() == "Guest")
        {
            displayManager->switchToGuest();
        }
        else if(list.at(nowAt)->objectName() == "SwitchUser")
        {
            displayManager->switchToGreeter();
        }
        else
        {
            displayManager->switchToUser(list.at(nowAt)->objectName());
        }
    }
}

void LockWidget::startAuth()
{
    if(authDialog)
    {
        authDialog->startAuth();
    }
}

void LockWidget::stopAuth()
{
    if(authDialog)
    {
        authDialog->stopAuth();
    }
}

void LockWidget::setX11Focus()
{
    if(authDialog){
    	authDialog->setX11Focus();
    }
}

void LockWidget::initUI()
{
    setFocusProxy(authDialog);

    if(QGSettings::isSchemaInstalled(TIME_TYPE_SCHEMA)){
    	QGSettings *time_type = new QGSettings(TIME_TYPE_SCHEMA);
        QStringList keys = time_type->keys();
    	if (keys.contains("hoursystem")) {
        	timeType = time_type->get("hoursystem").toInt();
        }
        if (keys.contains("date")) {
            dateType = time_type->get("date").toString();
        }
    }

    //显示系统时间
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [&]{
        if(timeType == 12)
            ui->lblTime->setText(QDateTime::currentDateTime().toString("A hh:mm"));
        else
            ui->lblTime->setText(QDateTime::currentDateTime().toString("hh:mm"));

        if(dateType == "cn")
            ui->lblDate->setText(QDate::currentDate().toString("yyyy/MM/dd ddd"));
        else
            ui->lblDate->setText(QDate::currentDate().toString("yyyy-MM-dd ddd"));
    });

    if(timeType == 12)
    	ui->lblTime->setText(QDateTime::currentDateTime().toString("A hh:mm"));
    else
        ui->lblTime->setText(QDateTime::currentDateTime().toString("hh:mm"));

    ui->lblTime->setStyleSheet("QLabel{color:white; font-size: 36px;}");
    ui->lblTime->setAlignment(Qt::AlignCenter);
    ui->lblTime->adjustSize();
    timer->start(1000);

//    QString date = QDate::currentDate().toString("yyyy/MM/dd ddd");
//    qDebug() << "current date: " << date;
//    ui->lblDate->setText(date);
    if(dateType == "cn")
        ui->lblDate->setText(QDate::currentDate().toString("yyyy/MM/dd ddd"));
    else
        ui->lblDate->setText(QDate::currentDate().toString("yyyy-MM-dd ddd"));

    ui->lblDate->setStyleSheet("QLabel{color:white; font-size: 18px;}");
    ui->lblDate->setAlignment(Qt::AlignCenter);
    ui->lblDate->adjustSize();
    ui->widgetTime->adjustSize();

    //电源管理
    ui->btnPowerManager->setIcon(QIcon(":/image/assets/powerManager.png"));
    ui->btnPowerManager->setFixedSize(48,48);
    ui->btnPowerManager->setIconSize(QSize(24,24));
    ui->btnPowerManager->setFocusPolicy(Qt::NoFocus);
    ui->btnPowerManager->installEventFilter(this);

    connect(ui->btnPowerManager,&QPushButton::clicked
        ,this,&LockWidget::showPowerManager);


    QtConcurrent::run([=](){
        updateNetIcon(getNetStatus());
    });

    ui->btnNetworkManager->setFixedSize(48,48);
    ui->btnNetworkManager->setIconSize(QSize(24,24));
    ui->btnNetworkManager->setFocusPolicy(Qt::NoFocus);
//    ui->btnNetworkManager->setStyleSheet("QPushButton:Hover{border-radius:24px;background-color:rgba(255, 255, 255, 0.15);}"
//                                       "QPushButton:Pressed{border-radius:24px;background-color:rgba(255, 255, 255, 0.05);}");
    ui->btnNetworkManager->installEventFilter(this);

    connect(ui->btnNetworkManager,&QPushButton::clicked
            ,this,&LockWidget::showNetManager);

    if(QX11Info::isPlatformX11()){
        //虚拟键盘
        ui->btnKeyboard->setIcon(QIcon(":/image/assets/keyboard.svg"));
        ui->btnKeyboard->setFixedSize(48, 48);
        ui->btnKeyboard->setIconSize(QSize(24, 24));
        ui->btnKeyboard->setFocusPolicy(Qt::NoFocus);
        ui->btnKeyboard->installEventFilter(this);
        ui->btnKeyboard->hide();

        connect(ui->btnKeyboard, &QPushButton::clicked,
                this, [&]{
            qDebug() << vKeyboard->isHidden();
            vKeyboard->setVisible(vKeyboard->isHidden());
        });


        connect(ui->btnKeyboard, &QPushButton::clicked,
                this, &LockWidget::showVirtualKeyboard);
    }

    //用户切换
    if(displayManager->canSwitch())
    {
        //initUserMenu();
        ui->btnSwitchUser->setIcon(QIcon(":/image/assets/switchUser.png"));
        ui->btnSwitchUser->setIconSize(QSize(24, 24));
        ui->btnSwitchUser->setFixedSize(48, 48);
        ui->btnSwitchUser->setFocusPolicy(Qt::NoFocus);
        ui->btnSwitchUser->raise();

        connect(ui->btnSwitchUser, &QPushButton::clicked,
                this, [&]{
            if(!usersMenu){
                initUserMenu();
            }

            if(scrollArea && scrollArea->isVisible()){
                scrollArea->hide();
            }
            else{
                scrollArea->show();
                if(m_kylinNM && m_kylinNM->isVisible())
                    m_kylinNM->hide();
                    scrollArea->setFocus();
            }
        });
    }

}

void LockWidget::showVirtualKeyboard()
{
    if(!vKeyboard){
        vKeyboard = new VirtualKeyboard(this);
        vKeyboard->hide();

        connect(vKeyboard, &VirtualKeyboard::aboutToClose,
            vKeyboard, &VirtualKeyboard::hide);
    }

    vKeyboard->setVisible(vKeyboard->isHidden());
    if(!vKeyboard->isHidden()){
    	vKeyboard->raise();
    }
    setVirkeyboardPos();
}

void LockWidget::showPowerManager()
{
    if(!powermanager){
        powermanager = new PowerManager(this);
        sureWidget = new SureWindow(this);
        powermanager->hide();
        connect(powermanager,SIGNAL(lock())
                ,this,SLOT(showPowerManager()));
        connect(powermanager,SIGNAL(switchToUser())
                ,this,SLOT(switchToGreeter()));
        connect(powermanager, SIGNAL(mulUsersLogined(int)),
                this,SLOT(switchToSureDialog(int)));
        sureWidget->adjustSize();
        sureWidget->move((width()-sureWidget->geometry().width())/2, (height()-sureWidget->geometry().height())/2);
        sureWidget->hide();
        connect(sureWidget, SIGNAL(cantelButtonclicked()),
            this, SLOT(hideSureDialog()));
        connect(sureWidget, SIGNAL(confirmButtonclicked()),
            this, SLOT(confirmClicked()));
    }

    if(m_kylinNM && m_kylinNM->isVisible())
        m_kylinNM->hide();
    if(scrollArea && scrollArea->isVisible())
        scrollArea->hide();
    if(sureWidget && sureWidget->isVisible())
        sureWidget->hide();
    if(powermanager->isVisible()){
        authDialog->setFocus();
        authDialog->show();
        powermanager->hide();
    }
    else{     
        authDialog->hide();
        powermanager->show();
        powermanager->setFocus();
#ifndef USE_INTEL
        powermanager->showNormalSize();
#endif
        powermanager->setGeometry((width()-powermanager->width())/2,
                                  (height()-powermanager->height())/2,
                                  powermanager->width(),powermanager->height());
    }
}

void LockWidget::switchToSureDialog(int type)
{
    powermanagerType = type;
    if(m_kylinNM && m_kylinNM->isVisible())
        m_kylinNM->hide();
    if(scrollArea && scrollArea->isVisible())
        scrollArea->hide();

    authDialog->hide();
    powermanager->hide();
    sureWidget->show();
    sureWidget->setFocus();
    ui->widgetTime->hide();
    ui->btnPowerManager->hide();
    ui->btnNetworkManager->hide();
    ui->btnSwitchUser->hide();
    ui->btnKeyboard->hide();
}

void LockWidget::hideSureDialog()
{
    sureWidget->hide();
    powermanager->show();
    ui->widgetTime->show();
    ui->btnPowerManager->show();
    ui->btnNetworkManager->show();
    ui->btnSwitchUser->show();
    ui->btnKeyboard->show();
}

void LockWidget::confirmClicked()
{
    if(m_kylinNM && m_kylinNM->isVisible())
        m_kylinNM->hide();
    if(scrollArea && scrollArea->isVisible())
        scrollArea->hide();
    sureWidget->hide();
    powermanager->hide();
    authDialog->show();
    ui->widgetTime->show();
    ui->btnPowerManager->show();
    ui->btnNetworkManager->show();
    ui->btnSwitchUser->show();
    ui->btnKeyboard->show();
    powermanager->doEvent(powermanagerType);
}

void LockWidget::showNetManager()
{
    if(!m_kylinNM){
        return;
    }

    if(m_kylinNM->isVisible())
    {
        m_kylinNM->hide();
    } else {
        m_kylinNM->show();
        if(scrollArea && scrollArea->isVisible())
            scrollArea->hide();
        m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20,
                               this->height() - m_kylinNM->height() - 100,
                               m_kylinNM->width(),
                               m_kylinNM->height());
        m_kylinNM->updateWifiList();
    }
}

void LockWidget::hideNetManager()
{
    if(!m_kylinNM){
        return;
    }

    if(m_kylinNM && m_kylinNM->isVisible())
        m_kylinNM->hide();
    if(scrollArea && scrollArea->isVisible())
        scrollArea->hide();
}

int LockWidget::getNetStatus()
{
    int ret = -1;
    QString actLanName = "--";
    QString actWifiName = "--";

    activecon *act = kylin_network_get_activecon_info();
    int index = 0;
    while (act[index].con_name != NULL) {
        if (QString(act[index].type) == "ethernet" || QString(act[index].type) == "802-3-ethernet") {
            actLanName = QString(act[index].con_name);
        }
        if (QString(act[index].type) == "wifi" || QString(act[index].type) == "802-11-wireless") {
            actWifiName = QString(act[index].con_name);
        }
        index ++;
    }

    // 设置图标
    if (actLanName != "--") {
        ret = 0;
    } else if (actWifiName != "--") {
        ret = 1;
    } else {
        ret = -1;
    }
    qDebug() << "[KylinNM] [getConnectStatus] getConnectStatus = " << ret;
    //KylinDBus::checkConnectivity();
    return ret;
}

void LockWidget::updateNetIcon(int status)
{
    switch(status) {
    case 0:
        //有线
        ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-wired.png"));
        break;
    case 1:
        //无线
        ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-wifi.png"));
        break;
    case 2:
        //有线+无线
        ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-wired.png"));
        break;
    default:
        //无连接
        ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-no-signal.png"));
    }
}

void LockWidget::switchToGreeter()
{
    if(authDialog)
    {
        authDialog->stopAuth();
    }
    displayManager->switchToGreeter();;
}

void LockWidget::setVirkeyboardPos()
{
    if(vKeyboard)
    {
        vKeyboard->setGeometry(0,
                               height() - height()/3,
                               width(), height()/3);

    }
}


void LockWidget::initUserMenu()
{
    scrollArea = new QScrollArea(this);
    scrollArea->installEventFilter(this);
//    scrollArea->setAttribute(Qt::WA_TranslucentBackground); //设置背景透明
//    scrollArea->viewport()->setAttribute(Qt::WA_TranslucentBackground); //设置背景透明
    scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //屏蔽水平滚动条
    scrollArea->setStyleSheet("QScrollArea {background-color: rgba(255,255,255,15%);border-radius:8px;}");
    scrollArea->viewport()->setStyleSheet("background-color:transparent;");
    scrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false);
    scrollArea->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu);
    scrollContents = new QWidget(scrollArea);
    scrollContents->installEventFilter(this);
    scrollArea->setWidget(scrollContents);
    scrollArea->hide();

    if(!usersMenu)
    {
        usersMenu = new QMenu(scrollContents);
        usersMenu->setObjectName("usersMenu");
        usersMenu->setToolTipsVisible(true);
//        usersMenu->setStyleSheet("QMenu{background-color:transparent;color:white;padding:5px 5px 5px 8px}");
                                 //QToolTip{border-radius:4px;background-color:rgb(255,255,255,40%);color:white;}
	//如果没有设置x11属性，则由于弹出菜单受窗口管理器管理，而主窗口不受，在点击菜单又点回主窗口会闪屏。
        usersMenu->setWindowFlags(Qt::X11BypassWindowManagerHint);
        //usersMenu->hide();
        connect(usersMenu, &QMenu::triggered,
                this, &LockWidget::onUserMenuTrigged);
    }

    if(displayManager->getDisplayType() == "gdm"){
//        QAction *action = new QAction(QIcon(users->getDefaultIcon()),
//                                      tr("SwitchUser"), this);
        QWidgetAction *action = new QWidgetAction(usersMenu);
        HoverWidget *widget = new HoverWidget("");
        widget->setStyleSheet("HoverWidget:hover{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
        widget->setObjectName("SwitchUser");
        list.append(widget);
        widget->setFixedSize(240, 40);
        QLabel *iconlabel =new QLabel(widget);
        QPixmap p(users->getDefaultIcon());
        p = p.scaled(32*scale,32*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
        p = PixmapToRound(p, 16*scale);
        iconlabel->setPixmap(p);
        iconlabel->setGeometry(8,4,32,32);
        QLabel *textlabel =new QLabel(widget);
        textlabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}");
        textlabel->setGeometry(48,8,190,24);
        action->setToolTip("SwitchUser");
        action->setData("SwitchUser");
        usersMenu->addAction(action);
        list.append(widget);
    }

    else if(displayManager->getDisplayType() == "lightdm"){
        connect(users, &Users::userAdded, this, &LockWidget::onUserAdded);
        connect(users, &Users::userDeleted, this, &LockWidget::onUserDeleted);

        for(auto user : users->getUsers())
        {
            onUserAdded(user);
        }

        if(displayManager->hasGuestAccount())
        {
//            QAction *action = new QAction(QIcon(users->getDefaultIcon()),
//                                      tr("Guest"), this);
            QWidgetAction *action = new QWidgetAction(usersMenu);
            HoverWidget *widget = new HoverWidget("");
            widget->setStyleSheet("HoverWidget:hover{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
            widget->setObjectName("Guest");
            list.append(widget);
            widget->setFixedSize(240, 40);
            QLabel *iconlabel =new QLabel(widget);
            QPixmap p(users->getDefaultIcon());
            p = p.scaled(32*scale,32*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
            p = PixmapToRound(p, 16*scale);
            iconlabel->setPixmap(p);
            iconlabel->setGeometry(8,4,32,32);
            QLabel *textlabel =new QLabel(widget);
            textlabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}");
            textlabel->setGeometry(48,8,190,24);
            action->setData("Guest");
            action->setToolTip("Guest");
            usersMenu->addAction(action);
            list.append(widget);
        }
    }
    UserItem currentUser = users->getUserByName(getenv("USER"));
    for(int i = 0;i < list.count(); i++){
        if(list.at(i)->objectName() == currentUser.name){
            list.at(i)->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}"
                                      "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,40%);border-radius: 6px;}");
            nowAt = i;
        } else {
            list.at(i)->setStyleSheet("HoverWidget{background-color:transparent;}"
                                      "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
        }
    }
    scrollContents->setFixedSize(usersMenu->width() - 14, usersMenu->height());
    //设置弹出菜单，设置弹出菜单的坐标为切换用户按钮的上方，中间保持一定间隔。
    if(scrollArea){
        if(scrollContents->height() < height()/2){
            scrollArea->setFixedSize(usersMenu->width(),scrollContents->height()+1);
        }else{
            scrollArea->setFixedSize(usersMenu->width() + 4, height()/2);
        }
        scrollArea->move(ui->btnSwitchUser->geometry().x()- scrollArea->width()/2 + 24, \
                    height() - 72 - scrollArea->height() - 5);
    }

}

void LockWidget::keyReleaseEvent(QKeyEvent *e)
{
    if(e->key() == Qt::Key_K){
        if(e->modifiers() & Qt::ControlModifier)
            showVirtualKeyboard();
    }
}

/* lockscreen follows cursor */
void LockWidget::resizeEvent(QResizeEvent *event)
{
    QSize size = event->size();
        //重新计算缩放比例
    scale = QString::number(size.width() / 1920.0, 'f', 1).toFloat();

    //系统时间
    ui->widgetTime->move((width()-ui->widgetTime->geometry().width())/2, 59*scale);
    if(sureWidget)
        sureWidget->move((width()-sureWidget->geometry().width())/2, (height()-sureWidget->geometry().height())/2);

    //认证窗口
    //设置认证窗口左右居中
    if(scale >= 1)
        authDialog->setGeometry((width()-authDialog->geometry().width())/2,height()/(4-0.65*scale), \
                            authDialog->width(), (height()*3/4));
    else
        authDialog->setGeometry((width()-authDialog->geometry().width())/2,height()/(4+0.65*scale), \
                                authDialog->width(), (height()*3/4));

    if(scale > 1)
            scale = 1;

    //右下角按钮,x,y的初始值代表距离右下角的距离。
    int x=24,y=72;
    x = x + ui->btnPowerManager->width();
    ui->btnPowerManager->move(width() - x,height() - y);

    if(ui->btnKeyboard->isVisible()){
        x = x+ui->btnKeyboard->width()+16;
        ui->btnKeyboard->move(width() - x, height() -  y);
    }

    x = x + ui->btnNetworkManager->width()+16;
    ui->btnNetworkManager->move(width() - x, height() - y);

    x = x + ui->btnSwitchUser->width()+16;
    ui->btnSwitchUser->move(width() - x, height() - y);
    setVirkeyboardPos();

    if(scrollContents && usersMenu)
        scrollContents->setFixedSize(usersMenu->width() - 14, usersMenu->height());
    //设置弹出菜单，设置弹出菜单的坐标为切换用户按钮的上方，中间保持一定间隔。
    if(scrollArea){
        if(scrollContents->height() < height()/2){
            scrollArea->setFixedSize(usersMenu->width(),scrollContents->height()+1);
        }else{
            scrollArea->setFixedSize(usersMenu->width() + 4, height()/2);
        }
        scrollArea->move(ui->btnSwitchUser->geometry().x()- scrollArea->width()/2 + 24, \
                    height() - y - scrollArea->height() - 5);
    }
    
    if(m_kylinNM){
        m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20,
                           this->height() - m_kylinNM->height() - 100,
                           m_kylinNM->width(),
                           m_kylinNM->height());
    }

    if(powermanager){
#ifndef USE_INTEL
        if(width() < 1280)
            powermanager->showSmallSize();
        else
            powermanager->showNormalSize();
#endif
        powermanager->setGeometry((width()- powermanager->width())/2,
                                  (height()-powermanager->height())/2,
                                  powermanager->width(),powermanager->height());

    }
    if(QX11Info::isPlatformX11()){
        XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime);
    }
}


void LockWidget::onUserAdded(const UserItem &user)
{
//    QAction *action = new QAction(QIcon(user.icon), user.realName, this);
//    action->setCheckable(true);

    QWidgetAction *action = new QWidgetAction(usersMenu);
    HoverWidget *widget = new HoverWidget("");
    widget->setStyleSheet("HoverWidget:hover{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
    widget->setObjectName(user.name);
    list.append(widget);
    widget->setFixedSize(240, 40);
    QLabel *iconlabel =new QLabel(widget);
    QPixmap p(user.icon);
    p = p.scaled(32*scale,32*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    p = PixmapToRound(p, 16*scale);
    iconlabel->setPixmap(p);
    //iconlabel->setStyleSheet("background-color:transparent;");
    iconlabel->setGeometry(8,4,32,32);
    QLabel *textlabel =new QLabel(widget);
    textlabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}");
    textlabel->setGeometry(48,8,190,24);
    if(getLoadStatus(user.name)){
        QLabel *statusIcon = new QLabel(widget);
        QPixmap status(":/image/assets/selected.svg");
        status = status.scaled(14*scale,14*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
        p = PixmapToRound(status, 7*scale);
        statusIcon->setPixmap(status);
        statusIcon->setGeometry(32, 5, 14, 14);
    }
    action->setDefaultWidget(widget);

    QFont font;
    font.setPixelSize(16);
    QString str = ElideText(font,189,user.realName);
    if(user.realName != str){
         textlabel->setToolTip(user.realName);
         textlabel->setText(str);
    } else {
        textlabel->setText(user.realName);
    }
    action->setData(user.name);
    usersMenu->addAction(action);
    usersMenu->adjustSize();
}

QPixmap LockWidget::PixmapToRound(const QPixmap &src, int radius)
{
    if (src.isNull()) {
        return QPixmap();
    }

    QPixmap pixmapa(src);
    QPixmap pixmap(radius*2,radius*2);
    pixmap.fill(Qt::transparent);
    QPainter painter(&pixmap);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    QPainterPath path;
    path.addEllipse(0, 0, radius*2, radius*2);
    painter.setClipPath(path);
    painter.drawPixmap(0, 0, radius*2, radius*2, pixmapa);
    return pixmap;
}

void LockWidget::onUserDeleted(const UserItem &user)
{
    for(auto action : usersMenu->actions())
    {
        if(action->data() == user.name)
            usersMenu->removeAction(action);
    }
}

bool LockWidget::getLoadStatus(const QString &name)
{
    QDBusInterface interface(LG_DBUS_SERVICE,
                                  LG_DBUS_PATH,
                                  LG_DBUS_INTERFACE,
                                  QDBusConnection::systemBus());
    QDBusMessage result = interface.call("ListUsers");
    QList<QVariant> outArgs = result.arguments();
    QVariant first = outArgs.at(0);
    QDBusArgument dbvFirst = first.value<QDBusArgument>();
    QVariant vFirst = dbvFirst.asVariant();
    const QDBusArgument &dbusArgs = vFirst.value<QDBusArgument>();

    QVector<userInfo> loginedUsers;

    dbusArgs.beginArray();
    while (!dbusArgs.atEnd()) {
        userInfo user;
        dbusArgs >> user;
        loginedUsers.push_back(user);
    }
    for (userInfo user : loginedUsers) {
        QDBusInterface userPertyInterface("org.freedesktop.login1",
                                          user.userPath.path(),
                                          "org.freedesktop.DBus.Properties",
                                          QDBusConnection::systemBus());
        QDBusReply<QVariant> reply = userPertyInterface.call("Get", "org.freedesktop.login1.User", "State");
        if (reply.isValid()) {
            QString status = reply.value().toString();
            if ("closing" != status) {
                m_loginedUser.append(user.userName);
            }
        }
    }
    int count = 0;
    for(int i = 0 ;i<m_loginedUser.count();i++)
    {
        if(m_loginedUser.at(i) == name)
            count++;
    }
    if(count > 0)
        return true;
    else
        return false;
}

void LockWidget::onUserMenuTrigged(QAction *action)
{
    qDebug() << action->data().toString() << "selected";

    if(authDialog)
    {
        authDialog->stopAuth();
    }

    QString userName = action->data().toString();
    for (int i =0; i < list.count(); i++)
    {
            if(list.at(i)->objectName() == userName){
                list.at(i)->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}"
                                          "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,40%);border-radius: 6px;}");
            } else {
                list.at(i)->setStyleSheet("HoverWidget{background-color:transparent;}"
                                          "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}");
            }
    }
    if(userName == "Guest")
    {
        displayManager->switchToGuest();
    }
    else if(userName == "SwitchUser")
    {
        displayManager->switchToGreeter();
    }
    else
    {
        displayManager->switchToUser(userName);
    }
}

bool LockWidget::exitSubWidget()
{
    bool allExited = true;
    if(scrollArea && scrollArea->isVisible()){
        scrollArea->hide();
        allExited = false;
    }
    if(powermanager && powermanager->isVisible()){
        authDialog->setFocus();
        authDialog->show();
        powermanager->hide();
        allExited = false;
    }
    if(m_kylinNM && m_kylinNM->isVisible()){
        m_kylinNM->hide();
        allExited = false;
    }
    return allExited;
}

QDBusArgument &operator <<(QDBusArgument &arg, const userInfo &usersInfo)
{
    arg.beginStructure();
    arg << usersInfo.userId
        << usersInfo.userName
        << usersInfo.userPath;
    arg.endStructure();
    return arg;
}
const QDBusArgument &operator >>(const QDBusArgument &arg, userInfo &usersInfo)
{
    arg.beginStructure();
    arg >> usersInfo.userId
        >> usersInfo.userName
        >> usersInfo.userPath;
    arg.endStructure();
    return arg;
}



