#include "hiperiso2diskwindow.h"
#include "ui_hiperiso2diskwindow.h"
#include "partcfgdialog.h"

#include <QMessageBox>

extern "C" {
#include "hiperiso_define.h"
#include "hiperiso_util.h"
#include "hiperiso_disk.h"
#include "hiperiso_json.h"
#include "hiperiso_http.h"
#include "hiperiso_qt.h"
}

MyQThread::MyQThread(QObject *parent) : QThread(parent)
{
    m_index = -1;
    m_type = 0;
    m_running = false;
}

void MyQThread::install_run()
{
    int ret = 0;
    int pos = 0;
    int buflen = 0;
    int percent = 0;
    char buf[1024];
    char dec[64];
    char out[256];
    char disk_name[32];    
    hiperiso_disk *cur;

    vlog("install run %d ...\n", m_index);

    cur = g_disk_list + m_index;
    snprintf(disk_name, sizeof(disk_name), "%s", cur->disk_name);
    snprintf(dec, sizeof(dec), "%llu", (unsigned long long)m_reserve_space);

    buflen = sizeof(buf);
    HISO_JSON_FMT_BEGIN(pos, buf, buflen);
    HISO_JSON_FMT_OBJ_BEGIN();
    HISO_JSON_FMT_STRN("method", "install");
    HISO_JSON_FMT_STRN("disk", disk_name);
    HISO_JSON_FMT_STRN("reserve_space", dec);
    HISO_JSON_FMT_UINT("partstyle", hiperiso_code_get_cur_part_style());
    HISO_JSON_FMT_UINT("secure_boot", m_secureboot);
    HISO_JSON_FMT_UINT("align_4kb", m_align4K);
    HISO_JSON_FMT_OBJ_END();
    HISO_JSON_FMT_END(pos);

    out[0] = 0;
    hiperiso_func_handler(buf, out, sizeof(out));
    vlog("func handler install <%s>\n", out);

    if (strstr(out, "success"))
    {
        while (percent != 100)
        {
            percent = hiperiso_code_get_percent();
            emit thread_event(THREAD_MSG_PROGRESS_BAR, percent);
            msleep(50);
        }

        ret = hiperiso_code_get_result();
        hiperiso_code_refresh_device();
        cur = NULL;
    }
    else
    {
        ret = 1;
    }

    emit thread_event(THREAD_MSG_INSTALL_FINISH, ret);
    m_running = false;
}

void MyQThread::update_run()
{
    int ret = 0;
    int percent = 0;
    char buf[1024];
    char out[256];
    char disk_name[32]; 
    hiperiso_disk *cur;

    vlog("install run %d ...\n", m_index);

    cur = g_disk_list + m_index;
    snprintf(disk_name, sizeof(disk_name), "%s", cur->disk_name);
    snprintf(buf, sizeof(buf), "{\"method\":\"update\",\"disk\":\"%s\",\"secure_boot\":%d}", disk_name, m_secureboot);

    out[0] = 0;
    hiperiso_func_handler(buf, out, sizeof(out));
    vlog("func handler update <%s>\n", out);

    if (strstr(out, "success"))
    {
        while (percent != 100)
        {
            percent = hiperiso_code_get_percent();
            emit thread_event(THREAD_MSG_PROGRESS_BAR, percent);
            msleep(50);
        }

        ret = hiperiso_code_get_result();
        hiperiso_code_refresh_device();
        cur = NULL;
    }
    else
    {
        ret = 1;
    }

    emit thread_event(THREAD_MSG_UPDATE_FINISH, ret);
    m_running = false;
}

void MyQThread::run()
{
    if (THREAD_TYPE_INSTALL == m_type)
    {
        install_run();
    }
    else if (THREAD_TYPE_UPDATE == m_type)
    {
        update_run();
    }
    else
    {

    }
}


Hiperiso2DiskWindow::Hiperiso2DiskWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Hiperiso2DiskWindow)
{
    m_partcfg = new PartCfgDialog();
    m_part_group = new QActionGroup(this);
    m_lang_group = new QActionGroup(this);
    m_thread = new MyQThread(this);

    ui->setupUi(this);
}

Hiperiso2DiskWindow::~Hiperiso2DiskWindow()
{
    delete m_partcfg;
    delete m_part_group;
    delete m_lang_group;
    delete m_thread;
    delete ui;
}

bool LangCompare(const QString &s1, const QString &s2)
{
    if (true == s1.startsWith("Chinese Simplified") && false == s2.startsWith("Chinese Simplified"))
    {
        return true;
    }
    else if (false == s1.startsWith("Chinese Simplified") && true == s2.startsWith("Chinese Simplified"))
    {
        return false;
    }
    else
    {
        return s1 < s2;
    }
}

int Hiperiso2DiskWindow::lang_string(const QString &id, QString &str)
{
    QString cur = hiperiso_code_get_cur_language();

    for (QJsonArray::iterator p = m_lang_array.begin(); p != m_lang_array.end(); p++)
    {
        if (p->toObject().value("name") == cur)
        {
            str = p->toObject().value(id).toString();
            str = str.replace("#@", "\r\n");
            return 0;
        }
    }

    return 1;
}

void Hiperiso2DiskWindow::update_ui_language()
{
    QString dev;
    QJsonObject obj;
    QString cur = hiperiso_code_get_cur_language();

    for (QJsonArray::iterator p = m_lang_array.begin(); p != m_lang_array.end(); p++)
    {
        if (p->toObject().value("name") == cur)
        {
            obj = p->toObject();
            break;
        }
    }

    ui->menuOption->setTitle(_LANG_STR("STR_MENU_OPTION"));
    ui->actionSecure_Boot_Support->setText(_LANG_STR("STR_MENU_SECURE_BOOT"));
    ui->menuPartition_Style->setTitle(_LANG_STR("STR_MENU_PART_STYLE"));
    ui->actionPartition_Configuration->setText(_LANG_STR("STR_MENU_PART_CFG"));
    ui->actionClear_Hiperiso->setText(_LANG_STR("STR_MENU_CLEAR"));
    ui->actionShow_All_Devices->setText(_LANG_STR("STR_SHOW_ALL_DEV"));

    dev = _LANG_STR("STR_DEVICE");
    if (m_partcfg->reserve)
    {
        QString str;
        str.sprintf(" [ -%lld%s ]", (long long)m_partcfg->resvalue, m_partcfg->unit ? "GB" : "MB");
        ui->groupBoxDevice->setTitle(dev + str);
    }
    else
    {
        ui->groupBoxDevice->setTitle(dev);
    }

    ui->groupBoxHiperisoLocal->setTitle(_LANG_STR("STR_LOCAL_VER"));
    ui->groupBoxHiperisoDevice->setTitle(_LANG_STR("STR_DISK_VER"));
    ui->groupBoxStatus->setTitle(_LANG_STR("STR_STATUS"));
    ui->ButtonInstall->setText(_LANG_STR("STR_INSTALL"));
    ui->ButtonUpdate->setText(_LANG_STR("STR_UPDATE"));
    m_partcfg->update_language_ui(obj);
    m_partcfg->setWindowTitle(_LANG_STR("STR_MENU_PART_CFG"));
}

void Hiperiso2DiskWindow::lang_check_action(QAction *act)
{
    hiperiso_code_set_cur_language(act->text().toStdString().c_str());
    update_ui_language();
}

void Hiperiso2DiskWindow::LoadLanguages()
{
    QString curlang = hiperiso_code_get_cur_language();
    if (curlang.isEmpty())
    {
        QString LANG = qgetenv("LANG");
        if (LANG.startsWith("zh_CN"))
        {
            hiperiso_code_set_cur_language("Chinese Simplified (简体中文)");
        }
        else
        {
            hiperiso_code_set_cur_language("English (English)");                    
        }
        curlang = hiperiso_code_get_cur_language();
    }


    QFile inFile("./tool/languages.json");
    inFile.open(QIODevice::ReadOnly|QIODevice::Text);
    QByteArray data = inFile.readAll();
    inFile.close();

    QJsonParseError errorPtr;
    QJsonDocument doc = QJsonDocument::fromJson(data, &errorPtr);

    m_lang_array = doc.array();
    QVector<QString> List;
    for (QJsonArray::iterator p = m_lang_array.begin(); p != m_lang_array.end(); p++)
    {
        List.push_back(p->toObject().value("name").toString());
    }

    connect(m_lang_group, SIGNAL(triggered(QAction *)), this, SLOT(lang_check_action(QAction *)));

    std::sort(List.begin(), List.end(), LangCompare);

    for (QVector<QString>::iterator p = List.begin(); p != List.end(); p++)
    {
        QAction *action = new QAction(*p, m_lang_group);
        action->setCheckable(true);

        if (p->compare(curlang) == 0)
        {
            action->setChecked(true);
            m_lang_group->triggered(action);
        }

        ui->menuLanguage->addAction(action);
    }


}

void Hiperiso2DiskWindow::part_style_check_action(QAction *action)
{
    int style = 0;

    if (action->text() == "MBR")
    {
        style = 0;
        ui->labelHiperisoLocalPartStyle->setText("MBR");
    }
    else
    {
        style = 1;
        ui->labelHiperisoLocalPartStyle->setText("GPT");
    }

    if (style != hiperiso_code_get_cur_part_style())
    {
        hiperiso_code_set_cur_part_style(style);
    }
}

static hiperiso_disk *select_active_dev(const QString &select, int *activeid)
{
    int i;
    int alldev = hiperiso_code_get_cur_show_all();
    hiperiso_disk *cur = NULL;

    /* find the match one */
    if (!select.isEmpty())
    {
        for (i = 0; i < g_disk_num; i++)
        {
            cur = g_disk_list + i;
            if (alldev == 0 && cur->type != HISO_DEVICE_USB)
            {
                continue;
            }

            if (select.compare(cur->disk_name) == 0)
            {
                *activeid = i;
                return cur;
            }
        }
    }

    /* find the first one that installed with Hiperiso */
    for (i = 0; i < g_disk_num; i++)
    {
        cur = g_disk_list + i;
        if (alldev == 0 && cur->type != HISO_DEVICE_USB)
        {
            continue;
        }

        if (cur->hisodata.hiperiso_valid)
        {
            *activeid = i;
            return cur;
        }
    }

    /* find the first USB interface device */
    for (i = 0; i < g_disk_num; i++)
    {
        cur = g_disk_list + i;
        if (alldev == 0 && cur->type != HISO_DEVICE_USB)
        {
            continue;
        }

        if (cur->type == HISO_DEVICE_USB)
        {
            *activeid = i;
            return cur;
        }
    }

    /* use the first one */
    for (i = 0; i < g_disk_num; i++)
    {
        cur = g_disk_list + i;
        if (alldev == 0 && cur->type != HISO_DEVICE_USB)
        {
            continue;
        }

        *activeid = i;
        return cur;
    }

    return NULL;
}


void Hiperiso2DiskWindow::FillDeviceList(const QString &select)
{
    int active;
    int count = 0;
    int alldev = hiperiso_code_get_cur_show_all();
    hiperiso_disk *cur;

    ui->comboBoxDevice->clear();

    for (int i = 0; i < g_disk_num; i++)
    {
        cur = g_disk_list + i;

        if (alldev == 0 && cur->type != HISO_DEVICE_USB)
        {
            continue;
        }

        QString item;
        item.sprintf("%s  [%s]  %s", cur->disk_name, cur->human_readable_size, cur->disk_model);
        ui->comboBoxDevice->addItem(item);
        count++;
    }

    cur = select_active_dev(select, &active);
    if (cur)
    {
        vlog("combox count:%d, active:%s id:%d\n", count, cur->disk_name, active);
        ui->ButtonInstall->setEnabled(true);
        ui->ButtonUpdate->setEnabled(cur->hisodata.hiperiso_valid);
        ui->comboBoxDevice->setCurrentIndex(active);
    }
    else
    {
        vlog("combox count:%d, no active id\n", count);
        ui->ButtonInstall->setEnabled(false);
        ui->ButtonUpdate->setEnabled(false);
    }
}


void Hiperiso2DiskWindow::OnInitWindow(void)
{
    int len;
    const uchar *data;
    QIcon icon;
    QPixmap pix1;
    QPixmap pix2;
    char ver[512];

    ui->labelHiperisoLocalSecure->hide();

    m_part_group->addAction(ui->actionMBR);
    m_part_group->addAction(ui->actionGPT);
    connect(m_part_group, SIGNAL(triggered(QAction *)), this, SLOT(part_style_check_action(QAction *)));

    if (hiperiso_code_get_cur_part_style())
    {
        ui->actionGPT->setChecked(true);
        m_part_group->triggered(ui->actionGPT);
    }
    else
    {
        ui->actionMBR->setChecked(true);
        m_part_group->triggered(ui->actionMBR);
    }

    snprintf(ver, sizeof(ver), VERSION_FMT, hiperiso_get_local_version());
    ui->labelHiperisoLocalVer->setText(QApplication::translate("Hiperiso2DiskWindow", ver, nullptr));

    LoadLanguages();

    data = (const uchar *)get_refresh_icon_raw_data(&len);
    pix1.loadFromData(data, len);
    icon.addPixmap(pix1);
    ui->ButtonRefresh->setIcon(icon);

    data = (const uchar *)get_secure_icon_raw_data(&len);
    pix2.loadFromData(data, len);
    ui->labelHiperisoLocalSecure->setPixmap(pix2);
    ui->labelHiperisoDeviceSecure->setPixmap(pix2);

    ui->labelHiperisoDeviceSecure->setHidden(true);
    ui->labelHiperisoDeviceVer->setText("");
    ui->labelHiperisoDevicePartStyle->setText("");

    ui->actionSecure_Boot_Support->trigger();

    ui->actionShow_All_Devices->setChecked(hiperiso_code_get_cur_show_all());

    connect(m_thread, &MyQThread::thread_event, this,  &Hiperiso2DiskWindow::thread_event);

    FillDeviceList("");
}

void Hiperiso2DiskWindow::showEvent(QShowEvent *ev)
{
    QMainWindow::showEvent(ev);
    OnInitWindow();
}

void Hiperiso2DiskWindow::on_ButtonInstall_clicked()
{
    int index;
    quint64 size = 0, space = 0;
    hiperiso_disk *cur;
    QString title_warn, title_err, msg;

    lang_string("STR_ERROR", title_err);
    lang_string("STR_WARNING", title_warn);

    if (m_thread->m_running || hiperiso_code_is_busy())
    {
        lang_string("STR_WAIT_PROCESS", msg);
        QMessageBox::warning(NULL, title_warn, msg);
        return;
    }

    index = ui->comboBoxDevice->currentIndex();
    if (index < 0 || index > g_disk_num)
    {
        vlog("Invalid combobox current index %d\n", index);
        return;
    }

    cur = g_disk_list + index;

    if (cur->is4kn)
    {
        lang_string("STR_4KN_UNSUPPORTED", msg);
        QMessageBox::critical(NULL, title_err, msg);
        return;
    }

    if (hiperiso_code_get_cur_part_style() == 0 && cur->size_in_byte > 2199023255552ULL)
    {
        lang_string("STR_DISK_2TB_MBR_ERROR", msg);
        QMessageBox::critical(NULL, title_err, msg);
        return;
    }

    if (m_partcfg->reserve)
    {
        size = cur->size_in_byte / SIZE_1MB;
        space = m_partcfg->resvalue;
        if (m_partcfg->unit == 1)
        {
            space = m_partcfg->resvalue * 1024;
        }

        if (size <= space || (size - space) <= HISOEFI_PART_BYTES / SIZE_1MB)
        {
            lang_string("STR_SPACE_VAL_INVALID", msg);
            QMessageBox::critical(NULL, title_err, msg);
            vlog("reserved space too big.\n");
            return;
        }
    }

    lang_string("STR_INSTALL_TIP", msg);
    if (QMessageBox::Yes != QMessageBox::warning(NULL, title_warn, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No))
    {
        return;
    }

    lang_string("STR_INSTALL_TIP2", msg);
    if (QMessageBox::Yes != QMessageBox::warning(NULL, title_warn, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No))
    {
        return;
    }

    ui->ButtonRefresh->setEnabled(false);
    ui->ButtonInstall->setEnabled(false);
    ui->ButtonRefresh->setEnabled(false);

    m_thread->m_type = THREAD_TYPE_INSTALL;
    m_thread->m_index = index;
    m_thread->m_reserve_space = space * SIZE_1MB;
    m_thread->m_secureboot = ui->actionSecure_Boot_Support->isChecked();
    m_thread->m_align4K = m_partcfg->align;
    m_thread->m_running = true;

    m_thread->start();
}

void Hiperiso2DiskWindow::on_ButtonUpdate_clicked()
{
    int index;
    hiperiso_disk *cur;
    QString title_info, title_warn, title_err, msg;

    lang_string("STR_ERROR", title_err);
    lang_string("STR_WARNING", title_warn);
    lang_string("STR_INFO", title_info);

    if (m_thread->m_running || hiperiso_code_is_busy())
    {        
        lang_string("STR_WAIT_PROCESS", msg);
        QMessageBox::warning(NULL, title_warn, msg);
        return;
    }

    index = ui->comboBoxDevice->currentIndex();
    if (index < 0 || index > g_disk_num)
    {
        vlog("Invalid combobox current index %d\n", index);
        return;
    }

    cur = g_disk_list + index;
    if (cur->hisodata.hiperiso_valid == 0)
    {
        vlog("invalid hiperiso version");
        return;
    }

    lang_string("STR_UPDATE_TIP", msg);
    if (QMessageBox::Yes != QMessageBox::information(NULL, title_info, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No))
    {
        return;
    }

    ui->ButtonRefresh->setEnabled(false);
    ui->ButtonInstall->setEnabled(false);
    ui->ButtonRefresh->setEnabled(false);

    m_thread->m_type = THREAD_TYPE_UPDATE;
    m_thread->m_index = index;        
    m_thread->m_secureboot = ui->actionSecure_Boot_Support->isChecked();

    m_thread->m_running = true;
    m_thread->start();
}

void Hiperiso2DiskWindow::on_ButtonRefresh_clicked()
{
    QString title_warn, msg;

    if (m_thread->m_running || hiperiso_code_is_busy())
    {
        lang_string("STR_WARNING", title_warn);
        lang_string("STR_WAIT_PROCESS", msg);
        QMessageBox::warning(NULL, title_warn, msg);
        return;
    }

    hiperiso_code_refresh_device();
    FillDeviceList("");
}

void Hiperiso2DiskWindow::on_comboBoxDevice_currentIndexChanged(int index)
{    
    char ver[512];
    hiperiso_disk *cur;

    ui->labelHiperisoDeviceSecure->setHidden(true);
    ui->labelHiperisoDeviceVer->setText("");
    ui->labelHiperisoDevicePartStyle->setText("");

    if (index < 0 || index > g_disk_num)
    {
        vlog("invalid combobox index %d\n", index);
        return;
    }

    cur = g_disk_list + index;
    if (cur->hisodata.hiperiso_valid)
    {
        if (cur->hisodata.secure_boot_flag)
        {
            ui->labelHiperisoDeviceSecure->setHidden(false);
        }
        else
        {
            ui->labelHiperisoDeviceSecure->setHidden(true);
        }

        if ((int)(ui->actionSecure_Boot_Support->isChecked()) != cur->hisodata.secure_boot_flag)
        {
            ui->actionSecure_Boot_Support->trigger();
        }

        snprintf(ver, sizeof(ver), VERSION_FMT, cur->hisodata.hiperiso_ver);
        ui->labelHiperisoDeviceVer->setText(QApplication::translate("Hiperiso2DiskWindow", ver, nullptr));
        ui->labelHiperisoDevicePartStyle->setText(cur->hisodata.partition_style ? "GPT" : "MBR");
    }
    else
    {
        if (!(ui->actionSecure_Boot_Support->isChecked()))
        {
            ui->actionSecure_Boot_Support->trigger();
        }
    }
}

void Hiperiso2DiskWindow::on_actionPartition_Configuration_triggered()
{
    m_partcfg->update_ui_status();
    if (QDialog::Accepted == m_partcfg->exec())
    {
        QString str;
        QString dev;
        lang_string("STR_DEVICE", dev);

        if (m_partcfg->reserve)
        {
            str.sprintf(" [ -%lld%s ]", (long long)m_partcfg->resvalue, m_partcfg->unit ? "GB" : "MB");
            ui->groupBoxDevice->setTitle(dev + str);
        }
        else
        {
            ui->groupBoxDevice->setTitle(dev);
        }
    }
}

void Hiperiso2DiskWindow::on_actionClear_Hiperiso_triggered()
{
    int ret;
    int index;
    hiperiso_disk *cur;
    QString title_err, title_warn, title_info, msg;
    char disk_name[64];
    char buf[256];
    char out[256];

    lang_string("STR_ERROR", title_err);
    lang_string("STR_WARNING", title_warn);
    lang_string("STR_INFO", title_info);

    if (m_thread->m_running || hiperiso_code_is_busy())
    {
        lang_string("STR_WAIT_PROCESS", msg);
        QMessageBox::warning(NULL, title_warn, msg);
        return;
    }

    index = ui->comboBoxDevice->currentIndex();
    if (index < 0 || index > g_disk_num)
    {
        vlog("Invalid combobox current index %d\n", index);
        return;
    }

    cur = g_disk_list + index;

    lang_string("STR_INSTALL_TIP", msg);
    if (QMessageBox::Yes != QMessageBox::warning(NULL, title_warn, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No))
    {
        return;
    }

    lang_string("STR_INSTALL_TIP2", msg);
    if (QMessageBox::Yes != QMessageBox::warning(NULL, title_warn, msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No))
    {
        return;
    }

    snprintf(disk_name, sizeof(disk_name), "%s", cur->disk_name);
    snprintf(buf, sizeof(buf), "{\"method\":\"clean\",\"disk\":\"%s\"}", disk_name);

    out[0] = 0;
    hiperiso_func_handler(buf, out, sizeof(out));
    vlog("func handler clean <%s>\n", out);

    if (strstr(out, "success"))
    {
        ret = hiperiso_code_get_result();
        hiperiso_code_refresh_device();
        cur = NULL;
    }
    else
    {
        ret = 1;
    }

    if (ret == 0)
    {
        lang_string("STR_CLEAR_SUCCESS", msg);
        QMessageBox::information(NULL, title_info, msg);
    }
    else
    {
        lang_string("STR_CLEAR_FAILED", msg);
        QMessageBox::critical(NULL, title_err, msg);
    }

    FillDeviceList(disk_name);
}

void Hiperiso2DiskWindow::on_actionShow_All_Devices_toggled(bool arg1)
{
    hiperiso_code_set_cur_show_all(arg1);
    FillDeviceList("");
}


void Hiperiso2DiskWindow::closeEvent(QCloseEvent *event)
{
    vlog("On closeEvent ...\n");

    if (m_thread->m_running)
    {
        QString title;
        QString msg;

        lang_string("STR_WARNING", title);
        lang_string("STR_WAIT_PROCESS", msg);
        QMessageBox::warning(NULL, title, msg);

        event->ignore();
        return;
    }

    hiperiso_code_save_cfg();

    event->accept();
}

void Hiperiso2DiskWindow::on_actionSecure_Boot_Support_triggered()
{
    ui->labelHiperisoLocalSecure->setHidden(!(ui->actionSecure_Boot_Support->isChecked()));
}

void Hiperiso2DiskWindow::set_percent(int percent)
{
    int index;
    QString status, radio;

    ui->progressBar->setValue(percent);

    lang_string("STR_STATUS", status);

    if (percent == 0)
    {
        ui->groupBoxStatus->setTitle(status);
    }
    else
    {
        index = status.indexOf("-");
        radio.sprintf("%d%%", percent);
        ui->groupBoxStatus->setTitle(status.left(index + 2) + radio);
    }
}

void Hiperiso2DiskWindow::thread_event(int msg, int data)
{
    char disk_name[32];
    QString title_err, title_info, tipmsg;

    if (msg == THREAD_MSG_PROGRESS_BAR)
    {
        set_percent(data);
    }
    else if (msg == THREAD_MSG_INSTALL_FINISH)
    {
        lang_string("STR_ERROR", title_err);
        lang_string("STR_INFO", title_info);

        if (data == 0)
        {
            lang_string("STR_INSTALL_SUCCESS", tipmsg);
            QMessageBox::information(NULL, title_info, tipmsg);
        }
        else
        {
            lang_string("STR_INSTALL_FAILED", tipmsg);
            QMessageBox::critical(NULL, title_err, tipmsg);
        }

        set_percent(0);
        ui->ButtonRefresh->setEnabled(true);
        ui->ButtonInstall->setEnabled(true);
        ui->ButtonRefresh->setEnabled(true);

        snprintf(disk_name, sizeof(disk_name), "%s", g_disk_list[m_thread->m_index].disk_name);
        FillDeviceList(disk_name);
    }
    else if (msg == THREAD_MSG_UPDATE_FINISH)
    {
        lang_string("STR_ERROR", title_err);
        lang_string("STR_INFO", title_info);

        if (data == 0)
        {
            lang_string("STR_UPDATE_SUCCESS", tipmsg);
            QMessageBox::information(NULL, title_info, tipmsg);
        }
        else
        {
            lang_string("STR_UPDATE_FAILED", tipmsg);
            QMessageBox::critical(NULL, title_err, tipmsg);
        }

        set_percent(0);
        ui->ButtonRefresh->setEnabled(true);
        ui->ButtonInstall->setEnabled(true);
        ui->ButtonRefresh->setEnabled(true);

        snprintf(disk_name, sizeof(disk_name), "%s", g_disk_list[m_thread->m_index].disk_name);
        FillDeviceList(disk_name);
    }
}
