#include "syschartnavigation.h"
#include <QDockWidget>
#include <QToolBar>
#include <QCompleter>
#include <QScriptValue>
#include <QVBoxLayout>
#include <QUrl>
#include <QDebug>
#include <QFileDialog>
#include <QDesktopServices>
#include <QTextDocument>
#include <QTextBlock>
#include <QPdfWriter>
#include <QPainter>
#include <topcore/topcore.h>
#include <topcore/topclasssqlthread.h>
#include <tbaseutil/ttheme.h>
#include <tbaseutil/tresource.h>
#include <tbaseutil/tconcurrent.h>
#include <tbaseutil/tdataparse.h>
#include <tbaseutil/tdataresponse.h>
#include <tbaseutil/tfileio.h>
#include <tbaseutil/tscriptengine.h>
#include <toputil/t.h>
#include <tdatabaseutil/tsqlconnectionpoolv2.h>
#include <tdatabaseutil/tsqlqueryv2.h>
#include <tdatabaseutil/tsqlselectorv2.h>
#include <twidget/tdialog.h>
#include <twidget/tmessagebox.h>
#include <twidget/ttableviewdialog.h>
#include <twidget/tsplitter.h>
#include <twidget/ttableview.h>
#include <twidget/tsearchentry.h>
#include <twidget/tlabel.h>
#include <twidget/tuiloader.h>
#include <twidget/tcombobox.h>
#include <twidget/tmulticombobox.h>
#include <twidget/tpushbutton.h>
#include <twidget/tgridlayout.h>
#include <twidget/tscrollarea.h>
#include <twidget/taccordion.h>
#include <twidget/tfiledialog.h>
#include <tchart/tchartwidget.h>
#include <tchart/tchartstore.h>
#include <tchart/tchartaxisnumeric.h>
#include <texcelxs/excelobject.h>
#include <texcelxs/book.h>
#include <texcelxs/sheet.h>
#include <texcelxs/format.h>
#include <texcelxs/font.h>
#include <texcelxs/range.h>
#ifdef Q_OS_WIN32
#include <QAxObject>
#include <tole/texcel.h>
#endif

SysChartNavigation::SysChartNavigation(const QString &iModuleName, const QVariantMap &iUrlPars, QWidget *iParent)
    : TopClassAbs(iParent)
{
    setLicenseKey("sys_common");
    initModule(iModuleName,iUrlPars);
    initUi();
    this->refreshActionState();
}

SysChartNavigation::~SysChartNavigation()
{
}

void SysChartNavigation::onSearch()
{
    if (this->uid().isEmpty()) return;

    QVariantList errs = mUiLoader->validateAll("COMMIT", true, "ERROR");
    if (!errs.isEmpty()) {
        QStringList err_str;
        for (QVariant &err: errs) {
            err_str.append(err.toMap().value("text").toString());
        }
        TMessageBox::error(this, ttr("Error"), err_str.join("\n"));
        return;
    }

    t::loading(this, "", -1, 0);
    QVariantMap uiData = mUiLoader->getAllValues(true).toVariant().toMap();
    QString funcJsonData = TDataParse::variant2JsonStr(uiData);

    // 生成图表
    TSqlSelectorV2 selector;
    selector.setTable("pub_chart_navigation");
    selector.setField("graph_layout");
    selector.setWhere("id", this->uid());
    QVariant dataRet = doThreadWork(new TopClassSqlThread(this), TOPSQLTHREAD_SELECT_VALUE, QVariant::fromValue(selector));
    TDataResponse dataRes(dataRet.toMap());
    if (dataRes.hasError()) {
        unloading();
        alertError(ttr("Load data failed!"), dataRes.errText());
        return;
    }
    QString graphLayoutStr = dataRes.data().toString();
    TError error;
    QVariantMap graphLayoutMap = TDataParse::jsonStr2Variant(graphLayoutStr, &error).toMap();
    if (error.isValid()) {
        unloading();
        alertError(ttr("Error"), error.text());
        return;
    }
    mDataSrcRetCache.clear();
    mDataSrcRetCacheUiLoader.clear();
    mDataSrcRetStrCache.clear();
    // 图片布局种类。是GrdiLayout还是VBoxLayout还是HBoxLayout
    QString graphLayoutType = graphLayoutMap.value("type").toString().trimmed().toLower();
    QVariantList graphList = graphLayoutMap.value("child").toList();
    if (graphLayoutType == "gridlayout") {
        if (!mChartListWgt->layout()) {
            TGridLayout *chartLayout = new TGridLayout();
            chartLayout->setContentsMargins(2, 2, 2, 8);
            mChartListWgt->setLayout(chartLayout);
        }
        for (QVariant &item : graphList) {
            QVariantMap itemMap = item.toMap();
            QString graphName = itemMap.value("name").toString().trimmed();
            QString graphType = itemMap.value("type").toString().trimmed().toLower();
            QVariantMap packMap = itemMap.value("pack").toMap();

            selector.clear();
            selector.setTable("pub_chart_graph");
            selector.setField(QStringList()<<"id"<<"dynamic");
            selector.setWhere("name", graphName);
            QVariant dataRetp = doThreadWork(new TopClassSqlThread(this), TOPSQLTHREAD_SELECT_MAP, QVariant::fromValue(selector));
            TDataResponse dataResp(dataRetp.toMap());
            if (dataResp.hasError()) {
                unloading();
                alertError(ttr("Load data failed!"), dataResp.errText());
                return;
            }
            QVariantMap graphMap = dataResp.data().toMap();
            if (graphType == "uiloader") {
                generateUiLoader(graphMap.value("id").toInt(), funcJsonData, packMap, "gridlayout");
            } else {
                if (graphMap.value("dynamic").toInt() == 1) {
                    dynamicGenerateChart(graphMap.value("id").toInt(), funcJsonData, packMap, "gridlayout");
                } else {
                    configGenerateChart(graphMap.value("id").toInt(), funcJsonData, packMap, "gridlayout");
                }
            }
        }
    } else if (graphLayoutType == "hboxlayout") {
    } else if (graphLayoutType == "vboxlayout") {
    }
    unloading();
}

void SysChartNavigation::onClear()
{
    if (mUiLoader != nullptr){
        mUiLoader->loadValues(QVariantMap());
    }
    if (mChartListWgt != nullptr) {
        for (TChartWidget *wid: mChartMap.values()) {
            if (wid) {
                wid->setParent(nullptr);
                wid->deleteLater();
                wid = nullptr;
            }
        }
        mChartMap.clear();
        mChartParameterRemarkMap.clear();
        for (QScrollArea *wid: mChartAreaMap.values()) {
            if (wid) {
                wid->setParent(nullptr);
                wid->deleteLater();
                wid = nullptr;
            }
        }
        mChartAreaMap.clear();
        for (TUiLoader *loader: mUiLoaderMap.values()) {
            if (loader) {
                loader->setParent(nullptr);
                loader->deleteLater();
                loader = nullptr;
            }
        }
        mUiLoaderMap.clear();
        mUiLoaderParamRemarkMap.clear();
    }
    mChartVisibleData.clear();
}

void SysChartNavigation::onDoubleClicked()
{
    if (TChartWidget* chartWgt = qobject_cast<TChartWidget*>(sender())) {
        TChartWidget* newChartWgt = new TChartWidget();
        newChartWgt->setAttribute(Qt::WA_DeleteOnClose, true);
        newChartWgt->setConfig(chartWgt->config());
        newChartWgt->setStore(chartWgt->store());
        newChartWgt->setWindowModality(Qt::ApplicationModal);
        newChartWgt->showMaximized();
    }
}

void SysChartNavigation::onExportPdfClicked(const QString &iFileStr)
{
    if (mChartMap.size() == 0 && mUiLoaderMap.size() == 0) {
        TMessageBox::error(this, ttr("Error"), ttr("No chart to export"));
        return;
    }
    QString filePath;
    if (iFileStr.isEmpty()) {
        filePath = "D://report.pdf";
    } else {
        filePath = "D://" + iFileStr;
    }

    QString outputFile = QFileDialog::getSaveFileName(this, ttr("Save File"), filePath, "*.pdf");
    if (outputFile.isEmpty()) {
        return;
    }

    QList<TChartWidget* > chartList = mChartMap.values();
    QPrinter printer;
    printer.setOutputFormat(QPrinter::PdfFormat);
    printer.setPageSize(pageTypeToEnum(mSizeComboBox->currentName()));
    printer.setOutputFileName(outputFile);

    int spacing = 20;
    int chartWidth = printer.width();
    int chartHeight = (printer.height() - spacing)/2;
    QPainter painter;
    painter.begin(&printer);
    int y = 0;
    for (TChartWidget* chart: chartList) {
        if (y + chartHeight > printer.height() ) {
            y = 0;
            printer.newPage();
        }
        QRect rect = QRect(0, y, chartWidth, chartHeight);
        chart->draw(painter, rect);
        y += chartHeight + spacing;
    }

    // UiLoader中的表格数据
    QList<TUiLoader*> uiloaderList = mUiLoaderMap.values();
    for (TUiLoader *uiloader: uiloaderList) {
        QList<TTableView*> tableviewList;
        QObjectList objectList = uiloader->getAllObject();
        for (QObject *obj: objectList) {
            if (TTableView *view = qobject_cast<TTableView*>(obj)) {
                tableviewList.append(view);
            }
        }
        for (TTableView *view: tableviewList) {
            QVariantList headerItems = view->headerItem();
            QVariantList dataList = view->allDataMap();
            QStringList field_text_list;
            QStringList field_name_list;
            for (QVariant var: headerItems) {
                QVariantMap headerMap = var.toMap();
                QString name = headerMap.value("name").toString();
                if (!name.isEmpty()) {
                    QString text = headerMap.value("display").toString();
                    QString realName = headerMap.value("displayRole").toString();
                    realName.remove("$");
                    field_name_list.append(realName);
                    field_text_list.append(text);
                }
            }
            QString html = QString("<table width='%1' border='1' align='center' frame='border' cellspacing='0' cellpadding='3px' rules='all'>").arg(printer.width());
            html += "<tr>";
            //表头字段
            for (QString ti: field_text_list) {
                html += QString("<th>%1</th>").arg(ti);
            }
            html += "</tr>";
            // 数据
            for (int i = 0; i < dataList.size(); ++i) {
                QVariantMap rowMap = dataList.at(i).toMap();
                html += "<tr>";
                for (QString name: field_name_list) {
                    QString text = rowMap.value(name).toString();
                    html += QString("<td>%1</td>").arg(text);
                }
                html += "</tr>";
            }
            html += "</table>";
            printer.newPage();
            QTextDocument textDoc;
            textDoc.setHtml(html);
            textDoc.drawContents(&painter);
            textDoc.end();
        }
    }
    painter.end();
    t::msgBoxExport(outputFile);
}

void SysChartNavigation::onExportExcelClicked(const QString &iFileStr)
{
    if (mChartMap.size() == 0 && mUiLoaderMap.size() == 0) {
        t::msgBoxError(ttr("No chart to export"));
        return;
    }
    // Get save path
    QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    if (iFileStr.isEmpty()) {
        defaultPath += "/" + mNaviName + " " + APP->getToday() + ".xlsx";
    } else {
        defaultPath += "/" + iFileStr;
    }
    QString filePath = TFileDialog::getSaveFileName(this, ttr("Export Excel"), defaultPath, "Excel Files (*.xlsx *.xls)");
    if (filePath.isEmpty()) {
        return;
    }
    // Init Book/Sheet
    Book *book = new Book;
    bool isOk = book->create(filePath);
    if (!isOk) {
        t::msgBoxError(ttr("Create file failed!"));
        return;
    }
    QString sheetName = "Sheet1";
    Sheet *sheet = book->addSheet(sheetName);
    if (sheet->isNull()) {
        t::msgBoxError(ttr("Add sheet failed!"));
        return;
    }
    this->setDisabled(true);
    int curRow = 0;
    // Filter Data
    QVariantMap filterData = mUiLoader->getAllValues().toVariant().toMap();
    QList<QWidget*> wgtList = mUiLoader->findChildren<QWidget*>();
    if (!filterData.isEmpty()) {
        Format *fmtFilterHeader = book->addFormat();
        Font *fontTitle = book->addFont();
        fontTitle->setName("Microsoft YaHei");
        fontTitle->setSize(11);
        fontTitle->setColor(50, 50, 50);
        fmtFilterHeader->setFont(fontTitle);
        fmtFilterHeader->setAlignH("CENTER");
        fmtFilterHeader->setAlignV("CENTER");
        fmtFilterHeader->setBorder("THIN");
        fmtFilterHeader->setBorderColor("#0070C0");
        fmtFilterHeader->setFillPattern("SOLID");
        fmtFilterHeader->setPatternForegroundColor("#F8F8F8");
        Format *fmtFilterData = book->addFormat();
        Font *fontData = book->addFont();
        fontData->setName("Microsoft YaHei");
        fontData->setSize(10);
        fontData->setColor(50, 50, 50);
        fmtFilterData->setFont(fontData);
        fmtFilterData->setBorder("THIN");
        fmtFilterData->setBorderColor("#0070C0");
        fmtFilterData->setFillPattern("SOLID");
        fmtFilterData->setPatternForegroundColor("#F8F8F8");
        fmtFilterData->setAlignV("TOP");
        fmtFilterData->setWrap(true);
        int curFilterCol = 0;
        for (QWidget *tmpObj: wgtList) {
            QString objName = tmpObj->objectName();
            if (filterData.contains(objName)) {
                QString val = filterData.value(objName).toString().trimmed();
                QObject *tmpObj = mUiLoader->getObject(objName);
                if (TComboBox *cmbox = qobject_cast<TComboBox*>(tmpObj)) {
                    val = cmbox->currentText();
                } else if (TMultiComboBox *mcmbox = qobject_cast<TMultiComboBox*>(tmpObj)) {
                    val = mcmbox->currentTexts().join(",");
                }
                QString title = mUiLoader->getTitle(objName).toString();
                sheet->setCellValue(curRow, curFilterCol, title, "", fmtFilterHeader);
                sheet->setCellValue(curRow + 1, curFilterCol, val, "", fmtFilterData);
                curFilterCol++;
            }
        }
        curRow = curRow + 3;
    }
    // Chart Data
    QList<TChartWidget* > chartWidgetList = mChartMap.values();
    for (TChartWidget* chartWidget : chartWidgetList) {
        QString parameterRemark = mChartParameterRemarkMap.value(chartWidget);
        QVariantMap parameterRemarkMap = TDataParse::jsonStr2Variant(parameterRemark).toMap();
        QString title = chartWidget->title();
        TChartStore* chartStore = chartWidget->store();
        QStringList dataKeyList = chartStore->dataKeyList();
        QVariantList dataList = chartStore->dataList();
        QStringList field_text_list;
        for (QString dataKey : dataKeyList) {
            QString realDataKey = dataKey;
            QString parameterRemarkItem = parameterRemarkMap.value(dataKey).toString().trimmed();
            if (!parameterRemarkItem.isEmpty()) {
                realDataKey = parameterRemarkItem;
            }
            field_text_list.push_back(realDataKey);
        }
        // Title
        if (!title.isEmpty()) {
            Format *formatTitle = book->addFormat();
            Font *fontTitle = book->addFont();
            fontTitle->setName("Microsoft YaHei");
            fontTitle->setSize(15);
            fontTitle->setBold(true);
            formatTitle->setFont(fontTitle);
            formatTitle->setAlignH("CENTER");
            formatTitle->setAlignV("CENTER");
            formatTitle->setBorder("THIN");
            formatTitle->setBorderColor("#0070C0");
            sheet->setCellValue(curRow, 0, title, "", formatTitle);
            sheet->setMerge(curRow, curRow, 0, field_text_list.size() - 1);
            sheet->setRows(0, 0, 28);
            curRow++;
        }
        // Header
        Format *formatHeader = book->addFormat();
        Font *fontHeader = book->addFont();
        fontHeader->setName("Microsoft YaHei");
        fontHeader->setSize(12);
        fontHeader->setBold(true);
        formatHeader->setFont(fontHeader);
        formatHeader->setAlignH("CENTER");
        formatHeader->setAlignV("CENTER");
        formatHeader->setBorder("THIN");
        formatHeader->setBorderColor("#0070C0");
        formatHeader->setFillPattern("SOLID");
        formatHeader->setPatternForegroundColor("#C4D79B");
        for (int col = 0; col < field_text_list.size(); col++) {
            sheet->setCellValue(curRow, col, field_text_list.value(col), "", formatHeader);
        }
        curRow++;
        // Data
        Format *formatData = book->addFormat();
        Font *fontData = book->addFont();
        fontData->setName("Microsoft YaHei");
        fontData->setSize(12);
        formatData->setFont(fontData);
        formatData->setBorder("THIN");
        formatData->setBorderColor("#0070C0");
        for (int i = 0; i < dataList.size(); i++) {
            QVariantList rowDataList = dataList.value(i).toList();
            for (int col = 0; col < rowDataList.size(); col++) {
                QString val = rowDataList.value(col).toString().trimmed();
                sheet->setCellValue(curRow, col, val, "", formatData);
            }
            qDebug()<<"rowszie: "<<rowDataList.size();
            curRow++;
        }
        curRow++;
    }
    // UiLoader's table
    // 将表头解析成name列表,text列表
    std::function<void(const QVariantList&, QStringList &, QStringList &)> parseHeaderItems = [](const QVariantList &iHeaderItems,
            QStringList &iFieldNameList, QStringList &iFieldTextList) {
        for (QVariant var: iHeaderItems) {
            QVariantMap headerMap = var.toMap();
            QString name = headerMap.value("name").toString();
            if (!name.isEmpty()) {
                QString text = headerMap.value("display").toString();
                QString realName = headerMap.value("displayRole").toString();
                realName.remove("$");
                iFieldNameList.append(realName);
                iFieldTextList.append(text);
            }
        }
    };
    // 将树形的数据转为表格数据
    std::function<QVariantList(const QVariantList &)> extract = [&](const QVariantList &iDataList)
    {
        QVariantList retList;
        for (QVariant var : iDataList) {
            retList.append(var);
            QVariantList subList = var.toMap().value("CHILDREN").toList();
            if (!subList.isEmpty()) {
                retList.append(extract(subList));
            }
        }
        return retList;
    };
    QList<TUiLoader*> uiloaderList = mUiLoaderMap.values();
    for (TUiLoader *uiloader: uiloaderList) {
        QList<QAbstractItemView*> itemViewList;
        QObjectList objectList = uiloader->getAllObject();
        for (QObject *obj: objectList) {
            if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(obj)) {
                itemViewList.append(view);
            }
        }
        for (QAbstractItemView *view: itemViewList) {
            QVariantList dataList;
            QVariantList headerItems;
            QStringList field_text_list;
            QStringList field_name_list;

            // Header
            Format *formatHeader = book->addFormat();
            Font *fontHeader = book->addFont();
            fontHeader->setName("Microsoft YaHei");
            fontHeader->setSize(12);
            fontHeader->setBold(true);
            formatHeader->setFont(fontHeader);
            formatHeader->setAlignH("CENTER");
            formatHeader->setAlignV("CENTER");
            formatHeader->setBorder("THIN");
            formatHeader->setBorderColor("#0070C0");
            formatHeader->setFillPattern("SOLID");
            formatHeader->setPatternForegroundColor("#C4D79B");
            // TTableView 和 TTreeView表头配置不一样,因此代码分开处理
            if (TTableView *tableView = qobject_cast<TTableView*>(view)) {
                dataList = tableView->allDataMap();
                headerItems = tableView->headerItem();
                QVariantList rawHeaderItems = tableView->initialHeaderItem();
                // TTableView表头配置中第一列为列头,暂未使用
                headerItems.removeFirst();
                parseHeaderItems(headerItems, field_name_list, field_text_list);
                rawHeaderItems.removeFirst();
                int tmpCol = 0;
                int depth = calcTreeDepth(rawHeaderItems);
                curRow += depth;
                for (QVariant var: rawHeaderItems) {
                    curRow -= depth;
                    QVariantMap varMap = var.toMap();
                    sheet->setCellValue(curRow, tmpCol, varMap.value("display").toString(), "", formatHeader);
                    QVariantList children = varMap.value("children").toList();
                    int filledHeight = 0;
                    if (children.size() == 0) {
                        filledHeight = depth - 1;
                    }
                    int width = calcTreeLeafSize(varMap);
                    sheet->setMerge(curRow, curRow + filledHeight, tmpCol, tmpCol + width - 1);
                    int subRow = curRow;
                    while(1) {
                        QVariantList tmpChildren;
                        if (children.size() > 0) {
                            subRow++;
                            int subCol = tmpCol;
                            for (QVariant item: children) {
                                QVariantMap itemMap = item.toMap();
                                sheet->setCellValue(subRow, subCol, itemMap.value("display").toString(), "", formatHeader);
                                QVariantList tmpList = itemMap.value("children").toList();
                                int tmpWidth = calcTreeLeafSize(itemMap);
                                int tmpFilledHeight = 0;
                                if (tmpList.size() == 0) {
                                    tmpFilledHeight = curRow + depth - subRow - 1;
                                } else {
                                    tmpChildren.append(tmpList);
                                }
                                sheet->setMerge(subRow, subRow + tmpFilledHeight, subCol, subCol + tmpWidth - 1);
                                subCol += tmpWidth;
                            }
                        }
                        children = tmpChildren;
                        if (children.size() == 0) {
                            break;
                        }
                    }
                    tmpCol += width;
                    curRow += depth;
                }
            } else if (TTreeView *treeView = qobject_cast<TTreeView*>(view)) {
                dataList = extract(treeView->allDataMap());
                headerItems = treeView->headerItem();
                parseHeaderItems(headerItems, field_name_list, field_text_list);
                int tmpCol = 0;
                for (QString field : field_text_list) {
                    sheet->setCellValue(curRow, tmpCol, field, "", formatHeader);
                    tmpCol++;
                }
                curRow++;
            }

            // Data
            Format *formatData = book->addFormat();
            Font *fontData = book->addFont();
            fontData->setName("Microsoft YaHei");
            fontData->setSize(12);
            formatData->setFont(fontData);
            formatData->setBorder("THIN");
            formatData->setBorderColor("#0070C0");
            for (int i = 0; i < dataList.size(); i++) {
                QVariantMap rowMap = dataList.value(i).toMap();
                int col = 0;
                for (QString name: field_name_list) {
                    QString val = rowMap.value(name).toString().trimmed();
                    sheet->setCellValue(curRow, col++, val, "", formatData);
                }
                curRow++;
            }
            curRow++;
        }
    }
    sheet->setAutoFitArea();
    this->setDisabled(false);
    book->save();
    book->close();

    if (isHookExists("handleExcel")) {
        callHooksQuick("handleExcel", QVariantList() << QVariant(filePath));
    }
    t::msgBoxExport(filePath);
}

void SysChartNavigation::onExportExcelClickedOld()
{
#ifdef Q_OS_WIN32
    if (mChartMap.size() == 0 && mUiLoaderMap.size() == 0) {
        TMessageBox::error(this, ttr("Error"), ttr("No chart to export"));
        return;
    }
    this->setDisabled(true);
    TExcel *excel = new TExcel(this);
    excel->setExcelVisible(true);
    excel->addBook();

    QList<TChartWidget* > chartWidgetList = mChartMap.values();
    int sheetIndex = 1;
    // Chart数据
    for (TChartWidget* chartWidget : chartWidgetList) {
        QString parameterRemark = mChartParameterRemarkMap.value(chartWidget);
        QVariantMap parameterRemarkMap = TDataParse::jsonStr2Variant(parameterRemark).toMap();

        QString title = chartWidget->title();
        qDebug() << "===== title " << title;
        TChartStore* chartStore = chartWidget->store();
        QStringList dataKeyList = chartStore->dataKeyList();
        QVariantList dataList = chartStore->dataList();

        QStringList field_text_list;
        for (QString dataKey : dataKeyList) {
            QString realDataKey = dataKey;
            QString parameterRemarkItem = parameterRemarkMap.value(dataKey).toString().trimmed();
            if (!parameterRemarkItem.isEmpty()) {
                realDataKey = parameterRemarkItem;
            }
            field_text_list.push_back(realDataKey);
        }

        if (excel->getSheetsCount() < sheetIndex) {
            excel->appendSheet(title);
        }
        excel->selectSheet(sheetIndex);
        excel->setSheetName(sheetIndex, title);

        //标题
        QVariantMap title_fontmap;
        title_fontmap.insert("Size",15);
        title_fontmap.insert("Bold",true);
        QString title_range;
        if (field_text_list.count() <= 26)
            title_range = QString("A1:%1").arg(QString(QChar(field_text_list.count() + 'A' - 1))) + "1";
        else
            title_range = QString("A1:%1%2").arg(QString(QChar(field_text_list.count()/26 + 'A' - 1)))
                          .arg(QString(QChar(field_text_list.count()%26 + 'A' - 1))) + "1";

        excel->mergeRange(title_range);
        excel->setRangeValue(title_range,title);
        excel->setRangeHorizontalAlignment(title_range,-4108);//-4108 x1center 水平居中
        excel->setRangeFont(title_range,title_fontmap);

        // 数据
        for (int i = 0; i < dataList.size(); ++i) {
            QVariantList rowItemList = dataList.at(i).toList();
            for (int p = 0; p < rowItemList.size(); ++p) {
                QAxObject *cell = excel->getCell(i + 3, p + 1);
                excel->setCellValue(cell, rowItemList.at(p).toString().trimmed());
            }
        }

        //表头字段
        for(int i = 0; i < field_text_list.count(); ++i) {
           QString range;
           if (i < 26)
               range = QString("%1").arg(QString(QChar(i + 'A')) + "2");
           else {
               range = QString("%1%2")
                       .arg(QString(QChar(i/26 + 'A' - 1)))
                       .arg(QString(QChar(i%26 + 'A')) + "2");
           }
           excel->setRangeValue(range,field_text_list.at(i));
           excel->setRangeHorizontalAlignment(range,-4108);//-4108 x1center 水平居中
           QVariantMap font_map;
           font_map.insert("Size",12);
           font_map.insert("Bold",true);
           font_map.insert("Color",QColor(255, 255, 255)); //表头字段字体设为白色
           excel->setRangeFont(range,font_map);
           excel->setRangeBackgroundColor(range,QColor(100,204,51,255)); //背景色设为绿色
           if(i < 26)
               excel->autoFitColumns(QString(QChar(i + 'A')));
           else
               excel->autoFitColumns(QString("%1%2").arg(QString(QChar(i/26 + 'A' - 1))).arg(QString(QChar(i%26 + 'A' - 1))));
        }

        //边框
        int row = excel->getUsedRows();
        int column = excel->getUsedColumns();
        QString rangecolunmn ;
        if (column <= 26)
            rangecolunmn = QString("%1").arg(QString(QChar(column + 'A' - 1)));
        else
            rangecolunmn = QString("%1%2").arg(QString(QChar(column/26 + 'A' - 1)))
                           .arg(QString(QChar(column%26 + 'A' - 1)));

        QString used_range = QString("A1:%1%2").arg(rangecolunmn).arg(row);
        QAxObject * range = excel->getRange(used_range);
        QAxObject* border = range->querySubObject("Borders");
        border->setProperty("Color", QColor(0, 0, 255));   //设置单元格边框色(蓝色)

        sheetIndex++;
    }
    // UiLoader中的表格数据
    QList<TUiLoader*> uiloaderList = mUiLoaderMap.values();
    int tableCount = 1;
    for (TUiLoader *uiloader: uiloaderList) {
        QList<TTableView*> tableviewList;
        QObjectList objectList = uiloader->getAllObject();
        for (QObject *obj: objectList) {
            if (TTableView *view = qobject_cast<TTableView*>(obj)) {
                tableviewList.append(view);
            }
        }
        for (TTableView *view: tableviewList) {
            QVariantList headerItems = view->headerItem();
            QVariantList dataList = view->allDataMap();

            QStringList field_text_list;
            QStringList field_name_list;
            for (QVariant var: headerItems) {
                QVariantMap headerMap = var.toMap();
                QString name = headerMap.value("name").toString();
                if (!name.isEmpty()) {
                    QString text = headerMap.value("display").toString();
                    QString realName = headerMap.value("displayRole").toString();
                    realName.remove("$");
                    field_name_list.append(realName);
                    field_text_list.append(text);
                }
            }

            if (excel->getSheetsCount() < sheetIndex) {
                excel->appendSheet(ttr("Table") + QString("%1").arg(tableCount));
            } else {
                excel->setSheetName(sheetIndex, ttr("Table") + QString("%1").arg(tableCount));
            }
            excel->selectSheet(sheetIndex);
            tableCount++;
            //表头字段
            for(int i = 0; i < field_text_list.count(); ++i) {
               QString range;
               if (i < 26)
                   range = QString("%1").arg(QString(QChar(i + 'A')) + "1");
               else {
                   range = QString("%1%2")
                           .arg(QString(QChar(i/26 + 'A' - 1)))
                           .arg(QString(QChar(i%26 + 'A')) + "1");
               }
               excel->setRangeValue(range,field_text_list.at(i));
               excel->setRangeHorizontalAlignment(range,-4108);//-4108 x1center 水平居中
               QVariantMap font_map;
               font_map.insert("Size",12);
               font_map.insert("Bold",true);
               font_map.insert("Color",QColor(255, 255, 255)); //表头字段字体设为白色
               excel->setRangeFont(range,font_map);
               excel->setRangeBackgroundColor(range,QColor(100,204,51,255)); //背景色设为绿色
               if(i < 26)
                   excel->autoFitColumns(QString(QChar(i + 'A')));
               else
                   excel->autoFitColumns(QString("%1%2").arg(QString(QChar(i/26 + 'A' - 1))).arg(QString(QChar(i%26 + 'A' - 1))));
            }
            // 数据
            for (int i = 0; i < dataList.size(); ++i) {
                QVariantMap rowMap = dataList.at(i).toMap();
                int p = 0;
                for (QString name: field_name_list) {
                    QString text = rowMap.value(name).toString();
                    QAxObject *cell = excel->getCell(i + 2, p + 1);
                    excel->setCellValue(cell, text);
                    p++;
                }
            }
            //边框
            int row = excel->getUsedRows();
            int column = excel->getUsedColumns();
            QString rangecolunmn ;
            if (column <= 26)
                rangecolunmn = QString("%1").arg(QString(QChar(column + 'A' - 1)));
            else
                rangecolunmn = QString("%1%2").arg(QString(QChar(column/26 + 'A' - 1)))
                               .arg(QString(QChar(column%26 + 'A' - 1)));

            QString used_range = QString("A1:%1%2").arg(rangecolunmn).arg(row);
            QAxObject * range = excel->getRange(used_range);
            QAxObject* border = range->querySubObject("Borders");
            border->setProperty("Color", QColor(0, 0, 255));   //设置单元格边框色(蓝色)

            sheetIndex++;
        }
    }
    this->setDisabled(false);
    TMessageBox::ok(this, ttr("Export Excel Success"));
#endif
}

void SysChartNavigation::graphOnly(int iMode)
{
    if (iMode == 0) {
        if (QToolBar *toolbar = qobject_cast<QToolBar*>(uim()->getWidget("MAIN_TOOLBAR"))) {
            mUiLoaderLayout->removeWidget(toolbar);
            toolbar->clear();
            toolbar->hide();
        }
        if (QToolBar *toolbar = qobject_cast<QToolBar*>(uim()->getWidget("SUB_TOOLBAR"))) {
            mUiLoaderLayout->insertWidget(0, toolbar, 1, Qt::AlignTop);
        }
    } else if (iMode == 1) {
    }
}

void SysChartNavigation::setChartVisibleData(const QVariantMap &iDataMap)
{
    mChartVisibleData = iDataMap;
}

QVariantMap SysChartNavigation::chartVisibleData()
{
    return mChartVisibleData;
}

TUiLoader *SysChartNavigation::uiloader()
{
    return mUiLoader;
}

QString SysChartNavigation::currentNaviName()
{
    return mNaviName;
}

void SysChartNavigation::uidChangeEvent(const QString &iUidStr)
{
    if (mUiLoader != nullptr){
        mUiLoader->setParent(nullptr);
        mUiLoader->deleteLater();
        mUiLoader = nullptr;
    }

    if (mScrollArea != nullptr) {
        mScrollArea->setParent(nullptr);
        mScrollArea->deleteLater();
        mScrollArea = nullptr;
    }

    if (mChartListWgt != nullptr) {
        mChartListWgt->deleteLater();
        mChartListWgt = nullptr;
        for (TChartWidget *wid: mChartMap.values()) {
            if (wid) {
                wid->setParent(nullptr);
                wid->deleteLater();
                wid = nullptr;
            }
        }
        mChartMap.clear();
        mChartParameterRemarkMap.clear();
        for (QScrollArea *wid: mChartAreaMap.values()) {
            if (wid) {
                wid->setParent(nullptr);
                wid->deleteLater();
                wid = nullptr;
            }
        }
        mChartAreaMap.clear();
        for (TUiLoader *loader: mUiLoaderMap.values()) {
            if (loader) {
                loader->setParent(nullptr);
                loader->deleteLater();
                loader = nullptr;
            }
        }
        mUiLoaderMap.clear();
        mUiLoaderParamRemarkMap.clear();
    }
    mChartVisibleData.clear();
    if (iUidStr.isEmpty()) return;
    TSqlSelectorV2 selector;
    selector.setTable("pub_chart_navigation");
    selector.setField(QStringList()<<"name"<<"parameter_list");
    selector.setWhere("id", iUidStr);
    QVariant data = doThreadWork(new TopClassSqlThread(this), TOPSQLTHREAD_SELECT_MAP, QVariant::fromValue(selector));
    TDataResponse dataRes(data.toMap());
    if (dataRes.hasError()) {
        alertError(dataRes.errText(), "Error");
    }
    QVariantMap naviData = dataRes.data().toMap();
    mNaviName = naviData.value("name").toString();
    mUiLoader = new TUiLoader;
    mUiLoader->setScriptEngine(APP->scriptEngine());
    mUiLoader->setSelf(this);
    mUiLoader->setUiStr(naviData.value("parameter_list").toString());
    mUiLoaderLayout->addWidget(mUiLoader, 1, Qt::AlignTop);

    // 这里预留。布局不一定是gridlayout
    mScrollArea = new TScrollArea(mSplitter);
    mScrollArea->setContentsMargins(0, 0, 0, 0);
    mChartListWgt = new QWidget(mScrollArea);
    mScrollArea->setWidget(mChartListWgt);
    mScrollArea->setWidgetResizable(true);
    mSplitter->addWidget(mScrollArea);
    mSplitter->setStretchFactor(1 ,1);
    mSplitter->setSizes(QList<int>()<<100<<1000);
    this->refreshActionState();
}

void SysChartNavigation::resizeEvent(QResizeEvent *iEvent)
{
    TopClassAbs::resizeEvent(iEvent);
//    int widthOffset = iEvent->size().width() / 2 - 30;
//    mAccordion->setExpandButtonOffset(TTHEME_DP(widthOffset), 0);
//    mAccordion->setCollapseButtonOffset(TTHEME_DP(widthOffset), 0);
}

void SysChartNavigation::initUi()
{
    mSplitter = new TSplitter(this);
    mSplitter->setOrientation(Qt::Vertical);
    this->setCentralWidget(mSplitter);

    QWidget *uiloader_spaceholder = new QWidget(this);
    mUiLoaderLayout = new QVBoxLayout(uiloader_spaceholder);
    mUiLoaderLayout->setContentsMargins(0, 0, 0, 0);
    mUiLoaderLayout->setSpacing(0);
    // 筛选界面可折叠
    mAccordion = new TAccordion(this);
    mAccordion->setProperty("SS_BG", "NAVI");
    mAccordion->setAccordionLocation(TAccordion::AccordionLocation::Top);
    QVBoxLayout *naviLayout = new QVBoxLayout(mAccordion);
    naviLayout->setMargin(0);
    naviLayout->setSpacing(0);
    naviLayout->addWidget(uiloader_spaceholder);
    mAccordion->expandButton()->setFixedSize(TTHEME_DP(30), TTHEME_DP(20));
    mAccordion->expandButton()->setToolTip(ttr("Display Navigation"));
    mAccordion->collapseButton()->setFixedSize(TTHEME_DP(30), TTHEME_DP(20));
    mAccordion->collapseButton()->setToolTip(ttr("Hide Navigation"));
    mAccordion->setIsExpanded(true);
    naviLayout->addSpacing(TTHEME_DP(20));

    mSplitter->addWidget(mAccordion);
    mSplitter->setStretchFactor(0, 1);
    if (QToolBar *toolbar = qobject_cast<QToolBar*>(uim()->getWidget("MAIN_TOOLBAR"))) {
        mUiLoaderLayout->addWidget(toolbar, 0, Qt::AlignTop);
        QWidget* blankWgt = new QWidget(toolbar);
        blankWgt->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        QHBoxLayout *toolLayout = new QHBoxLayout(blankWgt);
        toolLayout->setMargin(0);
        toolLayout->setSpacing(6);
        toolbar->addWidget(blankWgt);
        toolLayout->addStretch();

        TLabel *lblSize = new TLabel;
        lblSize->setText(ttr("Size"));
        lblSize->adjustSize();
        toolLayout->addWidget(lblSize);

        mSizeComboBox = new TComboBox;
        mSizeComboBox->setItemList(listPageType());
        mSizeComboBox->setCurrentName("A4");
        mSizeComboBox->setEditable(true);
        mSizeComboBox->setFixedWidth(60);
        toolLayout->addWidget(mSizeComboBox);
        toolLayout->addSpacing(10);
    }
}

void SysChartNavigation::dynamicGenerateChart(const int &pId, const QString &funcJsonData, const QVariantMap &packMap, const QString &wgtType)
{
    qDebug() << "dynamic generate chart function";
    // 1得到数据源函数
    TSqlSelectorV2 selector;
    selector.setTable("pub_chart_graph AS PCG INNER JOIN pub_chart_datasource AS PCD ON PCG.chart_datasource_id = PCD.id");
    selector.setField("PCG.name AS graph_name,PCG.data AS graph_data,PCG.parameter_remark,PCD.id AS pcd_id,PCD.data AS datasource_data");
    selector.setWhere(QString("PCG.id = %1").arg(pId));
    QVariant dataRet = doThreadWork(new TopClassSqlThread(this), TOPSQLTHREAD_SELECT_MAP, QVariant::fromValue(selector));
    TDataResponse dataRes(dataRet.toMap());
    if (dataRes.hasError()) {
        alertError(dataRes.errText(), "Error");
        return;
    }
    QVariantMap data = dataRes.data().toMap();
    QString graphName = data.value("graph_name").toString();
    QString datasourceData = data.value("datasource_data").toString();
    QString graphData = data.value("graph_data").toString();
    QString graphParameterRemark = data.value("parameter_remark").toString();
    QString dataSrcId = data.value("pcd_id").toString();

    TError error;
    QVariantMap datasourceResDataMap = mDataSrcRetCache.value(dataSrcId).toMap();
    if (datasourceResDataMap.isEmpty()) {
        QScriptValue datasourceFun = APP->scriptEngine()->evaluate(QString("(%1)").arg(datasourceData));
        QScriptValueList datasourceFunArgs;
        datasourceFunArgs << funcJsonData;

        // 2得到数据源执行的结果,是个JSON
        QScriptValue datasourceFunRes = datasourceFun.call(APP->scriptEngine()->newQObject(this), datasourceFunArgs);
        QString datasourceFunResStr = datasourceFunRes.toString();
        datasourceResDataMap = TDataParse::jsonStr2Variant(datasourceFunResStr, &error).toMap();
        if (error.isValid()) {
            qDebug() << "error line at " << __LINE__;
            TMessageBox::error(this, ttr("Error"), error.text());
            return;
        }
        // 如果返回的状态是Error就不画了
        if (datasourceResDataMap.value("status").toString() == "Error") {
            if (datasourceResDataMap.value("message").isValid()) {
                TMessageBox::error(this, ttr("Error"), datasourceResDataMap.value("message").toString());
            }
            qDebug() << "status is Error";
            return;
        }
        mDataSrcRetCache.insert(dataSrcId, datasourceResDataMap);
        mDataSrcRetStrCache.insert(dataSrcId, datasourceFunResStr);
    }
    // 3执行动态生成配置文件的脚本
    QScriptValue graphFun = APP->scriptEngine()->evaluate(QString("(%1)").arg(graphData));
    QScriptValueList graphFunArgs;
    graphFunArgs << mDataSrcRetStrCache.value(dataSrcId).toString();
    QScriptValue graphFunRes = graphFun.call(APP->scriptEngine()->newQObject(this), graphFunArgs);
    QString chartCfgStr = graphFunRes.toString();

    // 4生成Chart
    TChartWidget* mChartWidget = new TChartWidget(mChartListWgt);
    mChartWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    connect(mChartWidget, SIGNAL(doubleClicked(QString,double)), this, SLOT(onDoubleClicked()));

    TChartStore* mChartStore = new TChartStore(mChartWidget);
    QVariantList keyVaraintList = datasourceResDataMap.value("keyList").toList();
    QStringList dataKeyList;
    for (QVariant &item: keyVaraintList) {
        dataKeyList.append(item.toString());
    }
    mChartStore->setDataKeyList(dataKeyList);
    mChartStore->setDataList(datasourceResDataMap.value("dataList").toList());
    mChartWidget->setStore(mChartStore);
    mChartWidget->setConfig(TDataParse::jsonStr2Variant(chartCfgStr, &error).toMap());
    if (error.isValid()) {
        qDebug() << "error line at " << __LINE__;
        TMessageBox::error(this, ttr("Error"), error.text());
        return;
    }
    QScrollArea *newChartArea = new QScrollArea(mChartListWgt);
    newChartArea->setWidget(mChartWidget);
    newChartArea->setWidgetResizable(true);
    newChartArea->setContentsMargins(0,0,0,0);
    int chartMinWidth = mChartWidget->config().value("min_width", 0).toInt();
    if (chartMinWidth > 10) {
        mChartWidget->setMinimumWidth(chartMinWidth);
    }
    int chartMinHeight = mChartWidget->config().value("min_height", 0).toInt();
    if (chartMinHeight > 10) {
        mChartWidget->setMinimumHeight(chartMinHeight);
    }
    if (wgtType == "gridlayout") {
        if (TGridLayout* layout = qobject_cast<TGridLayout*>(mChartListWgt->layout())) {
            int fromRow = packMap.value("fromRow").toInt();
            int fromColumn = packMap.value("fromColumn").toInt();
            int rowSpan = packMap.value("rowSpan").toInt();
            int columnSpan = packMap.value("columnSpan").toInt();
            layout->addWidget(newChartArea, fromRow, fromColumn, rowSpan, columnSpan);
            // 如果存在该Chart的话就要把它移除掉
            if (mChartMap.contains(graphName)) {
                TChartWidget* chartPoint = mChartMap.value(graphName);
                if (chartPoint) {
                    chartPoint->deleteLater();
                    chartPoint = nullptr;
                }
                QScrollArea *chartArea = mChartAreaMap.value(graphName);
                if (chartArea) {
                    chartArea->deleteLater();
                    chartArea = nullptr;
                }
                mChartMap.insert(graphName, mChartWidget);
                mChartParameterRemarkMap.insert(mChartWidget, graphParameterRemark);
                mChartAreaMap.insert(graphName, newChartArea);
            } else {
                mChartMap.insert(graphName, mChartWidget);
                mChartParameterRemarkMap.insert(mChartWidget, graphParameterRemark);
                mChartAreaMap.insert(graphName, newChartArea);
            }
            if (!mChartVisibleData.value(graphName, true).toBool()) {
                layout->removeWidget(newChartArea);
                newChartArea->setVisible(false);
            }
        }
    } else if (wgtType == "vboxlayout") {
    } else if (wgtType == "hboxlayout") {
    }
}

void SysChartNavigation::configGenerateChart(const int &pId, const QString &funcJsonData, const QVariantMap &packMap, const QString &wgtType)
{
    qDebug() << "config generate chart function";
    // 1得到数据源函数
    TSqlSelectorV2 selector;
    selector.setTable("pub_chart_graph AS PCG INNER JOIN pub_chart_datasource AS PCD ON PCG.chart_datasource_id = PCD.id");
    selector.setField("PCG.name AS graph_name,PCG.data AS graph_data,PCG.parameter_remark,PCD.id AS pcd_id,PCD.data AS datasource_data");
    selector.setWhere(QString("PCG.id = %1").arg(pId));
    QVariant dataRet = doThreadWork(new TopClassSqlThread(this), TOPSQLTHREAD_SELECT_MAP, QVariant::fromValue(selector));
    TDataResponse dataRes(dataRet.toMap());
    if (dataRes.hasError()) {
        alertError(dataRes.errText(), "Error");
        return;
    }
    QVariantMap data = dataRes.data().toMap();
    QString graphName = data.value("graph_name").toString();
    QString datasourceData = data.value("datasource_data").toString();
    QString graphData = data.value("graph_data").toString();
    QString graphParameterRemark = data.value("parameter_remark").toString();
    QString dataSrcId = data.value("pcd_id").toString();

    TError error;
    QVariantMap datasourceResDataMap = mDataSrcRetCache.value(dataSrcId).toMap();
    if (datasourceResDataMap.isEmpty()) {
        QScriptValue datasourceFun = APP->scriptEngine()->evaluate(QString("(%1)").arg(datasourceData));
        QScriptValueList datasourceFunArgs;
        datasourceFunArgs << funcJsonData;

        // 2得到数据源执行的结果,是个JSON
        QScriptValue datasourceFunRes = datasourceFun.call(APP->scriptEngine()->newQObject(this), datasourceFunArgs);
        QString datasourceFunResStr = datasourceFunRes.toString();
        datasourceResDataMap = TDataParse::jsonStr2Variant(datasourceFunResStr, &error).toMap();
        if (error.isValid()) {
            qDebug() << "error line at " << __LINE__;
            TMessageBox::error(this, ttr("Error"), error.text());
            return;
        }
        // 如果返回的状态是Error就不画了
        if (datasourceResDataMap.value("status").toString() == "Error") {
            qDebug() << "status is Error";
            return;
        }
        mDataSrcRetCache.insert(dataSrcId, datasourceResDataMap);
    }

    QString chartCfgStr = graphData;

    // 4生成Chart
    TChartWidget* mChartWidget = new TChartWidget(mChartListWgt);
    mChartWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TChartStore* mChartStore = new TChartStore(mChartWidget);
    QVariantList keyVaraintList = datasourceResDataMap.value("keyList").toList();
    QStringList dataKeyList;
    for (QVariant &item: keyVaraintList) {
        dataKeyList.append(item.toString());
    }
    mChartStore->setDataKeyList(dataKeyList);
    mChartStore->setDataList(datasourceResDataMap.value("dataList").toList());
    mChartWidget->setStore(mChartStore);
    mChartWidget->setConfig(TDataParse::jsonStr2Variant(chartCfgStr, &error).toMap());
    if (error.isValid()) {
        qDebug() << "error line at " << __LINE__;
        TMessageBox::error(this, ttr("Error"), error.text());
        return;
    }
    QScrollArea *newChartArea = new QScrollArea(mChartListWgt);
    newChartArea->setWidget(mChartWidget);
    newChartArea->setWidgetResizable(true);
    newChartArea->setContentsMargins(0,0,0,0);
    int chartMinWidth = mChartWidget->config().value("min_width", 0).toInt();
    if (chartMinWidth > 10) {
        mChartWidget->setMinimumWidth(chartMinWidth);
    }
    int chartMinHeight = mChartWidget->config().value("min_height", 0).toInt();
    if (chartMinHeight > 10) {
        mChartWidget->setMinimumHeight(chartMinHeight);
    }
    if (wgtType == "gridlayout") {
        if (TGridLayout* layout = qobject_cast<TGridLayout*>(mChartListWgt->layout())) {
            int fromRow = packMap.value("fromRow").toInt();
            int fromColumn = packMap.value("fromColumn").toInt();
            int rowSpan = packMap.value("rowSpan").toInt();
            int columnSpan = packMap.value("columnSpan").toInt();
            layout->addWidget(newChartArea, fromRow, fromColumn, rowSpan, columnSpan);
            // 如果存在该Chart的话就要把它移除掉
            if (mChartMap.contains(graphName)) {
                TChartWidget* chartPoint = mChartMap.value(graphName);
                if (chartPoint) {
                    chartPoint->deleteLater();
                    chartPoint = nullptr;
                }
                QScrollArea *chartArea = mChartAreaMap.value(graphName);
                if (chartArea) {
                    chartArea->deleteLater();
                    chartArea = nullptr;
                }
                mChartMap.insert(graphName, mChartWidget);
                mChartParameterRemarkMap.insert(mChartWidget, graphParameterRemark);
                mChartAreaMap.insert(graphName, newChartArea);
            } else {
                mChartMap.insert(graphName, mChartWidget);
                mChartParameterRemarkMap.insert(mChartWidget, graphParameterRemark);
                mChartAreaMap.insert(graphName, newChartArea);
            }
            if (!mChartVisibleData.value(graphName, true).toBool()) {
                layout->removeWidget(newChartArea);
                newChartArea->setVisible(false);
            }
        }
    } else if (wgtType == "vboxlayout") {
    } else if (wgtType == "hboxlayout") {
    }
}

void SysChartNavigation::generateUiLoader(const int &pId, const QString &funcJsonData, const QVariantMap &packMap, const QString &wgtType)
{
    qDebug() << "generate uiloader function";
    // 1得到数据源函数
    TSqlSelectorV2 selector;
    selector.setTable("pub_chart_graph AS PCG INNER JOIN pub_chart_datasource AS PCD ON PCG.chart_datasource_id = PCD.id");
    selector.setField("PCG.name AS graph_name,PCG.data AS graph_data,PCG.parameter_remark,PCD.id AS pcd_id,PCD.data AS datasource_data");
    selector.setWhere(QString("PCG.id = %1").arg(pId));
    QVariant dataRet = doThreadWork(new TopClassSqlThread(this), TOPSQLTHREAD_SELECT_MAP, QVariant::fromValue(selector));
    TDataResponse dataRes(dataRet.toMap());
    if (dataRes.hasError()) {
        alertError(dataRes.errText(), "Error");
        return;
    }
    QVariantMap data = dataRes.data().toMap();
    QString graphName = data.value("graph_name").toString();
    QString datasourceData = data.value("datasource_data").toString();
    QString graphData = data.value("graph_data").toString();
    QString graphParameterRemark = data.value("parameter_remark").toString();
    QString dataSrcId = data.value("pcd_id").toString();
    // 生成uiloader
    TUiLoader *uiLoader = new TUiLoader(mChartListWgt);
    uiLoader->setScriptEngine(APP->scriptEngine());
    uiLoader->setSelf(this);
    uiLoader->setUiStr(graphData);

    QVariantMap uiDataMap = mDataSrcRetCacheUiLoader.value(dataSrcId).toMap();
    if (uiDataMap.isEmpty()) {
        QScriptValue datasourceFun = APP->scriptEngine()->evaluate(QString("(%1)").arg(datasourceData));
        QScriptValueList datasourceFunArgs;
        datasourceFunArgs << funcJsonData << APP->scriptEngine()->newQObject(uiLoader);

        // 2得到数据源执行的结果,是个JSON
        QScriptValue datasourceFunRes = datasourceFun.call(APP->scriptEngine()->newQObject(this), datasourceFunArgs);
        QString datasourceFunResStr = datasourceFunRes.toString();
        TError error;
        QVariantMap datasourceResDataMap = TDataParse::jsonStr2Variant(datasourceFunResStr, &error).toMap();
        if (error.isValid()) {
            qDebug() << "error line at " << __LINE__;
            TMessageBox::error(this, ttr("Error"), error.text());
            return;
        }
        // 如果返回的状态是Error就不画了
        if (datasourceResDataMap.value("status").toString() == "Error") {
            if (datasourceResDataMap.value("message").isValid()) {
                TMessageBox::error(this, ttr("Error"), datasourceResDataMap.value("message").toString());
                qDebug() << "show error message";
            }
            qDebug() << "status is Error";
            return;
        }

        uiDataMap = TDataParse::jsonStr2Variant(datasourceFunResStr, &error).toMap();
        if (error.isValid()) {
            qDebug() << "error line at " << __LINE__;
            TMessageBox::error(this, ttr("Error"), error.text());
            return;
        }
        mDataSrcRetCacheUiLoader.insert(dataSrcId, uiDataMap);
        mDataSrcRetCache.insert(dataSrcId, uiDataMap);
    }
    uiLoader->loadValues(uiDataMap);

    if (wgtType == "gridlayout") {
        if (TGridLayout* layout = qobject_cast<TGridLayout*>(mChartListWgt->layout())) {
            int fromRow = packMap.value("fromRow").toInt();
            int fromColumn = packMap.value("fromColumn").toInt();
            int rowSpan = packMap.value("rowSpan").toInt();
            int columnSpan = packMap.value("columnSpan").toInt();
            layout->addWidget(uiLoader, fromRow, fromColumn, rowSpan, columnSpan);
            // 如果存在该UiLoader的话就要把它移除掉
            if (mUiLoaderMap.contains(graphName)) {
                TUiLoader *tmpLoader = mUiLoaderMap.value(graphName);
                if (tmpLoader) {
                    tmpLoader->deleteLater();
                    tmpLoader = nullptr;
                    mUiLoaderMap.insert(graphName, uiLoader);
                    mUiLoaderParamRemarkMap.insert(uiLoader, graphParameterRemark);
                }
            } else {
                mUiLoaderMap.insert(graphName, uiLoader);
                mUiLoaderParamRemarkMap.insert(uiLoader, graphParameterRemark);
            }
            if (!mChartVisibleData.value(graphName, true).toBool()) {
                layout->removeWidget(uiLoader);
                uiLoader->setVisible(false);
            }
        }
    }
}

QString SysChartNavigation::mapToJson(const QVariantMap &data)
{
    QJsonDocument jsonDoc = QJsonDocument::fromVariant(QVariant(data));
    return QString(jsonDoc.toJson());
}

QVariantList SysChartNavigation::listPageType()
{
    QVariantList list;

    QStringList pageTypeList;
    pageTypeList << "A0" << "A1" << "A2" << "A3" << "A4" << "A5" << "A6"
                 << "A7" << "A8" << "A9" << "B0" << "B1" << "B2" << "B3"
                 << "B4" << "B5" << "B6" << "B7" << "B8" << "B9" << "B10";
    for (QString &pageType: pageTypeList) {
        QVariantMap pageTypeMap;
        pageTypeMap.insert("name", pageType);
        pageTypeMap.insert("text", pageType);
        list.append(pageTypeMap);
    }

    return list;
}

QVariantList SysChartNavigation::listOpenType()
{
    QVariantList list;

    QStringList openTypeList;
    openTypeList << ttr("Yes") << ttr("No");
    for (QString &openType: openTypeList) {
        QVariantMap openTypeMap;
        openTypeMap.insert("name", openType);
        openTypeMap.insert("text", openType);
        list.append(openTypeMap);
    }

    return list;
}

QPagedPaintDevice::PageSize SysChartNavigation::pageTypeToEnum(const QString &pageSize)
{
    if (pageSize == "A0") {
        return QPrinter::A0;
    } else if (pageSize == "A1") {
        return QPrinter::A1;
    } else if (pageSize == "A2") {
        return QPrinter::A2;
    } else if (pageSize == "A3") {
        return QPrinter::A3;
    } else if (pageSize == "A4") {
        return QPrinter::A4;
    } else if (pageSize == "A5") {
        return QPrinter::A5;
    } else if (pageSize == "A6") {
        return QPrinter::A6;
    } else if (pageSize == "A7") {
        return QPrinter::A7;
    } else if (pageSize == "A8") {
        return QPrinter::A8;
    } else if (pageSize == "A9") {
        return QPrinter::A9;
    } else if (pageSize == "B0") {
        return QPrinter::B0;
    } else if (pageSize == "B1") {
        return QPrinter::B1;
    } else if (pageSize == "B2") {
        return QPrinter::B2;
    } else if (pageSize == "B3") {
        return QPrinter::B3;
    } else if (pageSize == "B4") {
        return QPrinter::B4;
    } else if (pageSize == "B5") {
        return QPrinter::B5;
    } else if (pageSize == "B6") {
        return QPrinter::B6;
    } else if (pageSize == "B7") {
        return QPrinter::B7;
    } else if (pageSize == "B8") {
        return QPrinter::B8;
    } else if (pageSize == "B9") {
        return QPrinter::B9;
    } else if (pageSize == "B10") {
        return QPrinter::B10;
    } else {
        return QPrinter::Custom;
    }
}

int SysChartNavigation::calcTreeDepth(const QVariantList &iDataList)
{
    int maxDepth = 0;
    for (QVariant var: iDataList) {
        QVariantMap varMap = var.toMap();
        QVariantList children = varMap.value("children").toList();
        if (children.size() > 0) {
            int tmpDepth = calcTreeDepth(children);
            if (tmpDepth > maxDepth) {
                maxDepth = tmpDepth;
            }
        }
    }
    return maxDepth + 1;
}

int SysChartNavigation::calcTreeDepth(const QVariantMap &iDataMap)
{
    int depth = 0;
    QVariantList children = iDataMap.value("children").toList();
    if (children.size() == 0) {
        depth = 1;
    } else {
        depth = calcTreeDepth(children);
    }
    return depth;
}

int SysChartNavigation::calcTreeLeafSize(const QVariantMap &iDataMap)
{
    int leafSize = 0;
    QVariantList children = iDataMap.value("children").toList();
    if (children.size() == 0) {
        leafSize++;
    } else {
        for (QVariant var: children) {
            QVariantMap varMap = var.toMap();
            leafSize += calcTreeLeafSize(varMap);
        }
    }
    return leafSize;
}