/*
 * Copyright (C) 2020, 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 3 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, see <https://www.gnu.org/licenses/>.
 */
#include "cmainwnd.h"
#include <usermanual.h>
#include <kysdk/kysdk-system/libkysysinfo.h>
#include <QWidget>
#include <QScreen>
#include "windowhelper.h"

const QStringList g_supportDocFormats = {"txt", "pdf", "docx", "pptx"};
const QStringList g_supportPicFormats = {"bmp", "jpe", "jpeg", "jpg", "pbm", "pgm", "png", "ppm", "tiff", "webp"};

CMainWnd::CMainWnd(QWidget *parent)
    : KWidget(parent)
{
    disconnect(this->windowButtonBar(), &KWindowButtonBar::doubleClick, 0, 0);
    disconnect(this->iconBar(), &KIconBar::doubleClick, 0, 0);

    createAllChildWnd();

#ifdef UKUI_WINDOWHELPER_SUPPORT
    m_ukuiWindowHelper = new UkuiWindowHelper(this);
    m_ukuiWindowHelper->removeTitleBar();
    // AI 助手在任务栏有常住入口后，需要跳过任务栏显示
    m_ukuiWindowHelper->setSkipTaskBar(true);

    //m_ukuiWindowHelper->setSlideEffect(UkuiWindowHelper::Position::Right);
    initTopping(); // 初始化置顶
#else
    connect(kdk::WindowManager::self(), &kdk::WindowManager::windowAdded, this, [=](const kdk::WindowId &window_id) {
        if(getpid() == kdk::WindowManager::getPid(window_id) && m_window_id == 0)
        {
            m_window_id = window_id.toULongLong();
            // 旧版窗管接口依赖kdk::WindowManager::windowAdded信号响应之后拿到窗口id
            initTopping(); // 初始化置顶
        }
    });
    kdk::UkuiStyleHelper::self()->removeHeader(this);
#endif

    initGlobalSetting();
    m_msgPane = new CMsgPane();

    initCtrl();

    initSolts();
    initLayout();

    initScribeWords();
    initScribeWordsSetting();

    initXeventMonitor();
    initPosition();
    initShortcut();

    checkTheme();

    initTimer();

    //初始化系统控制命令
    StartUpTools::getInstance()->initConfig();

    //设置窗口标题
    this->setWindowTitle(tr("kylin-aiassistant"));
    this->setWindowIcon(QIcon(QString(":/icon/icon/kylin-aiassistant.svg")));

}

CMainWnd::~CMainWnd()
{
    if(m_xeventMonitor)
    {
        m_xeventMonitor->freeXres();
        m_xeventMonitor->quit();
        m_xeventMonitor->wait();
    }
}

void CMainWnd::createAllChildWnd()
{
#define NEW_OBJECT(pObj, TYPE) \
    if(NULL == pObj)           \
    {                          \
        pObj = new TYPE(this); \
    }
    NEW_OBJECT(m_leftBtnWidget, QWidget);
    m_leftBtnWidget->setAccessibleName("kylin-aiassistant_QWidget_m_leftBtnWidget");
    NEW_OBJECT(m_btnSideBar, CPushButtonEx);
    m_btnSideBar->setAccessibleName("kylin-aiassistant_CPushButtonEx_m_btnSideBar");
    NEW_OBJECT(m_btnBack, QPushButton);
    m_btnBack->setAccessibleName("kylin-aiassistant_QPushButton_m_btnBack");
    NEW_OBJECT(m_btnStick, QPushButton);
    m_btnStick->setAccessibleName("kylin-aiassistant_QPushButton_m_btnStick");
    connect(m_btnStick, &QPushButton::clicked, this, &CMainWnd::slotToTop);

    NEW_OBJECT(m_dbusOperator, KADBusOperator);
    m_settingPage = new SettingDialog(this);
    // fix bug #301003 【需求33947】【AI助手】设置窗口支持拖拽调整大小，双击后窗口最大化
    // 问题描述：由于sdk KWidget嵌套KWidget的实现机制问题，直接通过构造函数setFixedSize会失效
    // 解决方案：为避免此问题，采用规避方案：1. 不在构造函数中调用setFixedSize，改为在对象创建后设置固定大小 2. 在构造函数中首先调用resize，否则获取宽高时会出现问题
    m_settingPage->setFixedSize(744, 460);
    m_settingPage->setAccessibleName("kylin-aiassistant_SettingDialog_m_settingPage");
    SettingDialog::sharedInstance = m_settingPage;

    NEW_OBJECT(m_btnOccupiedMode, QPushButton);
    NEW_OBJECT(m_mainQml, QQuickWidget);
    NEW_OBJECT(m_closeModeWidget,CloseModeWidget);


    return;
}

void CMainWnd::initCtrl()
{
    //禁止父窗口样式影响子控件样式
    setAttribute(Qt::WA_StyledBackground);
    //设置主窗体颜色，修改this->palette可能会导致其他问题，bug #I9QUZV
    QPalette pale;
    pale.setColor(QPalette::Base, QColor("#F5F5F5"));
    this->setPalette(pale);
    //焦点不在窗口上时鼠标悬浮可显示tooltips
    this->setAttribute(Qt::WA_AlwaysShowToolTips);

    // 按照设计稿设计，窗口按钮大小为 32x32
    m_btnSideBar->setFixedSize(32, 32);
    m_btnSideBar->setIcon(QIcon(QString(":/icon/icon/window.svg")));
    m_btnSideBar->setIconSize(QSize(16, 16));
    m_btnSideBar->setProperty("isWindowButton", 0x1);
    m_btnSideBar->setProperty("useIconHighlightEffect", 0x2);
    m_btnSideBar->setProperty("windowMode", WINDOW_MODE_NORMAL);
    m_btnSideBar->setFlat(true);
    m_btnSideBar->setToolTip(tr("sidebar"));

    m_btnBack->setFixedSize(32, 32);
    m_btnBack->setIcon(QIcon(QString(":/icon/icon/back.svg")));
    m_btnBack->setIconSize(QSize(16, 16));
    m_btnBack->setProperty("isWindowButton", 0x1);
    m_btnBack->setProperty("useIconHighlightEffect", 0x2);
    m_btnBack->setProperty("windowMode", WINDOW_MODE_NORMAL);
    m_btnBack->setFlat(true);
    m_btnBack->setVisible(false);
    m_btnBack->setToolTip(tr("Back to homepage"));


    QHBoxLayout *leftBtnLayout = new QHBoxLayout;
    leftBtnLayout->setContentsMargins(6, 0, 0, 0);
    leftBtnLayout->addWidget(m_btnSideBar);
    leftBtnLayout->addWidget(m_btnBack);
    leftBtnLayout->setSpacing(0);
    leftBtnLayout->addSpacerItem(new QSpacerItem(20,20,QSizePolicy::Expanding,QSizePolicy::Minimum));
    m_leftBtnWidget->setFixedSize(70, 32);
    m_leftBtnWidget->setLayout(leftBtnLayout);

    // 按照设计稿设计，置顶按钮大小为 32x32
    m_btnStick->setFixedSize(32, 32);
    m_btnStick->setProperty("isWindowButton", 0x1);
    m_btnStick->setProperty("useIconHighlightEffect", 0x2);
    m_btnStick->setFlat(true);
    m_btnStick->setIcon(QIcon::fromTheme("ukui-fixed-symbolic"));
    m_btnStick->setToolTip(tr("fixed"));
    m_btnStick->setFocusPolicy(Qt::NoFocus);
    m_btnStick->setVisible(true);

    m_btnOccupiedMode->setFixedSize(32, 32);
    m_btnOccupiedMode->setProperty("isWindowButton", 0x1);
    m_btnOccupiedMode->setProperty("useIconHighlightEffect", 0x2);
    m_btnOccupiedMode->setProperty("windowMode", WINDOW_MODE_NORMAL);
    m_btnOccupiedMode->setFlat(true);
    m_btnOccupiedMode->setIcon(QIcon(QString(":/icon/icon/sideBySideDisplay.svg")));
    m_btnOccupiedMode->setToolTip(tr("Parallel display"));
    m_btnOccupiedMode->setFocusPolicy(Qt::NoFocus);
    m_btnOccupiedMode->setVisible(false);

    //标题栏菜单
    QMenu *menuConfig = new QMenu(this);
    menuConfig->setAccessibleName("kylin-aiassistant-QMenu_menuConfig");
    windowButtonBar()->menuButton()->setMenu(menuConfig);

    QActionGroup * actGroup = new QActionGroup(this);
    actGroup->setExclusive(true);
    int winMode = g_configManager->getConfigValue("win-mode").toInt();
    //视图模式
    QMenu * viewMode = new QMenu;
    viewMode->setAccessibleName("kylin-aiassistant-QMenu_viewMode");
    viewMode->menuAction()->setText(tr("ViewModel"));
    QAction * sidebarMode = new QAction(tr("SidebarMode"), this);
    sidebarMode->setCheckable(true);
    if(winMode == WINDOW_MODE_SIDEMODE){
        sidebarMode->setChecked(true);
    }
    actGroup->addAction(sidebarMode);
    connect(sidebarMode, &QAction::triggered, this, &CMainWnd::switchToSideMode);



    QAction * wndMode = new QAction(tr("WindowMode"), this);
    wndMode->setCheckable(true);
    if(winMode == WINDOW_MODE_WINDOWMODE){
        wndMode->setChecked(true);
    }
    actGroup->addAction(wndMode);
    connect(wndMode, &QAction::triggered, this, &CMainWnd::switchToWindowMode);

    viewMode->addActions(actGroup->actions());

    //根据主题版本判断是否开启大窗口模式切换入口
    menuConfig->addMenu(viewMode);

    //设置
    confAction = new QAction(tr("Setting"), this);
    menuConfig->addAction(confAction);

    //帮助
    QAction * helpAct = new QAction(tr("Help"), this);
    //2412 产品要求隐藏帮助按钮
    menuConfig->addAction(helpAct);
    connect(helpAct, &QAction::triggered, this, &CMainWnd::onShowHelp);
    QShortcut *shortcut = new QShortcut(QKeySequence(Qt::Key_F1), this);
    connect(shortcut, &QShortcut::activated, this, &CMainWnd::onShowHelp);

    //关于
    QAction * aboutAct = new QAction(tr("About"), this);
    menuConfig->addAction(aboutAct);
    connect(aboutAct, &QAction::triggered, this, &CMainWnd::onShowAbout);

    //退出
    QAction *act_exit = new QAction(tr("Exit"), this);
    menuConfig->addAction(act_exit);
    connect(act_exit, &QAction::triggered, this, &CMainWnd::onExitActionTriggled);

    // qml主页面
    m_mainQml->rootContext()->setContextProperty("globals",Globals::getinstance());
    m_mainQml->rootContext()->setContextProperty("msgPane",m_msgPane);
    m_mainQml->rootContext()->setContextProperty("commandTemplateListModel", CommandTemplateList::getInstance());
    //注册可用模型列表到qml中
    m_mainQml->rootContext()->setContextProperty("modelItemModel", ModelItemListModel::getInstance());
    m_mainQml->setSource(QUrl(QStringLiteral("qrc:/qml/qml/LoadImage.qml")));
    // 监听全局焦点变化
    connect(qApp, &QApplication::focusChanged, this, &CMainWnd::onFocusChanged);

    m_addFileMenu = new QMenu(this);
    m_addFileMenu->setAccessibleName("kylin-aiassistant-QMenu_addFileMenu");
    m_addFileMenu->setFixedWidth(128);
    QAction *addImageAct = m_addFileMenu->addAction(QIcon(":/icon/icon/addImage.svg"), tr("Add Image"));
    QAction *addFileAct = m_addFileMenu->addAction(QIcon(":/icon/icon/addFile.svg"), tr("Add File"));

    connect(m_msgPane, &CMsgPane::sigShowAddFileMenu, this, &CMainWnd::onShowAddFileMenu);
    connect(m_addFileMenu, &QMenu::aboutToHide, this, &CMainWnd::onAddFileMenuAboutToHide);
    connect(addImageAct, &QAction::triggered, this, [this](){
        qInfo() << "add image selected";
        this->onOpenFile(1);
    });
    connect(addFileAct, &QAction::triggered, this, [this](){
        qInfo() << "add document selected";
        this->onOpenFile(2);
    });

}

void CMainWnd::onShowAddFileMenu()
{
    // 获取主窗口的位置
    QRect geometry = this->geometry();
    int x = geometry.x();
    int y = geometry.y();

    // 计算固定位置
    int menuX = x + this->width() - 134;
    int menuY = y + this->height() - 152;

    m_addFileMenu->exec(QPoint(menuX, menuY));
    onAddFileMenuAboutToHide();
}

void CMainWnd::onAddFileMenuAboutToHide()
{
    qInfo() << "add file menu is about to hide";
    Q_EMIT m_msgPane->sigAddFileMenuHide();

}

void CMainWnd::initSolts()
{
    connect(confAction, SIGNAL(triggered()), this, SLOT(onConfActionTriggered()));

    connect(m_dbusOperator, &KADBusOperator::sigSetup, [this] {
        onConfActionTriggered();
    });
    connect(m_msgPane, &CMsgPane::sigSetup, [this] {
        onConfActionTriggered();
    });

    connect(m_btnSideBar, &QPushButton::clicked, this, &CMainWnd::onSideBarBtnClicked);

    connect(m_btnBack, &QPushButton::clicked, this, &CMainWnd::onBackBtnClicked);

    connect(m_msgPane,&CMsgPane::showPage,this,&CMainWnd::onPageChanged);

    connect(m_msgPane, &CMsgPane::sigLoadMyMessageBox, this, &CMainWnd::onShowCustomMessageBox);

    // 当聊天界面保存了历史会话到文件，则需要通知历史会话界面更新。
//    connect(m_msgPane, SIGNAL(sigSaveDialog(QString)), m_sideBar, SLOT(onSaveDialog(QString)));

    // 点击插件的时候需要加载对应插件的历史会话界面。
//    connect(m_sideBar, SIGNAL(sigPluginItemClicked(QString)), m_msgPane, SLOT(loadPlugin(QString)));

    connect(m_btnOccupiedMode, &QPushButton::clicked, this, &CMainWnd::onWindowModeButtonClicked);

    connect(this, &CMainWnd::sigThemeChanged, m_settingPage, &SettingDialog::onThemeChanged);
    connect(m_msgPane,&CMsgPane::showSettingPage,this,&CMainWnd::onConfActionTriggered);


    connect(m_settingPage, &SettingDialog::sigSetCloudModel, m_msgPane, &CMsgPane::onSetCloudModel);


    // 连接信号与槽
   connect(m_msgPane, &CMsgPane::activateMainWindowSignal, this, &CMainWnd::onActivateMainWindow);
   connect(m_msgPane, &CMsgPane::sigSaveAs, this, &CMainWnd::onSaveAs);
   connect(m_msgPane, &CMsgPane::sigOpenFile, this, &CMainWnd::onOpenFile);

   //展示用户手册
   connect(m_msgPane, &CMsgPane::sigCheckIntroduction, this, &CMainWnd::checkIntroduction);


   connect(m_closeModeWidget,&CloseModeWidget::sigHideCurrentApp,this,[&](){
       this->hide();
   });
   connect(m_closeModeWidget,&CloseModeWidget::sigCurrentCloseMode,m_settingPage,&SettingDialog::slUpdateCloseMode);
   connect(m_closeModeWidget,&CloseModeWidget::rejected,this,[&](){
       isCloseBoxOpen = false;
   });

   connect(m_msgPane, &CMsgPane::chatInitCompleted, this, [&](){
       m_mainQml->setSource(QUrl(QStringLiteral("qrc:/qml/qml/main.qml")));
       isChatInitCompleted = true;
       Q_EMIT m_msgPane->sigCheckIntroduction();
       // 解决窗口模式切换初始化加载出错问题
       int winMode = g_configManager->getConfigValue("win-mode").toInt();
       if (winMode == 2) {
           switchToSideMode();
       } else if (winMode == 3) {
           switchToWindowMode();
       } else {
           switchToSideMode();
       }
       m_msgPane->stopLoadTimer();
   });

    return;
}
void CMainWnd::initLayout()
{

    QHBoxLayout *layoutRMain = new QHBoxLayout(baseBar());
    layoutRMain->addWidget(m_mainQml);
    layoutRMain->setSpacing(0);
    layoutRMain->setMargin(0);
    layoutRMain->setContentsMargins(0, 0, 0, 0);

    KWindowButtonBar *button_bar = windowButtonBar();
    button_bar->maximumButton()->hide();
    button_bar->minimumButton()->hide();
//    connect(button_bar->minimumButton(), &QPushButton::clicked, []() {
//        isMinimizeClicked = true;
//        KyInfo() << "最小化按钮被点击";
//    });

    disconnect(button_bar->closeButton(), &QPushButton::clicked, 0, 0);
    connect(button_bar->closeButton(), &QPushButton::clicked, this,[&](){
        bool isHideTray = g_configManager->getConfigValue("is-hide-tray").toBool();
        KyInfo() << "====mainwnd closebutton clicked====isHideTray:" << isHideTray;
        if(isHideTray){
            this->hide();
        } else {
            this->close();
        }
    });

    ((QHBoxLayout *)button_bar->layout())->insertWidget(0, m_leftBtnWidget);
//    ((QHBoxLayout *)button_bar->layout())->insertWidget(0, m_btnBack);
//    ((QHBoxLayout *)button_bar->layout())->insertWidget(1, m_btnSideBar);
    //根据主题版本去判断是否启用独占模式
    ((QHBoxLayout *)button_bar->layout())->insertWidget(2, m_btnOccupiedMode);
//    if(!isSupportWindowMode)
//       m_btnOccupiedMode->setVisible(false);
    ((QHBoxLayout *)button_bar->layout())->insertWidget(3, m_btnStick);

    KIconBar *iconbar = iconBar();
    iconbar->setFixedWidth(200);
    iconbar->setIcon(QIcon(QString(":/icon/icon/kylin-aiassistant.svg")));
    iconbar->setWidgetName(tr("kylin-aiassistant"));
    iconbar->setStyleSheet("background-color: white;");  // 用palette不生效
    iconbar->setVisible(false);

    //窗口模式存在抖动现象，后续解决
    m_mainQml->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView);
    int winMode = g_configManager->getConfigValue("win-mode").toInt();
    if(winMode == 2){
        switchToSideMode();
    }else if (winMode == 3){
        switchToWindowMode();
    }else{
        switchToSideMode();
    }

    //关于窗口初始化
    appVersion = getAiAssistantVersion();
    aboutWindow = new kdk::KAboutDialog(this,
       QIcon(QString(":/icon/icon/kylin-aiassistant.svg")),
       tr(appShowingName.toLocal8Bit()),
       tr("Version: ") + appVersion /*APP_VERSION*/
    );
    aboutWindow->setAccessibleName("kylin-aiassistant_kdk::KAboutDialog_aboutWindow");
    aboutWindow->setBodyText(tr("kylin-aiassistant is a tool to help users..."));
    aboutWindow->setBodyTextVisiable(false);
}

void CMainWnd::switchToSideMode()
{
    KyInfo() << "=======switchToSideMode====";
    Q_EMIT m_msgPane->changeWinModeToChat(2);

    // 将页面大小和页面切换前置，解决页面切换滞后性
    QRect screenRect = QGuiApplication::primaryScreen()->availableGeometry();
        //通过信号实现控制前端页面大小
    Q_EMIT m_msgPane->changeToSideMode(SIDEBAR_WIDTH, screenRect.height() - windowButtonBar()->height() - 2 * WINDOW_MARGIN);

    //根据活跃模块内容切换到对应显示界面
    ActiveModule module = m_msgPane->getCurrentActiveModule();
    if(ActiveModule::MODULE_PLUGIN == module)
    {
        Q_EMIT m_msgPane->showPage(2);
    }
    else if(ActiveModule::MODULE_CHAT == module)
    {
        Q_EMIT m_msgPane->showPage(0);
    }

    m_isMouseDragMove = false; //恢复窗口不触发移动记住位置
    m_msgPane->m_windowMode = WINDOW_MODE_SIDEMODE;
    g_configManager->updateNonCriticalConfig("win-mode", WINDOW_MODE_SIDEMODE);
//    slotToTopChangeWinMode();

    //根据主题版本去判断是否启用该接口
    if(isSupportWindowMode){
        setMovable(false);
//        m_btnOccupiedMode->setVisible(true);
    }

    iconBar()->setVisible(false);
//    m_btnStick->setVisible(false);
    m_btnSideBar->setVisible(true);

    setFixedSize(SIDEBAR_WIDTH, screenRect.height() - 2 * WINDOW_MARGIN );
    KyInfo() << "====primaryScreen====" << QGuiApplication::primaryScreen()->name() << "=======availableGeometry====height" << screenRect.height();

    KyInfo() << "=======setGeometry====availableGeometry.right" << screenRect.right() << "availableGeometry.top" << screenRect.top() << "availableGeometry.height" << screenRect.height();
    this->setGeometry(QRect(screenRect.right() - SIDEBAR_WIDTH - WINDOW_MARGIN, screenRect.top() + WINDOW_MARGIN, SIDEBAR_WIDTH, screenRect.height()));

    // 恢复侧边模式是否独占
    int windowMode = WINDOW_MODE_NORMAL;
    QVariant value = m_btnOccupiedMode->property("windowMode");
    if(value.isValid() && value.type() == QVariant::Int)
    {
        windowMode = value.toInt();

    }
    if(windowMode == WINDOW_MODE_NORMAL)
    {
        //是否独占
        bool isAbreast = g_configManager->getConfigValue("is-side-mode-abreast").toBool();
        if(isAbreast){
            changeToOccupiedMode();
            m_btnOccupiedMode->setIcon(QIcon(QString(":/icon/icon/overlayDisplay.svg")));
            m_btnOccupiedMode->setProperty("windowMode", WINDOW_MODE_OCCUPIED);
            m_btnOccupiedMode->setToolTip(tr("Overlay display"));
        }else{
            changeToNormalMode();
            m_btnOccupiedMode->setIcon(QIcon(QString(":/icon/icon/sideBySideDisplay.svg")));
            m_btnOccupiedMode->setProperty("windowMode", WINDOW_MODE_NORMAL);
            m_btnOccupiedMode->setToolTip(tr("Parallel display"));
        }
    }

}

void CMainWnd::switchToWindowMode()
{
    KyInfo() << "=======switchToWindowMode====";
    Q_EMIT m_msgPane->changeWinModeToChat(3);

    // 将页面大小和页面切换前置，解决页面切换滞后性
    // 根据活跃模块内容并进行对应的显示
    ActiveModule module = m_msgPane->getCurrentActiveModule();
    if(ActiveModule::MODULE_PLUGIN == module)
    {
        Q_EMIT m_msgPane->showPage(4);
    }
    else if(ActiveModule::MODULE_CHAT == module)
    {
        Q_EMIT m_msgPane->showPage(4);
    }
    Q_EMIT m_msgPane->changeToWinMode(568 - windowButtonBar()->height());

    m_isMouseDragMove = false; //恢复窗口不触发移动记住位置
    m_msgPane->m_windowMode = WINDOW_MODE_WINDOWMODE;
    int windowMode = WINDOW_MODE_NORMAL;
    g_configManager->updateNonCriticalConfig("win-mode", WINDOW_MODE_WINDOWMODE);
//    slotToTopChangeWinMode();
    QVariant value = m_btnOccupiedMode->property("windowMode");
    if(value.isValid() && value.type() == QVariant::Int)
    {
        windowMode = value.toInt();

    }
    if(windowMode == WINDOW_MODE_OCCUPIED)
    {
        changeToNormalMode();
        m_btnOccupiedMode->setIcon(QIcon(QString(":/icon/icon/sideBySideDisplay.svg")));
        m_btnOccupiedMode->setProperty("windowMode", WINDOW_MODE_NORMAL);
        m_btnOccupiedMode->setToolTip(tr("Parallel display"));
    }
    //根据主题版本去判断是否启用该接口
    if(isSupportWindowMode){
        setMovable(true);
//        m_btnOccupiedMode->setVisible(false);
    }

    iconBar()->setVisible(true);
//    m_btnStick->setVisible(true);
    m_btnSideBar->setVisible(false);
    m_btnBack->setVisible(false);

    QRect screenRect = QGuiApplication::primaryScreen()->availableGeometry();
    setMinimumSize(768, 568);
    setMaximumSize(16777215, 16777215);

    int length = g_configManager->getConfigValue("window-mode-length").toInt();
    int wide = g_configManager->getConfigValue("window-mode-wide").toInt();
    resize(length, wide);

    //Q_EMIT m_msgPane->showPage(4);

    //窗口在屏幕居中
    //    setGeometry((screenRect.width() - this->width()) / 2 , (screenRect.height() - this->height()) / 2, this->width(), this->height());
    int x = g_configManager->getConfigValue("window-mode-x").toInt();
    int y = g_configManager->getConfigValue("window-mode-y").toInt();
    if(x < 0){
        this->setGeometry(QRect((screenRect.width() - this->width()) / 2 , (screenRect.height() - this->height()) / 2, this->width(), this->height()));
    }else{
        this->setGeometry(QRect(x , y, this->width(), this->height()));
    }
}

void CMainWnd::initTrayIcon()
{
    // 系统托盘
    m_trayIcon = new QSystemTrayIcon(this);
    m_trayIcon->setObjectName("kylin-aiassistant_QSystemTrayIcon_m_trayIcon");
    m_trayIcon->setToolTip(QString(tr("AI Assistant")));
    m_trayIcon->setIcon(QIcon(QString(":/icon/icon/kylin-aiassistant.svg")));

    connect(m_trayIcon, &QSystemTrayIcon::activated, this, &CMainWnd::onTrayIconActivated);
    m_trayIcon->show();
}

void CMainWnd::initTrayIconMenu()
{
    m_trayIconMenu = new QMenu();
    m_trayIconMenu->setAccessibleName("kylin-aiassistant_QMenu_m_trayIconMenu");
    QAction * quitAction =  new QAction(tr("Quit"));
    connect(quitAction, &QAction::triggered, [&](){
        exit(0);
    });
    m_trayIconMenu->addAction(quitAction);
    m_trayIcon->setContextMenu(m_trayIconMenu);
}

void CMainWnd::initScribeWords()
{
    m_selectwid = new SelectWidget;
    m_selectwid->setAccessibleName("kylin-aiassistant_SelectWidget_m_selectwid");

#ifdef UKUI_WINDOWHELPER_SUPPORT
    UkuiWindowHelper *ukuiWindowHelper = new UkuiWindowHelper(this);
    ukuiWindowHelper->removeTitleBar();
#else
    kdk::UkuiStyleHelper::self()->removeHeader(this);
#endif

    m_selectclip = new Clipboard;
    m_selectclip->setObjectName("kylin-aiassistant_Clipboard_m_selectclip");
    selectTimer  = new QTimer;
    selectTimer->setInterval(30);
    connect(selectTimer,&QTimer::timeout,this,&CMainWnd::onStartSendSelectMsg,Qt::UniqueConnection);
    connect(m_msgPane, &CMsgPane::copyToClipboard, m_selectclip, &Clipboard::setText);
//    connect(m_msgPane, &CMsgPane::copyToClipboard, [=](){
//        TipWidget::showTip(tr("Copy Successful"), 3000, QSize(120, 48), this, TipWidget::OK);
//    });
    connect(m_msgPane, &CMsgPane::copyToClipboard, [=](){
        m_msgPane->showTip(tr("Copy Successful"));
    });
//    connect(m_msgPane, &CMsgPane::copyImageToClipboard, [=](){
//        TipWidget::showTip(tr("Copy Successful"), 3000, QSize(120, 48), this, TipWidget::OK);
//    });
    connect(m_msgPane, &CMsgPane::copyImageToClipboard, [=](){
        m_msgPane->showTip(tr("Copy Successful"));
    });

    connect(m_msgPane, &CMsgPane::copySuccess, [=](){
        m_msgPane->showTip(tr("Copy Successful"));
    });
    connect(m_msgPane, &CMsgPane::tipsContinueDialog, [=](){
        TipWidget::showTip(tr("Dialogue is being generated, please try again later"), 3000, QSize(120, 48), this, TipWidget::WARNING);
    });
//    connect(m_msgPane, &CMsgPane::sigLikeAction, [=](){
//        TipWidget::showTip(tr("Thanks for your feedback"), 3000, QSize(120, 48), this, TipWidget::OK);
//    });
    connect(m_msgPane, &CMsgPane::sigLikeAction, [=](){
        m_msgPane->showTip(tr("Thanks for your feedback"));
    });
    connect(m_selectwid, &SelectWidget::sigbuttontext, this, &CMainWnd::handleClicpText);
    connect(m_selectwid, &SelectWidget::signalSendClicpText, this, &CMainWnd::handleClicpText);
    connect(m_selectwid, &SelectWidget::sigHomePageShow, this, [=]() {

        showView();
        m_selectwid->hide();
    });
    connect(m_selectwid, &SelectWidget::sigSettingShow, this, [=]() {
        onConfActionTriggered();
        m_selectwid->hide();
    });
    connect(m_selectwid, &SelectWidget::sigDisableScribe, this, [=]() {
        KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
        kdk_dia_upload_default(node, "send_disable_scribe_words_click_event", "scribeWordsPage");
        kdk_dia_data_free(node);

        //关闭划词界面
        m_selectwid->hide();
        g_configManager->updateConfig("is-stroke-word", false);
        //设置界面关闭划词按钮
        if(m_settingPage)
        {
            m_settingPage->scribeWordsDisabled();
        }


    });
}

void CMainWnd::initScribeWordsSetting()
{
    // 点击是否禁用划词按钮
    connect(m_settingPage, &SettingDialog::sigEnableScribeWords, this,[=]{
         g_configManager->updateConfig("is-stroke-word", true);
    });
    connect(m_settingPage, &SettingDialog::sigDisableScribeWords, this, [=]() {
        KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
        kdk_dia_upload_default(node, "send_setting_disable_scribe_words_button_click_event", "scribeWordsPage");
        kdk_dia_data_free(node);

        m_selectwid->hide();
        g_configManager->updateConfig("is-stroke-word", false);
    });
}

void CMainWnd::handleClicpText()
{
    QString buttonText = m_selectwid->getButtonText();
    QString clipText = m_selectclip->getClipText();
    int promptId = m_selectwid->getCurrentId();
    QString promptIconPath = CommandTemplateList::getInstance()->getPromptIconHighlightpath(promptId);
    if(clipText != "")
    {
        bool isEnd = m_msgPane->getIsEnd();
        if(!isEnd) //如果回答未结束则打断回答并启动计时器查询是否结束
        {
            m_msgPane->onStopReply();
            selectTimer->start();
        }
        else
        {
            QJsonObject jsonObjToWeb;
            jsonObjToWeb["msgHead"] = buttonText;
            jsonObjToWeb["promptId"] = promptId;
            jsonObjToWeb["promptIconPath"] = promptIconPath;
            QJsonDocument aiJsonSendWebDoc(jsonObjToWeb);
            QString jsonMsgHeadToWeb = aiJsonSendWebDoc.toJson(QJsonDocument::Indented);
            m_msgPane->onStartReplyingToChat();// 划词更新前端isReplying状态为true
            m_msgPane->onSendMsg(jsonMsgHeadToWeb, clipText);
            Q_EMIT m_msgPane->moveScrollBar();
        }
    }
    showView();
    int curWinMode = m_msgPane->getCurWinMode();
    if(curWinMode == 2)
    {
        m_msgPane->showPage(1);
    }
    else if (curWinMode == 3)
    {
        m_msgPane->showPage(4);
    }
    Q_EMIT m_msgPane->moveScrollBar();
    Q_EMIT m_msgPane->sigClearTextArea();
    m_selectwid->hide();
}

void CMainWnd::onStartSendSelectMsg()
{
    QString buttonText = m_selectwid->getButtonText();
    QString clipText = m_selectclip->getClipText();
    int promptId = m_selectwid->getCurrentId();
    bool currentEnd =  m_msgPane->getIsEnd();
    QString promptIconPath = CommandTemplateList::getInstance()->getPromptIconHighlightpath(promptId);
    if(currentEnd)
    {
        QJsonObject jsonObjToWeb;
        jsonObjToWeb["msgHead"] = buttonText;
        jsonObjToWeb["promptId"] = promptId;
        jsonObjToWeb["promptIconPath"] = promptIconPath;
        QJsonDocument aiJsonSendWebDoc(jsonObjToWeb);
        QString jsonMsgHeadToWeb = aiJsonSendWebDoc.toJson(QJsonDocument::Indented);
        m_msgPane->onStartReplyingToChat();// 划词更新前端isReplying状态为true
        m_msgPane->onSendMsg(jsonMsgHeadToWeb, clipText);
        Q_EMIT m_msgPane->moveScrollBar();
        selectTimer->stop();
    }
    showView();
    int curWinMode = m_msgPane->getCurWinMode();
    if(curWinMode == 2)
    {
        m_msgPane->showPage(1);
    }
    else if (curWinMode == 3)
    {
        m_msgPane->showPage(4);
    }
    Q_EMIT m_msgPane->moveScrollBar();
    m_selectwid->hide();

}

void CMainWnd::onShotCutActionTriggled() { }

void CMainWnd::onAboutActionTriggled() { }

void CMainWnd::onExitActionTriggled()
{
    // QCoreApplication::quit();
    close();
}

void CMainWnd::onTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
{
    KyInfo() << "QSystemTrayIcon::ActivationReason" << reason;
    KyInfo() << "isHidden:" << this->isHidden()
             << "isMinimized" << this->isMinimized()
             << "isVisible" << this->isVisible()
             << "isMinimizeClicked" << isMinimizeClicked;

    if (reason == QSystemTrayIcon::DoubleClick || reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::MiddleClick) {
        KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
        kdk_dia_upload_default(node, "system_tray_icon_click_event", "systemTrayIcon");
        kdk_dia_data_free(node);

        bool isMinimizedState = this->isMinimized() || isMinimizeClicked;

        if (this->isVisible()) {
            if (isMinimizedState) {
                showView(); // 可见且最小化
            } else {
                hideView();
            }
        } else {
            showView();
        }
    }

}

void CMainWnd::onAppRestarted(const QString &message)
{
    KyInfo() << "====onAppRestarted====message" << message;
    if (message == "selected") {
        if(!this->isVisible()){
            showView();
        }
        onShowScribeWord();
    } else if (message == "running") {
        // 如果AI助手窗口被遮挡，则执行show操作，将窗口置于顶层
        if (!this->isActiveWindow()){
            showView();
        }else {
            showOrHideWindow();
        }
    } else {//当做文件路径处理
        if (!this->isActiveWindow()) {
            showView();
        }

        QUrl url(message);
        QString filePath = url.path();
        QFileInfo fileInfo(filePath);
        if (g_supportPicFormats.contains(fileInfo.suffix().toLower())) {
            m_msgPane->onShowImage(filePath, 1);
        } else if (g_supportDocFormats.contains(fileInfo.suffix().toLower())) {
            m_msgPane->onShowDocument(filePath);
        }
    }

}

void CMainWnd::closeEvent(QCloseEvent *e)
{
    e->accept();
    return;
}

void CMainWnd::resizeEvent(QResizeEvent *event)
{
    // 重写 resizeEvent 方法以监听窗口大小变化
    QWidget::resizeEvent(event); // 调用基类方法
    // 在这里记录新的大小值
    // 例如，保存到成员变量或文件中
    int winMode = g_configManager->getConfigValue("win-mode").toInt();
    if(winMode == 3){
        resizeTimer->stop();
        resizeTimer->start(100); // 设置一个短暂的延迟，比如100毫秒
    }
}

void CMainWnd::moveEvent(QMoveEvent *event)
{
    //QWidget::moveEvent(event); // 调用基类方法
    int winMode = g_configManager->getConfigValue("win-mode").toInt();
    if(winMode == 3 || winMode == 2){
        //KyInfo() << "=================qqqqq";
        moveTimer->stop();
        moveTimer->start(100); // 设置一个短暂的延迟，比如100毫秒
        //event->accept();
        KWidget::moveEvent(event);
    }
}

void CMainWnd::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
        // 处理回车键的事件
        //KyInfo() << "Enter key pressed!";
        m_msgPane->keyReturnPressed();
    }

    // 调用基类的 keyPressEvent()，以便处理其他按键事件
    KWidget::keyPressEvent(event);
}

bool CMainWnd::eventFilter(QObject *obj, QEvent *event) {
    if (event->type() == QEvent::MouseButtonPress) {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
        if (mouseEvent->button() == Qt::LeftButton) {
            m_msgPane->sendFocusChanged();
        }
    }
    return QWidget::eventFilter(obj, event);
}

void CMainWnd::showView()
{
    this->activateWindow();
    //KWindowSystem::forceActiveWindow(m_window_id);

    KyInfo() << "force Active Window";

    this->show();
    this->raise();
    this->activateWindow();

    if(g_configManager->getConfigValue("is-first-install").toBool() == true && isChatInitCompleted == true && m_introductionView == nullptr){
        QTimer::singleShot(300, this, [=](){
            IntroductionView *introductionDialog = new IntroductionView(this);
            m_introductionView = introductionDialog;
            connect(introductionDialog,&IntroductionView::showSettingPage,this,&CMainWnd::onConfActionTriggered);
            connect(introductionDialog,&IntroductionView::openUKUIControlCenterView,m_msgPane,&CMsgPane::openUkuiControlCenter);
            int posX = this->x() + (this->width() - introductionDialog->width()) / 2;
            int posY = this->y() + (this->height() - introductionDialog->height()) / 2;
            introductionDialog->move(posX,posY);
            if(isWayland){
                KyInfo() << "IntroductionView showView isWayland";
                introductionDialog->setGeometry(QRect(posX, posY, introductionDialog->width(), introductionDialog->height()));
            }
            introductionDialog->exec();
            m_introductionView = nullptr;
        });
    } else if (m_settingPage != nullptr && isSettingOpen == true) {
        showSettingPage();
    }

    isMinimizeClicked = false;

    m_mainQml->setFocus();
    Q_EMIT m_msgPane->sigActiveTextArea();

    KyInfo() << "showView end";

    return;
}

void CMainWnd::hideView()
{
    KyInfo() << "hideView";
    if((m_settingPage != nullptr && isSettingOpen == true) || isMsgBoxOpen || isCloseBoxOpen || (aboutWindow != nullptr && aboutWindow->isVisible()) || (m_introductionView != nullptr && m_introductionView->isVisible()))
    {
        return;
    }
    this->hide();
}

void CMainWnd::onFocusChanged(QWidget *oldWidget, QWidget *newWidget) {
    // 如果新窗口为空，说明 QWidget 失去焦点
    if (!newWidget) {
        m_msgPane->sendFocusChanged();
    }
}

void CMainWnd::slotToTop()
{
    qInfo() << "isTop " << m_isTop;

    if(!m_isTop){
        keepWindowAbove(true);
        m_isTop = true;
        g_configManager->updateConfig("is-window-mode-topping", true);
    }else{
        keepWindowAbove(false);
        m_isTop = false;
        g_configManager->updateConfig("is-window-mode-topping", false);
    }

    m_btnStick->setIcon(QIcon::fromTheme(m_isTop ? "ukui-unfixed-symbolic" : "ukui-fixed-symbolic"));
    m_btnStick->setToolTip(m_isTop ? tr("unfixed") : tr("fixed"));
}

void CMainWnd::slotToTopChangeWinMode()
{
    int curWinMode = m_msgPane->getCurWinMode();
    if(curWinMode == 2)
    {
        bool isTopping = g_configManager->getConfigValue("is-window-mode-topping").toBool();
        if(m_isTop){
            keepWindowAbove(true);
            m_isTop = true;
        }
    }
    else if (curWinMode == 3){        // 窗口模式
        bool isTopping = g_configManager->getConfigValue("is-window-mode-topping").toBool();
        if(isTopping){
            keepWindowAbove(true);
            m_isTop = true;
        }
    }
    m_btnStick->setIcon(QIcon::fromTheme(m_isTop ? "ukui-unfixed-symbolic" : "ukui-fixed-symbolic"));
    m_btnStick->setToolTip(m_isTop ? tr("unfixed") : tr("fixed"));
}

void CMainWnd::onWindowModeButtonClicked()
{
    int windowMode = WINDOW_MODE_NORMAL;
    QVariant value = m_btnOccupiedMode->property("windowMode");
    if(value.isValid() && value.type() == QVariant::Int)
    {
        windowMode = value.toInt();
    }

    if(windowMode == WINDOW_MODE_NORMAL)
    {
        changeToOccupiedMode();
        m_btnOccupiedMode->setIcon(QIcon(QString(":/icon/icon/overlayDisplay.svg")));
        m_btnOccupiedMode->setProperty("windowMode", WINDOW_MODE_OCCUPIED);
        m_btnOccupiedMode->setToolTip(tr("Overlay display"));
        g_configManager->updateConfig("is-side-mode-abreast", true);
        return;
    }

    changeToNormalMode();
    m_btnOccupiedMode->setIcon(QIcon(QString(":/icon/icon/sideBySideDisplay.svg")));
    m_btnOccupiedMode->setProperty("windowMode", WINDOW_MODE_NORMAL);
    m_btnOccupiedMode->setToolTip(tr("Parallel display"));
    g_configManager->updateConfig("is-side-mode-abreast", false);

    return;
}

void CMainWnd::onSideBarBtnClicked()
{
    ActiveModule activateModule = m_msgPane->getCurrentActiveModule();

    if (activateModule == ActiveModule::MODULE_PLUGIN) {
        // 当前在侧边栏
        if (m_previousModule == ActiveModule::MODULE_CHAT) {
            // KyInfo() << "返回助手主页";
            Q_EMIT m_msgPane->showPage(1);
        }

    } else {
        Q_EMIT m_msgPane->cancelVoiceStopReplying();//停止语音更新状态
        Q_EMIT m_msgPane->cancelSendAudio();//停止语音恢复UI
        // 切换到侧边栏
        m_previousModule = activateModule;
        Q_EMIT m_msgPane->showPage(2);
    }

    return;
}

void CMainWnd::onBackBtnClicked()
{
    m_msgPane->onBackBtnClicked();
}

void CMainWnd::onPageChanged(const int pageNumber)
{
    //在主页和侧边栏时无需显示返回按钮
    if(pageNumber == 0 || pageNumber ==1 || pageNumber == 2 || pageNumber ==4)
    {
        m_btnBack->setVisible(false);
    }
    //在非侧边栏界面需要显示侧边栏按钮
    if(pageNumber == 0 || pageNumber == 1 )
    {
        m_btnSideBar->setVisible(true);
    }
    PageType newPage;
    //侧边栏模式控制前端显示页面 0显示全部 1显示主页面 2显示侧边栏 3显示会议助手界面 4窗口模式下显示主界面 5窗口模式下显示会议界面
    switch (pageNumber) {
    case 0:
        newPage = PageType::MAIN_PAGE_SIDEBAR_MODE;
        m_btnBack->setVisible(false);
        break;
    case 1:
        newPage = PageType::MAIN_PAGE_SIDEBAR_MODE;
        m_btnBack->setVisible(false);
        break;
    case 2:
        newPage = PageType::SHOW_SIDEBAR;
        break;
    case 4:
        newPage = PageType::MAIN_PAGE_WINDOW_MODE;
        m_btnBack->setVisible(false);
        break;
    default:
        newPage = PageType::MAIN_PAGE_SIDEBAR_MODE;
        m_btnBack->setVisible(false);
        break;
    }

    g_currentPage = newPage; // 更新全局页面状态

}

void CMainWnd::onShowCustomMessageBox(const QVariantList &strings) {
    //KyInfo() << "删除确认弹窗打开";
    CustomMessageBox msgBox(this);
    msgBox.setMessage(tr("After deleting the conversation, it cannot be restored. Do you want to continue deleting?"));
    msgBox.setButtons(CustomMessageBox::OkButton | CustomMessageBox::CancelButton);
    //窗口居中
    msgBox.move(this->x() + (this->width() - msgBox.width()) / 2 , this->y() + (this->height() - msgBox.height()) / 2);
    KyInfo() << "*********** msgBox : " <<msgBox.x() << "  " << msgBox.y();

    isMsgBoxOpen = true;
    if (msgBox.exec() == QDialog::Accepted) {
        if (msgBox.clickedButton() == CustomMessageBox::OkButton) {
            // 用户点击了删除按钮，执行删除操作
            m_msgPane->deleteSessionList(strings);
        }
        isMsgBoxOpen = false;
    } else {
        //KyInfo() << "cancelClick";
        m_msgPane->modifyDialogueList(strings);
        isMsgBoxOpen = false;
    }
}

void CMainWnd::onConfActionTriggered()
{
    showSettingPage();
    m_settingPage->resetIndex();
    isSettingOpen = true;
}

void CMainWnd::onCreateDialog()
{
    // 先保存当前会话
    m_msgPane->saveDialog();

    // 然后清除当前会话
    m_msgPane->clearDialog();

    // 隐藏历史会话界面
//    m_sideBar->hide();

    return;
}

void CMainWnd::initXeventMonitor()
{
    if(isWayland)
        return;
    if(!m_xeventMonitor)
    {
        m_xeventMonitor = new xEventMonitor;
        connect(m_xeventMonitor, SIGNAL(mousePress(int, int)), this, SLOT(onX11GlobalMousePress(int, int)), Qt::QueuedConnection);
//        connect(m_xeventMonitor, SIGNAL(mouseRelease(int, int)), this, SLOT(onX11GlobalMouseRelease(int, int)), Qt::QueuedConnection);
    }
}
void CMainWnd::onX11GlobalMousePress(int x, int y)
{
    int m_MouseClick_X = x / Globals::scaleFactor;
    int m_MouseClick_Y = y / Globals::scaleFactor;

    QRect geoRect = m_selectwid->geometry();
    if(!geoRect.contains(m_MouseClick_X, m_MouseClick_Y) && m_selectwid->isVisible() && !m_selectwid->isIncludeMenuPage(m_MouseClick_X,m_MouseClick_Y)
            && !m_selectwid->isIncludeMoreCommandWidget(m_MouseClick_X,m_MouseClick_Y))
    {
         m_selectwid->closeWidgetAndinstructPage(m_MouseClick_X, m_MouseClick_Y);
    }

    return;
}

void CMainWnd::showOrHideWindow()
{
    KyInfo() << "----showorhidewindow----isMinimizeClicked" << isMinimizeClicked << "----isMinimized----" << isMinimized();

    bool isMinimizedState = this->isMinimized() || isMinimizeClicked;

    if (this->isVisible()) {
        if (isMinimizedState) {
            showView(); // 可见且最小化
        } else {
            hideView();
        }
    } else {
        showView();
    }
}

void CMainWnd::onShowHelp()
{
    kdk::UserManual aiAssistantUserManual;
    if (!aiAssistantUserManual.callUserManual("kylin-aiassistant")) {
        qCritical() << "user manual call fail!";
    }
    return;
}

void CMainWnd::onShowAbout()
{
     aboutWindow->exec();
     return;
}

// 用于记录窗口大小改变后的值
void CMainWnd::onResizeEnd()
{
    int finalWidth = width();
    int finalHeight = height();
    //KyInfo() << "Final window size:" << finalWidth << "x" << finalHeight;
    g_configManager->updateConfig("window-mode-length", finalWidth);
    g_configManager->updateConfig("window-mode-wide", finalHeight);
//    g_gsettings->set("window-mode-length", 902);
//    g_gsettings->set("window-mode-wide", 568);
}

// 用于记录窗口位置改变后的值
void CMainWnd::onMoveEnd()
{
    int finalX = pos().x();
    int finalY = pos().y();
    //KyInfo() << "Final window position:" << finalX << "," << finalY;

    if(finalX < 0){
        finalX = 0;
    }
    if(finalY < 0){
        finalY = 0;
    }
    int curWinMode = m_msgPane->getCurWinMode();
    if(m_isMouseDragMove){
        if(curWinMode == 2)
        {
            g_configManager->updateConfig("side-mode-x", finalX);
            g_configManager->updateConfig("side-mode-y", finalY);
        }
        else if (curWinMode == 3){
            g_configManager->updateConfig("window-mode-x", finalX);
            g_configManager->updateConfig("window-mode-y", finalY);
        }
    }
    m_isMouseDragMove = true;
//    g_gsettings->set("window-mode-x", -1);
    //    g_gsettings->set("window-mode-y", -1);
}

void CMainWnd::onActivateMainWindow()
{
    this->activateWindow();
    this->setFocus();
}

void CMainWnd::onSaveAs(const QString &base64Image)
{
    bool ok = false;
    QPixmap pixmap;

    // 去掉前缀
    QStringList parts = base64Image.split(",");
    if(parts.length() == 2)
    {
        QString imageData = parts.at(1);
        QByteArray byteArray = QByteArray::fromBase64(imageData.toLocal8Bit());
        pixmap.loadFromData(byteArray);
    }
    if(pixmap.isNull())
    {
        KyInfo() << "pixmap is null";
        return;
    }

    // 获取当前时间
    QDateTime currentTime = QDateTime::currentDateTime();
    QString formattedTime = currentTime.toString("yyyyMMdd_hhmmss");
    // 使用格式化后的时间作为文件名
    QString fileName = "aiassistant_" + formattedTime + ".png";
    QString path = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).at(0);
    if(path.endsWith("/"))
    {
        path += fileName;
    }
    else
    {
        path += "/" + fileName;
    }

    //wayland环境下，构造函数必须加this， setModal(true)
    QFileDialog *fileDialog = new QFileDialog(this); // 设置窗口标题属性自定义
    fileDialog->setAccessibleName("kylin-aiassistant_QFileDialog_fileDialog");
    fileDialog->setModal(true);
    fileDialog->setNameFilter(QLatin1String("PNG(*.png);;JPE(*.jpe);;JPEG(*.jpeg);;JPG(*.jpg);;PBM(*.pbm);;PGM(*.pgm);;BMP(*.bmp);;PPM(*.ppm);;TIFF(*.tiff);;WEBP(*.webp)"));
    fileDialog->setDirectory(QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).at(0));
    fileDialog->setAcceptMode(QFileDialog::AcceptSave);
    fileDialog->selectFile(path);

    if(fileDialog->exec() == QFileDialog::Accepted)
    {
        QString savePath = fileDialog->selectedFiles().at(0);

        QFileInfo fileName = savePath;
        if(savePath.isNull())
        {
            return;
        }

        if(fileName.suffix().isNull())
        {
            savePath += QLatin1String(".png");
        }
        fileName = savePath;
        QString name = fileName.fileName();
        QString msg;
        QString message;
        if(!name.startsWith(QChar('.'), Qt::CaseInsensitive))
        {
            QFileInfo fileInfo(savePath);
            QStringList parts = base64Image.split(",");
            // 解码 Base64 字符串
            QByteArray decodedData;
            if(parts.length() == 2)
            {
                QString imageData = parts.at(1);
                decodedData = QByteArray::fromBase64(imageData.toLatin1());
            }
            if(fileInfo.suffix() == "jpeg"|| fileInfo.suffix() == "pgm"|| fileInfo.suffix() == "pbm" || fileInfo.suffix() == "ppm" || fileInfo.suffix() == "jpg"){
                // jpeg pgm pbm ppm jpg保存白色背景会填充黑色，额外处理，其中pgm pbm只支持黑白像素
                QImage originalImage;
                originalImage.loadFromData(decodedData);
                // 创建带有白色背景的新图像
                QImage newImage(originalImage.size(), QImage::Format_RGB32);
                newImage.fill(Qt::white);
                // 使用QPainter在新图像上绘制原图
                QPainter painter(&newImage);
                painter.drawImage(0, 0, originalImage);
                painter.end();
                // 保存图像
                if (newImage.save(savePath)) {
                    ok = true;
                } else {
                    ok = false;
                }
            }else if(fileInfo.suffix() == "jpe"){
                // 使用 QImage 加载解码后的数据
                // jpe保存会报错，额外处理
                QImage img;
                if (img.loadFromData(decodedData)) {
                    // 保存为 .jpe 格式（实际上是 JPEG 格式）
                    if (img.save(savePath, "JPEG")) {
                        ok = true;
                    } else {
                        ok = false;
                    }
                } else {
                    qDebug() << "Failed to load image from decoded data.";
                }
                //ok = img.save(savePath, "JPEG");
            }else if(fileInfo.suffix() == "bmp"){
                // bmp保存白色背景会填充黑色，额外处理
                QImage image;
                image = image.convertToFormat(QImage::Format_RGB32);
                    // 保存为 .jpe 格式（实际上是 JPEG 格式）
                if (image.loadFromData(decodedData)) {
                    // 保存为 .jpe 格式（实际上是 JPEG 格式）
                    if (image.save(savePath)) {
                        ok = true;
                    } else {
                        ok = false;
                    }
                } else {
                    qDebug() << "Failed to load image from decoded data.";
                }
            }else{
                ok = pixmap.save(savePath);
            }
        }
        if(ok)
        {
            QString pathNoFile = savePath.left(savePath.lastIndexOf(QLatin1String("/")));
            message = QObject::tr("Image saved as ") + savePath;
            msg = "<a href=\"" + savePath + "\">" + message + "</a>";
        }
        else
        {
            if(name.contains(QChar('/')))
            {
                msg = QObject::tr("file name can not contains '/'");
            }
            else if(name.startsWith(QChar('.'), Qt::CaseInsensitive))
            {
                msg = QObject::tr("can not save file as hide file");
            }
            else if(name.length() > 255)
            {
                msg = QObject::tr("can not save  because filename too long");
            }
            else
            {
//                message = QObject::tr("Error trying to save as ") + savePath;
//                msg = "<a href=\"" + savePath + "\">" + message + "</a>";
                msg = QObject::tr("Error trying to save as ") + savePath;
            }
            QMessageBox saveErrBox(QMessageBox::Warning, QObject::tr("Save Error"), msg);
            saveErrBox.exec();
        }
    }
    return;
    }

void CMainWnd::onOpenFile(int typeNum)
{
    FileType type = FileType(typeNum);
    //wayland环境下，构造函数必须加this， setModal(true)
    QFileDialog m_fileDialog(this);
    m_fileDialog.setModal(true);
    m_fileDialog.update();
    QList<QUrl> list = m_fileDialog.sidebarUrls();
    int sidebarNum = 8; //最大添加U盘数，可以自己定义
    QString home = QDir::homePath().section("/", -1, -1);
    QString mnt = "/media/" + home + "/";
    QDir mntDir(mnt);
    mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
    QFileInfoList filist = mntDir.entryInfoList();
    QList<QUrl> mntUrlList;
    for(int i = 0; i < sidebarNum && i < filist.size(); ++i)
    {
        QFileInfo fi = filist.at(i);
        //华为990、9a0需要屏蔽最小系统挂载的目录
        if(fi.fileName() == "2691-6AB8")
            continue;
        mntUrlList << QUrl("file://" + fi.filePath());
    }

    QFileSystemWatcher fsw(&m_fileDialog);
    fsw.addPath("/media/" + home + "/");
    connect(&fsw, &QFileSystemWatcher::directoryChanged, &m_fileDialog, [=, &sidebarNum, &mntUrlList, &list, &m_fileDialog](const QString path) {
        QDir wmntDir(path);
        wmntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
        QFileInfoList wfilist = wmntDir.entryInfoList();
        mntUrlList.clear();
        for(int i = 0; i < sidebarNum && i < wfilist.size(); ++i)
        {
            QFileInfo fi = wfilist.at(i);
            //华为990、9a0需要屏蔽最小系统挂载的目录
            if(fi.fileName() == "2691-6AB8")
                continue;
            mntUrlList << QUrl("file://" + fi.filePath());
        }
        m_fileDialog.setSidebarUrls(list + mntUrlList);
        m_fileDialog.update();
    });

    connect(&m_fileDialog, &QFileDialog::finished, &m_fileDialog, [=, &list, &m_fileDialog]() {
        m_fileDialog.setSidebarUrls(list);
    });

    //这行要添加，设置左侧导航
    m_fileDialog.setSidebarUrls(list + mntUrlList);
    //设置视图模式
    m_fileDialog.setViewMode(QFileDialog::Detail);
    //设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles
    m_fileDialog.setFileMode(QFileDialog::ExistingFile);
    m_fileDialog.setOption(QFileDialog::HideNameFilterDetails);

    QString file_path;
    QString format;
    QString openFile = tr("Open Image");
    QStringList supportFile = { "txt","pdf","docx","pptx"};
    QStringList supportFormats = {  "bmp","jpe","jpeg","jpg","pbm","pgm","png","ppm","tiff","webp"};

    if(type == IMAGE)
    {
        //构造打开条件
        format = "(";
        for(const QString &str: supportFormats)
            format += "*." + str + " ";
        format += ");;";

        const QString supportFormatsClassify = "(*.bmp);;"
                                               "(*.jpe *.jpeg *.jpg);;"
                                               "(*.pbm);;"
                                               "(*.pgm);;"
                                               "(*.png);;"
                                               "(*.ppm);;"
                                               "(*.tiff);;"
                                               "(*.webp)";
        //所有类型都放在一起，类型名显示不全，故增加分层，将同一类型的放在一起，分层显示
        format = format + supportFormatsClassify;
        QVariant imagePath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
        //打开文件夹中的图片文件
        file_path = m_fileDialog.getOpenFileName(this, openFile, imagePath.toString(), format);
    }
    else if(type == DOCUMENT)
    {
        format = "(";
        for(const QString &str: supportFile)
            format += "*." + str + " ";
        format += ");;";
        const QString supportFormatsClassify = "(*.txt);;"
                                               "(*.pdf);;"
                                               "(*.docx);;"
                                               "(*.pptx)";
        //所有类型都放在一起，类型名显示不全，故增加分层，将同一类型的放在一起，分层显示
        format = format + supportFormatsClassify;
        QVariant path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);

        //打开文件夹中的图片文件
        file_path = m_fileDialog.getOpenFileName(this, openFile, path.toString(), format);
}

    //空校验，点击“取消”
    if(file_path.isEmpty())
    {
        return;
    }
    // 目前文件对话框无法限制不能选中超过一个文件，多选的时候只上传第一张
//    else if(file_path.size() > 1)
//    {
//        onShowErrorMoreImage();
//        return;
//    }
    else
    {
        QFileInfo fileInfo(file_path);
        //判断文件后缀
        if(!supportFormats.contains(fileInfo.suffix().toLower()) && !supportFile.contains(fileInfo.suffix().toLower()))
        {
            if(type == IMAGE)
            {
                m_msgPane->onShowErrorFormatImage();
            }
            else if(type == DOCUMENT)
            {
                m_msgPane->onShowErrorFormatFile();
            }
            return;
        }
        //判断文件大小
        else if(fileInfo.size() > MAXIMAGESIZE)
        {
            m_msgPane->onShowErrorSizeImage();
            return;
        }
        else
        {
            if(type == IMAGE)
            {
                m_msgPane->onShowImage(file_path, 1);
            }
            else if(type == DOCUMENT)
            {
                m_msgPane->onShowDocument(file_path);
            }
        }
    }
}

void CMainWnd::onShowScribeWord()
{
    //如果禁用划词则直接返回
    bool isSelectDisable = g_configManager->getConfigValue("is-stroke-word").toBool();
//    KyInfo() << "当前禁用划词显示的标志位为"<< isSelectDisable;
    if(!isSelectDisable){
        return;
    }

    // 处理 v11 环境下划词显示异常问题
//    if(isWayland){
////        WindowManager::setOpenUnderCursor(m_selectwid->windowHandle());
//        m_selectwid->show();
//    }
//    else{
//        m_selectwid->showScribeWordsAtCursorPosition();
//    }
    KyInfo() << "=======m_selectwid->isVisible()======" << m_selectwid->isVisible();
    if (m_selectwid->isVisible() == true) {
        m_selectwid->closeWidgetAndinstructPage(1,1);
    } else {
        m_selectwid->showScribeWordsAtCursorPosition();
        m_msgPane->sendFocusChanged();

        if(m_selectclip)
        {
            KyInfo() << "current selectClip message:" << m_selectclip->getClipText();
            if(m_selectclip->getClipText() == "" || m_selectclip->getClipText() == "\n" || m_selectclip->getClipText().isEmpty())
            {
                m_selectwid->slUpdateSelectEnableStatus(false);
            }
            else
            {
                m_selectwid->slUpdateSelectEnableStatus(true);
            }
        }
    }


}

void CMainWnd::initPosition()
{
    QScreen *primaryScreen = QGuiApplication::primaryScreen();
    Globals::scaleFactor = primaryScreen->devicePixelRatio();

    // 屏幕的分辨率或可用显示区域变化
    connect(primaryScreen, &QScreen::availableGeometryChanged, [this] {
        KyInfo() << "11111=======availableGeometryChanged=======";
        changeScreenResolution();
    });
    // 主屏变化
    connect(qApp, &QGuiApplication::primaryScreenChanged, this, [=](QScreen *screen){
        Q_UNUSED(screen);
        KyInfo() << "22222=======primaryScreenChanged=======" << screen->name();
        changeScreenResolution();
    });
    // 屏幕被添加
    connect(qApp, &QGuiApplication::screenAdded, this, [=](QScreen *screen){
        connect(screen, &QScreen::geometryChanged, this, [=](const QRect& geometry){
            KyInfo() << "33333=======geometryChanged======="<< screen->name() << geometry;
        });
        KyInfo() << "33333=======screenAdded=======add" << screen->name() << screen->geometry();
        changeScreenResolution();
    });
    // 屏幕被移除
    connect(qApp, &QGuiApplication::screenRemoved, this, [=](QScreen *screen){
        KyInfo() << "44444=======screenRemoved=======remove" << screen->name() << screen->geometry();
        changeScreenResolution();
    });
    for(QScreen *screen : qApp->screens()) {
        // 屏幕的几何区域变化
        connect(screen, &QScreen::geometryChanged, this, [=](const QRect& geometry){
            KyInfo() << "44444=======geometryChanged=======" << screen->name() << "geometry" << geometry << "availableGeometry" << screen->availableGeometry();
            changeScreenResolution();
        });
    }

    return;
}

void CMainWnd::changeScreenResolution(){
    KyInfo() << "===availableGeometryChanged==";
    int curWinMode = m_msgPane->getCurWinMode();
    if(curWinMode == 2)
    {
        // 侧边栏模式
        switchToSideMode();
    }
    else if (curWinMode == 3){
        // 窗口模式
        switchToWindowMode();
    }
}

void CMainWnd::initTimer()
{
    resizeTimer = new QTimer(this);
    moveTimer = new QTimer(this);
    resizeTimer->setSingleShot(true);
    connect(resizeTimer, &QTimer::timeout, this, &CMainWnd::onResizeEnd);
    moveTimer->setSingleShot(true);
    connect(moveTimer, &QTimer::timeout, this, &CMainWnd::onMoveEnd);
}

void CMainWnd::initTopping()
{
    bool isTopping = g_configManager->getConfigValue("is-window-mode-topping").toBool();

    qInfo() << "isTopping " << isTopping;

    if(isTopping){
        m_isTop = true;
        keepWindowAbove(true);
    }

    m_btnStick->setIcon(QIcon::fromTheme(m_isTop ? "ukui-unfixed-symbolic" : "ukui-fixed-symbolic"));
    m_btnStick->setToolTip(m_isTop ? tr("unfixed") : tr("fixed"));
}

void CMainWnd::changeToOccupiedMode()
{   QRect screenRect = QGuiApplication::primaryScreen()->availableGeometry();
    KWindowSystem::setExtendedStrut(winId(),
        /* Left   */ 0, 0, 0,
        /* Right  */ width(), 0, screenRect.height(),
        /* Top    */ 0, 0, 0,
        /* Bottom */ 0, 0, 0);

    return;
}

void CMainWnd::changeToNormalMode()
{
    KWindowSystem::setExtendedStrut(winId(),
        /* Left   */ 0, 0, 0,
        /* Right  */ 0, 0, 0,
        /* Top    */ 0, 0, 0,
        /* Bottom */ 0, 0, 0);

    return;
}

void CMainWnd::showSettingPage()
{
    m_settingPage->show();
    QScreen *screen = QApplication::primaryScreen();
    int screenWidth = screen->size().width();
    int screenHeight = screen->size().height();
    int widgetWidth = m_settingPage->width();
    int widgetHeight = m_settingPage->height();
    int x = (screenWidth - widgetWidth) / 2;
    int y = (screenHeight - widgetHeight) / 2;
    m_settingPage->move(x, y);

    if (!m_settingPage->isActiveWindow()) {
        KyInfo() << "m_settingPage isActiveWindow false";
        KWindowSystem::forceActiveWindow(m_settingPage->winId());
    }
}

void CMainWnd::initShortcut()
{
    //设置划词快捷键
    if(m_actionShowScribeWord){
        KGlobalAccel::self()->removeAllShortcuts(m_actionShowScribeWord);
        delete m_actionShowScribeWord;
    }
    m_actionShowScribeWord = new QAction(this);
    m_actionShowScribeWord->setObjectName("Action showScribeWord");
    //这两行必须写，否则注册快捷键的模块名为中文，会导致快捷键注册失败
    m_actionShowScribeWord->setProperty("componentName", "kylin-aiassistant");
    m_actionShowScribeWord->setProperty("componentDisplayName", "AI aiassistant");

    //移除之前需要set一次,估计是bug
    KGlobalAccel::self()->setShortcut(m_actionShowScribeWord, QList<QKeySequence>{Qt::ALT+ Qt::META + Qt::Key_C});
    KGlobalAccel::self()->removeAllShortcuts(m_actionShowScribeWord);

    connect(m_actionShowScribeWord, &QAction::triggered, this, &CMainWnd::onShowScribeWord);
    KGlobalAccel::self()->setShortcut(m_actionShowScribeWord, QList<QKeySequence>{Qt::ALT+ Qt::META + Qt::Key_C});

    //设置助手显示弹窗快捷键
    if(m_actionShowView){
        KGlobalAccel::self()->removeAllShortcuts(m_actionShowView);
        delete m_actionShowView;
    }
    m_actionShowView = new QAction(this);
    m_actionShowView->setObjectName("Action showView");
    //这两行必须写，否则注册快捷键的模块名为中文，会导致快捷键注册失败
    m_actionShowView->setProperty("componentName", "kylin-aiassistant");
    m_actionShowView->setProperty("componentDisplayName", "AI aiassistant");

    //移除之前需要set一次,估计是bug
    KGlobalAccel::self()->setShortcut(m_actionShowView, QList<QKeySequence>{Qt::META + Qt::Key_C});
    KGlobalAccel::self()->removeAllShortcuts(m_actionShowView);

//    connect(m_actionShowView, &QAction::triggered, this, &CMainWnd::showOrHideWindow);
//    KGlobalAccel::self()->setShortcut(m_actionShowView, QList<QKeySequence>{Qt::META + Qt::Key_C});

}

QString CMainWnd::getAiAssistantVersion()
{
    FILE *pp = NULL;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    char *q = NULL;
    QString version = tr("none");

    pp = popen("dpkg -l kylin-aiassistant", "r");
    if(NULL == pp)
        return version;

    while((read = getline(&line, &len, pp)) != -1){
        q = strrchr(line, '\n');
        *q = '\0';

        QString content = line;
        QStringList list = content.split(" ");

        list.removeAll("");

        if (list.size() >= 3)
            version = list.at(2);
    }

    free(line);
    pclose(pp);
    return version;
}
void CMainWnd::initGlobalSetting()
{
    isSupportWindowMode = Globals::getIsSupportWindowMode();
}

void CMainWnd::checkTheme()
{
    if(QGSettings::isSchemaInstalled("org.ukui.style"))
    {
        themeData = new QGSettings("org.ukui.style");

        if(themeData->get("style-name").toString() == "ukui-dark" || themeData->get("style-name").toString() == "ukui-black")
        {
            Globals::themeColor = 1;
            Q_EMIT sigThemeChanged();
            // changeDarkTheme();
        }
        else
        {
            Globals::themeColor = 0;
            Q_EMIT sigThemeChanged();
            // changeLightTheme();
        }

        Globals::fontSize = themeData->get(UKUI_FONT_SIZE).toString().toFloat();

        connect(themeData, &QGSettings::changed, this, [=](const QString &key) {
            if(key == "styleName")
            {
                if((themeData->get("style-name").toString() == "ukui-dark" || themeData->get("style-name").toString() == "ukui-black"))
                {
                    if(Globals::themeColor != 1)
                    {
                        Globals::themeColor = 1;
                        Q_EMIT sigThemeChanged();
                        // changeDarkTheme();
                    }
                }
                else
                {
                    if(Globals::themeColor != 0)
                    {
                        Globals::themeColor = 0;
                        Q_EMIT sigThemeChanged();
                        // changeLightTheme();
                    }
                }
            }
            else if(key == UKUI_FONT_SIZE)
            {
                //获取字号的值
                int fontSizeKey = themeData->get(UKUI_FONT_SIZE).toString().toFloat();
                //发送改变信号
                if(fontSizeKey > 0)
                {
                    Globals::fontSize = fontSizeKey;
                    Q_EMIT Globals::getinstance()->fontsizeChanged(fontSizeKey);
                }
            }
        });
    }
}

void CMainWnd::keepWindowAbove(bool needTokeepAbove)
{
    qInfo() << "needTokeepAbove " << needTokeepAbove;

#ifdef UKUI_WINDOWHELPER_SUPPORT
    UkuiWindowHelper::States states;
    states |= UkuiWindowHelper::State::Minimizable;
    states |= UkuiWindowHelper::State::Maximizable;
    states |= UkuiWindowHelper::State::Closeable;
    states |= UkuiWindowHelper::State::Fullscreenable;

    states |= UkuiWindowHelper::State::Resizable;
    states |= UkuiWindowHelper::State::Focusable;
    states |= UkuiWindowHelper::State::Activatable;

    int winMode = g_configManager->getConfigValue("win-mode").toInt();
    qInfo() << "winMode " << winMode;
    if (winMode == 3){
        states |= UkuiWindowHelper::State::Movable;
    }

    if (needTokeepAbove) {
        states |= UkuiWindowHelper::State::KeepAbove;

    }

    m_ukuiWindowHelper->setWindowState(states);
#else
    qInfo() << "m_window_id " << m_window_id;
    kdk::WindowManager::keepWindowAbove(m_window_id);
#endif

    return;
}

void CMainWnd::setMovable(bool isMovable)
{
    qInfo() << "isMovable " << isMovable;

#ifdef UKUI_WINDOWHELPER_SUPPORT
    UkuiWindowHelper::States states;
    states |= UkuiWindowHelper::State::Minimizable;
    states |= UkuiWindowHelper::State::Maximizable;
    states |= UkuiWindowHelper::State::Closeable;
    states |= UkuiWindowHelper::State::Fullscreenable;
    states |= UkuiWindowHelper::State::Resizable;
    states |= UkuiWindowHelper::State::Focusable;
    states |= UkuiWindowHelper::State::Activatable;

    if (isMovable) {
        states |= UkuiWindowHelper::State::Movable;
    }

    if (m_isTop) {
        states |= UkuiWindowHelper::State::KeepAbove;

    }

    m_ukuiWindowHelper->setWindowState(states);
#else
    this->topLevelWidget()->setProperty("useStyleWindowManager", isMovable);
#endif

    return;
}

void CMainWnd::checkIntroduction()
{
    if(g_configManager->getConfigValue("is-first-install").toBool() == true && isChatInitCompleted == true && m_introductionView == nullptr){
        QTimer::singleShot(300, this, [=](){
            if (this->isVisible() == true) {
                KyInfo() << "====init complete====mainwnd show true";
                IntroductionView *introductionDialog = new IntroductionView(this);
                m_introductionView = introductionDialog;
                connect(introductionDialog,&IntroductionView::showSettingPage,this,&CMainWnd::onConfActionTriggered);
                connect(introductionDialog,&IntroductionView::openUKUIControlCenterView,m_msgPane,&CMsgPane::openUkuiControlCenter);
                int posX = this->x() + (this->width() - introductionDialog->width()) / 2;
                int posY = this->y() + (this->height() - introductionDialog->height()) / 2;
                introductionDialog->move(posX,posY);
                if(isWayland){
                    KyInfo() << "IntroductionView showView isWayland";
                    introductionDialog->setGeometry(QRect(posX, posY, introductionDialog->width(), introductionDialog->height()));
                }
                introductionDialog->exec();
                m_introductionView = nullptr;
            }
        });
    }

    return;
}

void CMainWnd::aboutToQuit()
{
    qInfo() << "aboutToQuit";
    if(!m_msgPane->getIsReplying())  {
        return;
    }
    m_msgPane->pushMsg("replyEnd", true);
    return;
}
