// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "dsplitlistwidget.h"
#include "globaldef.h"
#include "utils.h"

#include <DApplication>
#include <DStyleHelper>
#if QT_VERSION_MAJOR <= 5
#include <DApplicationHelper>
#endif
#include <DLog>

#include <QToolTip>
#include <QPainter>
#include <QMouseEvent>
#include <QPainterPath>
#include <QTimer>

#define FTM_SPLIT_TOP_SPACE_TAG "_space_"
#define FTM_SPLIT_TOP_SPLIT_TAG "_split_"
#define FTM_SPLIT_LINE_INDEX    5
#define TITLE_VISIBLE_WIDTH    96
#define IS_NEED_ELLIPSIS  30 //是否需要省略号

DNoFocusDelegate::DNoFocusDelegate(QAbstractItemView *parent)
    : DStyledItemDelegate(parent)
    , m_parentView(qobject_cast<DSplitListWidget *>(parent))
{
    // qDebug() << "Entering function: DNoFocusDelegate::DNoFocusDelegate";
}

//用于去除选中项的边框
/*************************************************************************
 <Function>      paint
 <Description>   绘制函数
 <Author>        null
 <Input>
    <param1>     painter            Description:绘制类的指针
    <param2>     option             Description:当前项
    <param3>     index              Description:当前项索引
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DNoFocusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                             const QModelIndex &index) const
{
    // qDebug() << "Entering function: DNoFocusDelegate::paint";
    if (index.isValid()) {
        // qDebug() << "index is valid";
        painter->save();
        painter->setFont(DApplication::font());
        painter->setRenderHint(QPainter::Antialiasing, true);

        QVariant varDisplay = index.data(Qt::DisplayRole);
        QString iniTitle = varDisplay.value<QString>();
        QFont nameFont = painter->font();
        QString strTitle = adjustLength(iniTitle, nameFont);

        QStyleOptionViewItem viewOption(option);  //用来在视图中画一个item

        DPalette::ColorGroup cg = (option.state & QStyle::State_Enabled)
                                  ? DPalette::Normal : DPalette::Disabled;
        if (cg == DPalette::Normal && !(option.state & QStyle::State_Active)) {
            // qDebug() << "cg is Normal and option.state is not Active";
            cg = DPalette::Inactive;
        }

        if (strTitle.startsWith(FTM_SPLIT_TOP_SPACE_TAG)) {
            // qDebug() << "strTitle starts with FTM_SPLIT_TOP_SPACE_TAG";
            //用于ListView顶部空白
        } else if (strTitle.startsWith(FTM_SPLIT_TOP_SPLIT_TAG)) {
            // qDebug() << "strTitle starts with FTM_SPLIT_TOP_SPLIT_TAG";
            QRect lineRect;
            lineRect.setX(option.rect.x() + 10);
            lineRect.setY(option.rect.y() + option.rect.height() - 2);
            lineRect.setWidth(option.rect.width() - 20);
            lineRect.setHeight(2);
            //绘制分割线
#if QT_VERSION_MAJOR > 5
            DPalette pa = DGuiApplicationHelper::instance()->applicationPalette();
#else
            DPalette pa = DApplicationHelper::instance()->palette(m_parentView);
#endif
            DStyleHelper styleHelper;
            QColor fillColor = styleHelper.getColor(static_cast<const QStyleOption *>(&option), pa, DPalette::ItemBackground);
            painter->fillRect(lineRect, fillColor);
        } else {
            // qDebug() << "strTitle does not start with FTM_SPLIT_TOP_SPACE_TAG or FTM_SPLIT_TOP_SPLIT_TAG";
            QRect rect;
            rect.setX(option.rect.x());
            rect.setY(option.rect.y());
            rect.setWidth(option.rect.width());
            rect.setHeight(option.rect.height());

            QRect backgroundRect = QRect(rect.left() + 10, rect.top(), rect.width() - 20, rect.height());

            paintBackground(painter, option, backgroundRect, cg);

            //绘制标题
            /* bug#20266 UT000591 */ /*bug 21075 ut000442*/
            QRect fontNameRect;
            if (strTitle == "System") {
                // qDebug() << "strTitle is System";
                fontNameRect = QRect(backgroundRect.left() + 10, backgroundRect.top() + 1, backgroundRect.width() - 20, backgroundRect.height() - 7);
            } else {
                // qDebug() << "strTitle is not System";
                fontNameRect = QRect(backgroundRect.left() + 10, backgroundRect.top() + 2, backgroundRect.width() - 20, backgroundRect.height() - 7);
            }

            nameFont.setWeight(QFont::Medium);
            nameFont.setPixelSize(DFontSizeManager::instance()->fontPixelSize(DFontSizeManager::T6));
            painter->setFont(nameFont);

            if (option.state & QStyle::State_Selected) {
                // qDebug() << "option.state is Selected";
                painter->setPen(QPen(option.palette.color(DPalette::HighlightedText)));
                painter->drawText(fontNameRect, Qt::AlignLeft | Qt::AlignVCenter, strTitle);
            } else {
                // qDebug() << "option.state is not Selected";
                painter->setPen(QPen(option.palette.color(DPalette::Text)));
                painter->drawText(fontNameRect, Qt::AlignLeft | Qt::AlignVCenter, strTitle);
            }
        }
        painter->restore();
    } else {
        // qDebug() << "index is not valid";
        QStyledItemDelegate::paint(painter, option, index);
    }
    // qDebug() << "Exiting function: DNoFocusDelegate::paint";
}

/*************************************************************************
 <Function>      sizeHint
 <Description>   获取一项的size
 <Author>        null
 <Input>
    <param1>     option            Description:listview中的一行成员
    <param2>     index             Description:当前项的索引
 <Return>        QSize             Description:返回的尺寸大小
 <Note>          null
*************************************************************************/
QSize DNoFocusDelegate::sizeHint(const QStyleOptionViewItem &option,
                                 const QModelIndex &index) const
{
    // qDebug() << "Entering function: DNoFocusDelegate::sizeHint";
    Q_UNUSED(index)

    int rowIndex = index.row();

#ifdef DTKWIDGET_CLASS_DSizeMode
    if (DGuiApplicationHelper::instance()->sizeMode() == DGuiApplicationHelper::SizeMode::CompactMode) {
        // qDebug() << "DGuiApplicationHelper::instance()->sizeMode() == DGuiApplicationHelper::SizeMode::CompactMode";
        if (FTM_SPLIT_LINE_INDEX == rowIndex) {
            // qDebug() << "FTM_SPLIT_LINE_INDEX == rowIndex";
            return QSize(option.rect.width(), 20);
        } else {
            // qDebug() << "FTM_SPLIT_LINE_INDEX != rowIndex";
            return QSize(option.rect.width(), 24);
        }
    }
#endif

    if (FTM_SPLIT_LINE_INDEX == rowIndex) {
        // qDebug() << "FTM_SPLIT_LINE_INDEX == rowIndex";
        return QSize(option.rect.width(), 24);
    } else {
        // qDebug() << "FTM_SPLIT_LINE_INDEX != rowIndex";
        return QSize(option.rect.width(), 36);
    }
    // qDebug() << "Exiting function: DNoFocusDelegate::sizeHint";
}


/*************************************************************************
 <Function>      paintBackground
 <Description>   绘制背景
 <Author>        null
 <Input>
    <param1>     painter                   Description:绘制类指针
    <param2>     option                    Description:listview中的一行成员
    <param3>     backgroundRect            Description:绘制背景区域
    <param4>     cg                        Description:ColorGroup
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DNoFocusDelegate::paintBackground(QPainter *painter, const QStyleOptionViewItem &option, const QRect &backgroundRect, const QPalette::ColorGroup cg) const
{
    // qDebug() << "Entering function: DNoFocusDelegate::paintBackground";
    //绘制左侧列表外部高亮区域的路径
    QPainterPath pathFirst;
    const int radius = 8;
    setPaintPath(backgroundRect, pathFirst, 0, 0, radius);
    bool isTabFocus = m_parentView->IsTabFocus();
    if (option.state & QStyle::State_Selected) {
        // qDebug() << "option.state & QStyle::State_Selected";
        //判断是否为通过tab获得的焦点
        if (isTabFocus) {
            //如果为hover状态，颜色亮度需要加亮
            if (option.state & QStyle::State_MouseOver) {
                // qDebug() << "option.state & QStyle::State_MouseOver";
                paintTabBackground(painter, option, backgroundRect, cg, true);
            } else {
                // qDebug() << "option.state & QStyle::State_MouseOver is false";
                paintTabBackground(painter, option, backgroundRect, cg, false);
            }
        } else if (!isTabFocus) {
            // qDebug() << "option.state & QStyle::State_Selected and isTabFocus is false";
            QColor fillColor = option.palette.color(cg, DPalette::Highlight);
            //如果为hover状态，颜色亮度需要加亮
            if (option.state & QStyle::State_MouseOver) {
                // qDebug() << "option.state & QStyle::State_MouseOver";
#if QT_VERSION_MAJOR > 5
                fillColor = fillColor.lighter(120);
#else
                fillColor = fillColor.light(120);
#endif
            }
            painter->setBrush(QBrush(fillColor));
            painter->fillPath(pathFirst, painter->brush());
        }
    } else if (option.state & QStyle::State_MouseOver) {
        // qDebug() << "option.state & QStyle::State_MouseOver";
        //未选中状态下的hover，需要有淡灰色背景
        DStyleHelper styleHelper;
        QColor fillColor = styleHelper.getColor(static_cast<const QStyleOption *>(&option), DPalette::ToolTipText);
        fillColor.setAlphaF(0.1);
        painter->setBrush(QBrush(fillColor));
        painter->fillPath(pathFirst, painter->brush());
    }
    // qDebug() << "Exiting function: DNoFocusDelegate::paintBackground";
}

/*************************************************************************
 <Function>      paintTabBackground
 <Description>   绘制tab选中后的背景
 <Author>        null
 <Input>
    <param1>     painter                   Description:绘制类指针
    <param2>     option                    Description:listview中的一行成员
    <param3>     backgroundRect            Description:绘制背景区域
    <param4>     cg                        Description:ColorGroup
    <param4>     isHover                   Description:是否为hover状态
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DNoFocusDelegate::paintTabBackground(QPainter *painter, const QStyleOptionViewItem &option,
                                          const QRect &backgroundRect, const QPalette::ColorGroup cg, const bool isHover) const
{
    // qDebug() << "Entering function: DNoFocusDelegate::paintTabBackground";
    //绘制左侧列表外部高亮区域的路径
    QPainterPath pathFirst;
    const int radius = 8;
    setPaintPath(backgroundRect, pathFirst, 0, 0, radius);

    //绘制左侧列表窗口色区域的路径
    QPainterPath pathSecond;
    setPaintPath(backgroundRect, pathSecond, 2, 2, 6);

    //绘制左侧列表内部高亮区域的路径
    QPainterPath pathThird;
    setPaintPath(backgroundRect, pathThird, 3, 3, 6);

    QColor fillColor = option.palette.color(cg, DPalette::Highlight);

    //如果为hover状态，颜色亮度需要加亮
    if (isHover) {
#if QT_VERSION_MAJOR > 5
        // qDebug() << "fillColor is lighter";
        fillColor = fillColor.lighter(120);
#else
        // qDebug() << "fillColor is light";
        fillColor = fillColor.light(120);
#endif
    }
    painter->setBrush(QBrush(fillColor));
    painter->fillPath(pathFirst, painter->brush());

    QColor fillColor2 = option.palette.color(cg, DPalette::Window);
    painter->setBrush(QBrush(fillColor2));
    painter->fillPath(pathSecond, painter->brush());

    painter->setBrush(QBrush(fillColor));
    painter->fillPath(pathThird, painter->brush());

    // qDebug() << "Exiting function: DNoFocusDelegate::paintTabBackground";
}

/*************************************************************************
 <Function>      setPaintPath
 <Description>   设置需要绘制区域的路径
 <Author>        null
 <Input>
    <param1>     bgRect            Description:listview一项的区域范围
    <param2>     path              Description:需要绘制区域的路径
    <param3>     xDifference       Description:x方向需要变化的数值
    <param4>     yDifference       Description:y方向需要变化的数值
    <param5>     radius            Description:圆弧半径
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DNoFocusDelegate::setPaintPath(const QRect &bgRect, QPainterPath &path, const int xDifference, const int yDifference, const int radius) const
{
    // qDebug() << "Entering function: DNoFocusDelegate::setPaintPath";
    QPoint path_bottomRight(bgRect.bottomRight().x() - xDifference, bgRect.bottomRight().y() - yDifference);
    QPoint path_topRight(bgRect.topRight().x() - xDifference, bgRect.topRight().y() + yDifference);
    QPoint path_topLeft(bgRect.topLeft().x() + xDifference, bgRect.topLeft().y() + yDifference);
    QPoint path_bottomLeft(bgRect.bottomLeft().x() + xDifference, bgRect.bottomLeft().y() - yDifference);
    path.moveTo(path_bottomRight - QPoint(0, 10));
    path.lineTo(path_topRight + QPoint(0, 10));
    path.arcTo(QRect(QPoint(path_topRight - QPoint(radius * 2, 0)), QSize(radius * 2, radius * 2)), 0, 90);
    path.lineTo(path_topLeft + QPoint(10, 0));
    path.arcTo(QRect(QPoint(path_topLeft), QSize(radius * 2, radius * 2)), 90, 90);
    path.lineTo(path_bottomLeft - QPoint(0, 10));
    path.arcTo(QRect(QPoint(path_bottomLeft - QPoint(0, radius * 2)), QSize(radius * 2, radius * 2)), 180, 90);
    path.lineTo(path_bottomRight - QPoint(10, 0));
    path.arcTo(QRect(QPoint(path_bottomRight - QPoint(radius * 2, radius * 2)), QSize(radius * 2, radius * 2)), 270, 90);
    // qDebug() << "Exiting function: DNoFocusDelegate::setPaintPath";
}



/*************************************************************************
 <Function>      adjustLength
 <Description>   自适应长度
 <Author>        null
 <Input>
    <param1>     titleName       Description:名字
    <param2>     font            Description:当前字体
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
QString DNoFocusDelegate::adjustLength(QString &titleName, QFont &font) const
{
    // qDebug() << "Entering function: DNoFocusDelegate::adjustLength";
    QFontMetrics fontMetric(font);

    QString finalTitle = "";
    QString m_curTitle = "";

    for (auto str : titleName) {
        m_curTitle += str;
#if QT_VERSION_MAJOR > 5
        if (fontMetric.boundingRect(m_curTitle).width() > TITLE_VISIBLE_WIDTH) {
#else
        if (fontMetric.width(m_curTitle) > TITLE_VISIBLE_WIDTH) {
#endif
            if (m_curTitle == titleName) {
                finalTitle = m_curTitle;
                break;
            } else {
#if QT_VERSION_MAJOR > 5
                if (fontMetric.boundingRect("...").width() > IS_NEED_ELLIPSIS) {
#else
                if (fontMetric.width("...") > IS_NEED_ELLIPSIS) {
#endif
                    finalTitle = m_curTitle;
                } else {
                    finalTitle =   m_curTitle.append("...");
                }
                break;
            }
        } else {
            finalTitle = titleName;
        }
    }

    // qDebug() << "Exiting function: DNoFocusDelegate::adjustLength";
    return finalTitle;
}

DSplitListWidget::DSplitListWidget(QWidget *parent)
    : DListView(parent)
{
    qDebug() << "Entering function: DSplitListWidget::DSplitListWidget";
    //去除选中项的边框
    this->setItemDelegate(new DNoFocusDelegate(this));
    this->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers);
    this->setAutoScroll(false);
    this->setMouseTracking(true);
    this->installEventFilter(this);
    initListData();
    connect(m_signalManager, &SignalManager::setSpliteWidgetScrollEnable, this, &DSplitListWidget::setRefreshFinished);
    connect(m_signalManager, &SignalManager::setLostFocusState, this, [ = ](bool isTrue) {
        m_isFocusFromFontListView = isTrue;
    });
    qDebug() << "Exiting function: DSplitListWidget::DSplitListWidget";
}

DSplitListWidget::~DSplitListWidget()
{
    qDebug() << "Entering function: DSplitListWidget::~DSplitListWidget";
}

void DSplitListWidget::initListData()
{
    qDebug() << "Entering function: DSplitListWidget::initListData";
    m_titleStringList << DApplication::translate("Category", "All Fonts")
                      << DApplication::translate("Category", "System")
                      << DApplication::translate("Category", "User")
                      << DApplication::translate("Category", "Favorites")
                      << DApplication::translate("Category", "Active")
                      << DApplication::translate("Category", "Chinese")
                      << DApplication::translate("Category", "Monospaced");
    for (int i = 0; i < m_titleStringList.size(); i++) {
        QString titleString = m_titleStringList.at(i);
        m_titleStringIndexMap.insert(titleString, i);
    }

    m_categoryItemModell = new QStandardItemModel(this);

    int iTitleIndex = 0;
    for (int i = 0; i < m_titleStringList.size() + 1; i++) {
        QStandardItem *item = new QStandardItem;
        if (FTM_SPLIT_LINE_INDEX == i) {
            item->setFlags(item->flags() & ~Qt::ItemIsSelectable & ~Qt::ItemIsEnabled);
            item->setData(QVariant::fromValue(QString(FTM_SPLIT_TOP_SPLIT_TAG)), Qt::DisplayRole);
        } else {
            QString titleString = m_titleStringList.at(iTitleIndex++);
            item->setData(QVariant::fromValue(titleString), Qt::DisplayRole);
        }
        m_categoryItemModell->appendRow(item);
    }

    this->setModel(m_categoryItemModell);

    //设置默认选中
    QModelIndex index = m_categoryItemModell->index(AllFont, 0);
    selectionModel()->select(index, QItemSelectionModel::Select);
    qDebug() << "Exiting function: DSplitListWidget::initListData";
}

/*************************************************************************
 <Function>      setIsHalfWayFocus
 <Description>   设置是否为其它原因获取的焦点
 <Author>        null
 <Input>
    <param1>     IsHalfWayFocus            Description:是否为其它原因获取的焦点
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::setIsHalfWayFocus(bool IsHalfWayFocus)
{
    // qDebug() << "Entering function: DSplitListWidget::setIsHalfWayFocus";
    m_IsHalfWayFocus = IsHalfWayFocus;
}

/*************************************************************************
 <Function>      IsTabFocus
 <Description>   判断是否tab选中
 <Author>        null
 <Input>
    <param1>     null            Description:null
 <Return>        bool            Description:是否tab选中
 <Note>          null
*************************************************************************/
bool DSplitListWidget::IsTabFocus() const
{
    // qDebug() << "Entering function: DSplitListWidget::IsTabFocus";
    return m_IsTabFocus;
}

/*************************************************************************
 <Function>      getStatus
 <Description>   获取当前SplitListview的状态
 <Author>        null
 <Input>
    <param1>     null            Description:null
 <Return>        FocusStatus            Description:当前SplitListview的状态
 <Note>          null
*************************************************************************/
FocusStatus &DSplitListWidget::getStatus()
{
    // qDebug() << "Entering function: DSplitListWidget::getStatus";
    m_currentStatus.m_IsFirstFocus = this->m_IsFirstFocus;
    m_currentStatus.m_IsHalfWayFocus = this->m_IsHalfWayFocus;
    m_currentStatus.m_IsMouseClicked = this->m_IsMouseClicked;

    // qDebug() << "Exiting function: DSplitListWidget::getStatus";
    return m_currentStatus;
}

/*************************************************************************
 <Function>      setCurrentStatus
 <Description>   设置SplitListView的状态
 <Author>        null
 <Input>
    <param1>     currentStatus            Description:SplitListView的状态
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::setCurrentStatus(const FocusStatus &currentStatus)
{
    // qDebug() << "Entering function: DSplitListWidget::setCurrentStatus";
    m_currentStatus = currentStatus;
}

/*************************************************************************
 <Function>      mouseMoveEvent
 <Description>   鼠标移动事件
 <Author>        null
 <Input>
    <param1>     event            Description:鼠标移动事件
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::mouseMoveEvent(QMouseEvent *event)
{
    // qDebug() << "Entering function: DSplitListWidget::mouseMoveEvent";
    //正在安装过程中，禁止鼠标事件
    if (m_isIstalling) {
        // qDebug() << "m_isIstalling is true";
        return;
    }

    //更新用于判断是否弹出提示信息的鼠标状态标志位
    m_isMouseMoved = true;
    if (QToolTip::isVisible()) {
        // qDebug() << "QToolTip::isVisible is true";
        QToolTip::hideText();
    }

    QPoint difference_pos = event->pos() - lastTouchBeginPos;

    //通过亮的点的y值差距获得移动的趋势
    if (difference_pos.y() > 0) {
        // qDebug() << "difference_pos.y() > 0";
        m_IsPositive = true;
    } else {
        // qDebug() << "difference_pos.y() <= 0";
        m_IsPositive = false;
    }

    QPoint clickPoint = event->pos();
    QModelIndex modelIndex = indexAt(clickPoint);

    if (modelIndex.row() == 5)
        return;
    DListView::mouseMoveEvent(event);
    // qDebug() << "Exiting function: DSplitListWidget::mouseMoveEvent";
}

/*************************************************************************
 <Function>      setRefreshFinished
 <Description>   设置安装是否结束
 <Author>        null
 <Input>
    <param1>     isInstalling            Description:安装是否结束
 <Return>        null                    Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::setRefreshFinished(bool isInstalling)
{
    // qDebug() << "Entering function: DSplitListWidget::setRefreshFinished";
    if (isInstalling) {
        // qDebug() << "isInstalling is true";
        m_refreshFinished = false;
    } else {
        // qDebug() << "isInstalling is false";
        m_refreshFinished = true;
    }
    // qDebug() << "Exiting function: DSplitListWidget::setRefreshFinished";
}

/*************************************************************************
 <Function>      wheelEvent
 <Description>   滚轮事件
 <Author>        null
 <Input>
    <param1>     event            Description:滚轮事件
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::wheelEvent(QWheelEvent *event)
{
    // qDebug() << "Entering function: DSplitListWidget::wheelEvent";
    if (!m_refreshFinished)
        return;
    int now = -1;
    //bug47986处理方案中或出现选项在分隔符位置的场景，此时菜单选项为空，之前不需考虑为空的情况，所以需要增加以下判断
    //选项为空则当前位置为分隔符
    if (selectedIndexes().count() == 0)
        now = FTM_SPLIT_LINE_INDEX;
    else
        now = selectedIndexes().last().row();
    int next = now;
#if QT_VERSION_MAJOR > 5
    if (event->angleDelta().y() > 0) {
#else
    if (event->delta() > 0) {
#endif
        if (now > 0) {
            if (now == 6) {
                next = now - 2;
            } else {
                next = now - 1;
            }
        } else {
            return;
        }
    } else {
        if (now < this->count() - 1) {
            if (now == 4) {
                next = now + 2;
            } else {
                next = now + 1;
            }
        } else {
            return;
        }
    }
    if (next == now) {
        // qDebug() << "next == now";
        return;
    } else {
        // qDebug() << "next != now";
        this->setModel(m_categoryItemModell);
        QStandardItem *item = m_categoryItemModell->item(next);
        QModelIndex modelIndex = m_categoryItemModell->indexFromItem(item);
        setCurrentIndex(modelIndex);
        Q_EMIT m_signalManager->changeView();
        if (next > 5) {
            emit  onListWidgetItemClicked(next - 1);
        } else {
            emit  onListWidgetItemClicked(next);
        }
    }
    // qDebug() << "Exiting function: DSplitListWidget::wheelEvent";
}

/*************************************************************************
 <Function>      setCurrentPage
 <Description>   进行操作后切换到当前的页面
 <Author>        null
 <Input>
    <param1>     null            Description:null
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::setCurrentPage()
{
    qDebug() << "Entering function: DSplitListWidget::setCurrentPage";
    QModelIndex current = currentIndex();

    int row = current.row();
    qDebug() << __FUNCTION__ << row << m_LastPageNumber;
    if (row < 0 || FTM_SPLIT_LINE_INDEX == row || row == m_LastPageNumber) {
        // qDebug() << "row < 0 || FTM_SPLIT_LINE_INDEX == row || row == m_LastPageNumber, return";
        return;
    }

    m_LastPageNumber = row;
    QStandardItem *item = m_categoryItemModell->item(row);
    QVariant varUserData = item->data(Qt::DisplayRole).value<QVariant>();
    int realIndex = m_titleStringIndexMap.value(varUserData.toString());

    emit onListWidgetItemClicked(realIndex);
    emit m_signalManager->changeView();
    qDebug() << "Exiting function: DSplitListWidget::setCurrentPage";
}

/*************************************************************************
 <Function>      setLastPageNumber
 <Description>   记录当前界面的上一个界面
 <Author>        null
 <Input>
    <param1>     LastPageNumber            Description:当前界面的上一个界面
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::setLastPageNumber(int LastPageNumber)
{
    // qDebug() << "Entering function: DSplitListWidget::setLastPageNumber";
    m_LastPageNumber = LastPageNumber;
}

void DSplitListWidget::setIsIstalling(bool isIstalling)
{
    // qDebug() << "Entering function: DSplitListWidget::setIsIstalling";
    m_isIstalling = isIstalling;
}

/*************************************************************************
 <Function>      mouseReleaseEvent
 <Description>   鼠标释放事件
 <Author>        null
 <Input>
    <param1>     event           Description:事件对象
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::mouseReleaseEvent(QMouseEvent *event)
{
    // qDebug() << "Entering function: DSplitListWidget::mouseReleaseEvent";
    //TODO
    //正在安装过程中，禁止鼠标事件
    if (m_isIstalling)
        return;
    QPoint clickPoint = event->pos();
    QModelIndex modelIndex = indexAt(clickPoint);
    //  根据移动趋势进行移动到分割线时的处理
    if (modelIndex.row() == FTM_SPLIT_LINE_INDEX) {
        // qDebug() << "modelIndex.row() == FTM_SPLIT_LINE_INDEX";
        //
        if (m_IsPositive) {
            // qDebug() << "m_IsPositive is true";
            modelIndex = m_categoryItemModell->index(6, 0);
            setCurrentIndex(modelIndex);
        } else {
            // qDebug() << "m_IsPositive is false";
            modelIndex = m_categoryItemModell->index(4, 0);
            setCurrentIndex(modelIndex);
        }
    }
    setCurrentPage();

    //如果鼠标释放时，位置在有效菜单项，则延时弹出提示信息
    if (viewport()->visibleRegion().contains(event->pos())) {
        // qDebug() << "viewport()->visibleRegion().contains(event->pos())";
        //初始化鼠标状态标志位
        m_isMouseMoved = false;

        QModelIndex curIndex = indexAt(event->pos());
        QPoint showPoint = event->globalPos();
        const QString tooltip = curIndex.data(Qt::DisplayRole).toString();
        QTimer::singleShot(500, [ = ] {
            //如果悬停位置为空、位置为分割线或中途鼠标移动,不弹出提示信息
            if (tooltip.isEmpty() || tooltip == "_split_" || m_isMouseMoved == true)
                return;
            QToolTip::showText(showPoint, tooltip, this);
        });
    }

    DListView::mouseReleaseEvent(event);
    // qDebug() << "Exiting function: DSplitListWidget::mouseReleaseEvent";
}

/*************************************************************************
 <Function>      keyPressEvent
 <Description>   鼠标点击事件
 <Author>        null
 <Input>
    <param1>     event            Description:鼠标点击事件
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::keyPressEvent(QKeyEvent *event)
{
    // qDebug() << "Entering function: DSplitListWidget::keyPressEvent";
    if (event->key() == Qt::Key_Up) {
        // qDebug() << "event->key() == Qt::Key_Up";
        if (currentIndex().row() == 0) {
            // qDebug() << "currentIndex().row() == 0";
            QModelIndex modelIndex = m_categoryItemModell->index(7, 0);
            setCurrentIndex(modelIndex);
        } else {
            // qDebug() << "currentIndex().row() != 0";
            DListView::keyPressEvent(event);
        }
        setCurrentPage();
    } else if (event->key() == Qt::Key_Down) {
        // qDebug() << "event->key() == Qt::Key_Down";
        if (currentIndex().row() == 7) {
            // qDebug() << "currentIndex().row() == 7";
            QModelIndex modelIndex = m_categoryItemModell->index(0, 0);
            setCurrentIndex(modelIndex);
        } else {
            // qDebug() << "currentIndex().row() != 7";
            DListView::keyPressEvent(event);
        }
        setCurrentPage();
    } else if (event->key() == Qt::Key_End || event->key() == Qt::Key_Home) {
        // qDebug() << "event->key() == Qt::Key_End || event->key() == Qt::Key_Home";
        event->accept();
    } else {
        // qDebug() << "event->key() != Qt::Key_Up && event->key() != Qt::Key_Down && event->key() != Qt::Key_End && event->key() != Qt::Key_Home";
        DListView::keyPressEvent(event);
    }
    // qDebug() << "Exiting function: DSplitListWidget::keyPressEvent";
}

/*************************************************************************
 <Function>      eventFilter
 <Description>   事件过滤器
 <Author>        null
 <Input>
    <param1>     obj              Description:UNUSED
    <param2>     event            Description:事件
 <Return>        bool             Description:是否处理
 <Note>          null
*************************************************************************/
bool DSplitListWidget::eventFilter(QObject *obj, QEvent *event)
{
    // qDebug() << "Entering function: DSplitListWidget::eventFilter";
    Q_UNUSED(obj)

//失去焦点的时候对这几个标志位进行复位
    if (event->type() == QEvent::FocusOut) {
        m_IsMouseClicked = false;
        m_IsTabFocus = false;
        m_IsLeftFocus = false;
        m_IsHalfWayFocus = false;
    }

//获取焦点时只要不是通过鼠标点击获取焦点以及不是打开软件自动设置的焦点以及不是其他过程中途设置的焦点，就是判断为通过tab获取到的焦点
    if (event->type() == QEvent::FocusIn) {
        // qDebug() << m_isFocusFromFontListView;
        if (!m_IsMouseClicked && !m_IsFirstFocus && !m_IsHalfWayFocus && !m_isFocusFromFontListView) {
            m_IsTabFocus = true;
        }
//        m_IsFristTimeFocus = false;
        m_IsFirstFocus = false;
    }
    // qDebug() << "Exiting function: DSplitListWidget::eventFilter";
    return false;
}


/*************************************************************************
 <Function>      helpEvent
 <Description>   左侧列表hover现实提示信息.
 <Author>        null
 <Input>
    <param1>     event             Description:QHelpEvent
    <param2>     view              Description:listview
    <param3>     option            Description:当前项
    <param4>     index             Description:当前项的索引
 <Return>        bool              Description:委托可以处理该事件，则返回true;否则返回false
 <Note>          null
*************************************************************************/
bool DNoFocusDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view
                                 , const QStyleOptionViewItem &option, const QModelIndex &index)
{
    // qDebug() << "Entering function: DNoFocusDelegate::helpEvent";
    QToolTip::hideText();
    if (event->type() == QEvent::ToolTip) {
        // qDebug() << "event->type() == QEvent::ToolTip";
        const QString tooltip = index.data(Qt::DisplayRole).toString();
        // qDebug() << __FUNCTION__ << "__now Hover is :__" << tooltip;
        if (tooltip.isEmpty() || tooltip == "_split_") {
            hideTooltipImmediately();
        } else {
            // qDebug() << "tooltip is not empty and not _split_";
            int tooltipsize = tooltip.size();
            const int nlong = 32;
            int lines = tooltipsize / nlong + 1;
            QString strtooltip;
            for (int i = 0; i < lines; ++i) {
                strtooltip.append(tooltip.mid(i * nlong, nlong));
                strtooltip.append("\n");
            }
            strtooltip.chop(1);
//            QTimer::singleShot(1000, [ = ]() {
            QToolTip::showText(event->globalPos(), strtooltip, view);

//            QTimer::singleShot(500, []() {
//                QToolTip::hideText();
//            });
//            });
        }
        return false;
    }
    // qDebug() << "Exiting function: DNoFocusDelegate::helpEvent";
    return DNoFocusDelegate::helpEvent(event, view, option, index);
}

/*************************************************************************
 <Function>      hideTooltipImmediately
 <Description>   隐藏提示信息
 <Author>        null
 <Input>
    <param1>     null            Description:null
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DNoFocusDelegate::hideTooltipImmediately()
{
    // qDebug() << "Entering function: DNoFocusDelegate::hideTooltipImmediately";
    QWidgetList qwl = QApplication::topLevelWidgets();
    for (QWidget *qw : qwl) {
        if (QStringLiteral("QTipLabel") == qw->metaObject()->className()) {
            qw->close();
        }
    }
    // qDebug() << "Exiting function: DNoFocusDelegate::hideTooltipImmediately";
}

/*************************************************************************
 <Function>      mousePressEvent
 <Description>   鼠标点击事件
 <Author>        null
 <Input>
    <param1>     event            Description:鼠标点击事件
 <Return>        null            Description:null
 <Note>          null
*************************************************************************/
void DSplitListWidget::mousePressEvent(QMouseEvent *event)
{
    // qDebug() << "Entering function: DSplitListWidget::mousePressEvent";
    QPoint clickPoint = event->pos();
    QModelIndex modelIndex = indexAt(clickPoint);

    m_IsMouseClicked = true;
    //正在安装过程中，禁止鼠标事件
    if (Qt::RightButton == event->button() || Qt::MiddleButton == event->button() || m_isIstalling) {
        // qDebug() << "Qt::RightButton == event->button() || Qt::MiddleButton == event->button() || m_isIstalling, return";
        return;
    }

    //鼠标按下时记录点击的点，用作后面获得移动的趋势
    lastTouchBeginPos = event->pos();

    //应该设置焦点，否则鼠标在其他区域release会导致缺失焦点。
    //    setFocus(Qt::MouseFocusReason);
    if (modelIndex.row() == currentIndex().row())
        return;
    //ut000465根据产品要求左侧列表点击不做focus效果处理，因此即使左侧列表通过tab获取焦点，点击后去除tabfocus状态，不绘制focus选中边框
    if (hasFocus() && m_IsTabFocus) {
        // qDebug() << "hasFocus() && m_IsTabFocus, m_IsTabFocus = false";
        m_IsTabFocus = false;
    }
    DListView::mousePressEvent(event);
    // qDebug() << "Exiting function: DSplitListWidget::mousePressEvent";
}
