| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090 | #include "transmitterswitch.h"#include "ui_transmitterswitch.h"#include <QFile>#include <QList>#include <memory>#include <QLayout>#include <QScrollBar>#include "LHQLogAPI.h"#include "pBtnUserData2.h"#include "FromWebAPI.h"#include "TransmitterSwitchInfo.h"#include "savetotemplate.h"#include "importtemplate.h"#include "warning.h"#include "tipwidget.h"#include "UIStyleManager.h"#include "PlanData.h"#include "plancard.h"#include "flowlayout.h"#include "managerplan.h"#include "importtemplate.h"#include "copytoother.h"#include "templatemanager.h"#include "FromSQLite.h"TransmitterSwitch::TransmitterSwitch(QWidget *parent) :    QWidget(parent),    ui(new Ui::TransmitterSwitch){    ui->setupUi(this);    LH_WRITE_LOG("================================== TransmitterPlan =================================");    /* 创建一个布局 */    QVBoxLayout* layout = new QVBoxLayout(parent);    layout->setMargin(0);    layout->setSpacing(0);    parent->setLayout(layout);    layout->addWidget(this);    /* 创建一个流式布局,存放卡片 */    m_flowlayout = new FlowLayout(ui->scrollAreaContents_Card, 0, m_cardHorSpacing, m_cardVerSpacing);    // m_flowlayout->setContentsMargins(0, 0, 0, 0);    // m_flowlayout->setSpacing(200);        ui->scrollAreaContents_Card->setLayout(m_flowlayout);    /* 创建WebAPI实例 */    m_fromWebAPI = new FromWebAPI;    /* 设置“默认计划”按钮可点击 */    ui->pBtn_defaultPlan->setCheckable(true);    ui->pBtn_allFrequency->setCheckable(true);    connect(ui->pBtn_allFrequency, &QPushButton::clicked, this, &TransmitterSwitch::do_selectFrequencyBtn);        /* 设置提示文本 */    m_tipText = new QLabel(this);    m_tipText->resize(936,56);    m_tipText->setObjectName("label_TipText");    m_tipText->setText(R"(按时刻执行模式:即以时刻点为单位进行执行,若某日既为普通日和特殊日,在某一时刻皆有执行动作,将优先执行特殊日在此时刻所计划的动作。按天执行模式:即以天为单位进行执行,若某日既为普通日和特殊日,则当日一整天优先执行特殊日所计划的动作,普通日计划当日不再执行。)");    m_tipText->hide();    QPoint pos = ui->label_Tip->mapTo(this, ui->label_Tip->pos());    m_tipText->move(pos.x() + 2, pos.y() + 2 );     /* 去掉阴影的宽度和高度 */    ui->label_Tip->installEventFilter(this);    /* 设置默认值 */    ui->pBtn_defaultPlan->setChecked(true);    ui->rBtn_moment->setChecked(true);    /* 连接信号和槽 */    connect(ui->pBtn_addPlan, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnAddExecPlan);    connect(ui->pBtn_importPlan, &QPushButton::clicked, this, &TransmitterSwitch::do_importData);    connect(ui->pBtn_exportPlan, &QPushButton::clicked, this, &TransmitterSwitch::do_exportData);    connect(ui->pBtn_editPlan, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnModifyExecPlan);    connect(ui->pBtn_refresh, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnRefresh);    connect(ui->pBtn_defaultPlan, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnIsOpenPlan);    connect(ui->rBtn_moment, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnExecMode);    connect(ui->rBtn_day, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnExecMode);    // connect(ui->pBtn_clearPlan, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnClearPlan);    connect(ui->pBtn_deletePlan, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnClearPlan);    connect(ui->pBtn_cloneToOther, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnCopyToOther);    connect(ui->pBtn_templateManager, &QPushButton::clicked, this, &TransmitterSwitch::do_pBtnManageTemplate);    /* 设置QSS */    connect(&EPUIStyle, &UIStyleManager::signal_qssChanged, this, &TransmitterSwitch::do_setUIStyle);    /* 设置默认的皮肤 */    EPUIStyle.setUIStyle(enum_UIStyle::UI_Dark);    /* 设置默认点击的按钮 */    ui->pBtn_allFrequency->setChecked(true);}TransmitterSwitch::~TransmitterSwitch(){    if(m_tipText != nullptr)    {        delete m_tipText;        m_tipText = nullptr;    }    if(m_fromWebAPI != nullptr)    {        delete m_fromWebAPI;        m_fromWebAPI = nullptr;    }    if(m_fromSQLite != nullptr)    {        delete m_fromSQLite;        m_fromSQLite = nullptr;    }    delete ui;}/* 初始化webAPI,重载版 */void TransmitterSwitch::initTS(const InitData& data){    setWebAPIInfo(data.url, data.serverID, data.serverKey);    /* 设置权限 */    setUserPermission(data.userPermission);}/* 修改用户权限 */void TransmitterSwitch::setUserPermission(int userPermission){    eUserPermission userPerm = static_cast<eUserPermission>(userPermission);    GInfo.setUserPermission(userPerm);    if(eUserPermission::User_Administrator == userPerm)    {        /* 管理员权限 */        ui->pBtn_addPlan->show();        ui->pBtn_editPlan->show();        ui->pBtn_deletePlan->show();        ui->pBtn_cloneToOther->show();        ui->pBtn_exportPlan->show();        ui->pBtn_importPlan->show();        ui->pBtn_templateManager->show();        ui->pBtn_defaultPlan->setEnabled(true);        ui->rBtn_moment->setEnabled(true);        ui->rBtn_day->setEnabled(true);    }    else if(eUserPermission::User_Normal == userPerm)    {        /* 普通用户权限 */        ui->pBtn_addPlan->hide();        ui->pBtn_editPlan->hide();        ui->pBtn_deletePlan->hide();        ui->pBtn_cloneToOther->hide();        ui->pBtn_exportPlan->hide();        ui->pBtn_importPlan->hide();        ui->pBtn_templateManager->hide();        ui->pBtn_defaultPlan->setEnabled(false);        ui->rBtn_moment->setEnabled(false);        ui->rBtn_day->setEnabled(false);    }}/* 设置样式表路径,给弹窗页面使用,不需要包含最后的white,black */void TransmitterSwitch::setQSSPath(const QString &qssPath){    if(qssPath.isEmpty())    {        return;    }    /* 去掉最后的“/” */    // if(qssPath.endsWith("/"))    // {    //     EPUIStyle.setQSSPath(qssPath.left(qssPath.length() - 1));    // } else    // {    //     EPUIStyle.setQSSPath(qssPath);    // }}/** * @brief 设置WebAPI信息 *  * @param url WebAPI地址 * @param serID 数据库ID * @param serKey 限制的关键字 */void TransmitterSwitch::setWebAPIInfo(const QString &url, const QString &serverID, const QString &serverKey){    if(m_fromWebAPI == nullptr)    {        m_fromWebAPI = new FromWebAPI;    }    if(url.isEmpty() || serverID.isEmpty() || serverKey.isEmpty())    {        LH_WRITE_ERROR("WebAPI info is empty");        return;    }    m_fromWebAPI->initWebApi(url, serverID, serverKey);    /* 获取支持的设备 */    ChnContainer.clearAllChannel();    m_fromWebAPI->getChannelInfo(ChnContainer.getMapChannel());    /* 创建获取到的卡片信息 */    createAllCard();}/** * @brief 获取EQM数据库计划,包括所有的配置信息 *  */void TransmitterSwitch::getExecPlanFromEQM(){    if(m_fromWebAPI == nullptr)    {        LH_WRITE_ERROR("未初始化WebAPI");        return;    }    /* 判断是在线还是离线模式 */    if(!GInfo.isOnlineDB())    {        LH_WRITE_LOG(QString("当前为离线模式,无法获取计划"));        return;    }    /* 获取页面的配置信息 */    if(m_fromWebAPI->getConfigData(CfgData.getMapConfigData()))    {        // TipWidget::display(TipWidget::OPERATOR_OK, "获取配置成功", this);    }else {        TipWidget::display(TipWidget::OPERATOR_FAIL, "获取配置失败", this);        return;    }    /* 设置计划配置 */    auto& mapConfig = CfgData.getMapConfigData();    for(auto begin = mapConfig.begin(), end = mapConfig.end(); begin != end; begin++)    {        if(begin->key == static_cast<int>(enum_ExecPlanConfig::OpenPlan))        {            ui->pBtn_defaultPlan->setChecked(begin->value == 1 ? true : false);        }        else if(begin->key == static_cast<int>(enum_ExecPlanConfig::ExecMode))        {            if(begin->value == 0)            {                ui->rBtn_moment->setChecked(true);            }else {                ui->rBtn_day->setChecked(true);            }        }    }    /* 判断两种配置是否都有默认值 */    if(CfgData.findConfigData(static_cast<int>(enum_ExecPlanConfig::OpenPlan)) == false)    {        /* 没有默认值,设置为默认开启 */        ui->pBtn_defaultPlan->setChecked(true);        ConfigData config1;        config1.key = static_cast<int>(enum_ExecPlanConfig::OpenPlan);        config1.value = 1;        config1.updateTime = QDateTime::currentDateTime();        CfgData.updateConfigData(config1);        /* 将配置写入数据库 */        if(m_fromWebAPI->insertConfigData(CfgData.getMapConfigData()))        {            /* 调用回调函数 */            if(m_trackCB != nullptr)            {                m_trackCB(1, g_mapTrack.value(1));            }        }    }    if(CfgData.findConfigData(static_cast<int>(enum_ExecPlanConfig::ExecMode)) == false)    {        /* 没有默认值,设置为默认按时刻执行 */        ui->rBtn_moment->setChecked(true);        ConfigData config2;        config2.key = static_cast<int>(enum_ExecPlanConfig::ExecMode);        config2.value = 0;        config2.updateTime = QDateTime::currentDateTime();        CfgData.updateConfigData(config2);        /* 将配置写入数据库 */        if(m_fromWebAPI->insertConfigData(CfgData.getMapConfigData()))        {            /* 调用回调函数 */            if(m_trackCB != nullptr)            {                m_trackCB(1, g_mapTrack.value(1));            }        }    }    /* 判断是单频率还是多频率 */    if(!GInfo.isOneFrequency())    {        /* 所有频率 */        QMap<int, QList<OnePlanItemInfo>> mapPlan;        if(m_fromWebAPI->getExecPlanData(mapPlan))        {            /* 先清空所有的计划 */            // PData.clearAllPlanItem();            /* 遍历所有的频率 */            for(auto begin = mapPlan.begin(), end = mapPlan.end(); begin != end; begin++)            {                auto pCard = PData.findPlanCard(begin.key());                if(pCard != nullptr)                {                    if(isFrequencyInCountdown(pCard->getChannelInfo().ChannelID))                    {                        TipWidget::display(TipWidget::OPERATOR_WARN, QString("<%1>正在倒计时中,无法更新计划").arg(pCard->getChannelInfo().ChannelName), this);                        continue;                    }                    pCard->clearPlanItem(); /* 清空当前频率的计划 */                    pCard->setPlanList(begin.value());                }            }            TipWidget::display(TipWidget::OPERATOR_OK, "获取计划成功", this);        }else {            TipWidget::display(TipWidget::OPERATOR_FAIL, QString("获取计划失败"), this);        }    }else     {        /* 指定频率 */        QList<OnePlanItemInfo> listPlan;        if(m_fromWebAPI->getExecPlanData(GInfo.getChannelInfo().ChannelID, listPlan))        {            /* 先清空所有的计划 */            PData.clearAllPlanItem();            /* 清空当前频率的计划 */            auto pCard = PData.findPlanCard(GInfo.getChannelInfo().ChannelID);            if(pCard != nullptr)            {                pCard->setPlanList(listPlan);            }            TipWidget::display(TipWidget::OPERATOR_OK, "获取计划成功", this);        }else {            TipWidget::display(TipWidget::OPERATOR_FAIL, QString("获取计划失败"), this);        }    }    /* 调用回调函数 */    if(m_trackCB != nullptr)    {        m_trackCB(2, g_mapTrack.value(2));    }}/* 将计划保存到EQM数据库 */void TransmitterSwitch::saveExecPlanToEQM(){    if(m_fromWebAPI == nullptr)    {        LH_WRITE_ERROR("未初始化WebAPI");        return;    }    /* 判断是在线还是离线模式 */    if(!GInfo.isOnlineDB())    {        LH_WRITE_LOG(QString("当前为离线模式,无法保存计划"));        return;    }    QList<OnePlanItemInfo> list;    /* 获取当前计划的执行模式 */    int execType = 0;    if(ui->rBtn_moment->isChecked())    {        execType = 0;    } else    {        execType = 1;    }    /* 保存“默认计划”和“执行模式” */    ConfigData config1;    config1.key = static_cast<int>(enum_ExecPlanConfig::OpenPlan);    config1.value = ui->pBtn_defaultPlan->isChecked() ? 1 : 0;    config1.updateTime = QDateTime::currentDateTime();    CfgData.updateConfigData(config1);        ConfigData config2;    config2.key = static_cast<int>(enum_ExecPlanConfig::ExecMode);    config2.value = ui->rBtn_moment->isChecked() ? 0 : 1;    config2.updateTime = QDateTime::currentDateTime();    CfgData.updateConfigData(config2);    /* 更新“计划是否更新”标志位,在更新前需要先获取数据库的标志位,如果依旧为1,那么本地是否更改都设置为1 */    ConfigData config3;    if(!m_fromWebAPI->getConfigData(static_cast<int>(enum_ExecPlanConfig::IsChanged), config3))    {        config3.key = static_cast<int>(enum_ExecPlanConfig::IsChanged);    }    /* 只要数据库和本地更新标志位有一个为true,说明还未被读走,则设置标志位为true */    // if((config3.value == 1) || IData.isUpdate())    // {    //     config3.value = 1;    // }    config3.updateTime = QDateTime::currentDateTime();    CfgData.updateConfigData(config3);    /* 将配置写入数据库 */    m_fromWebAPI->insertConfigData(CfgData.getMapConfigData());    /* 调用回调函数 */    if(m_trackCB != nullptr)    {        m_trackCB(1, g_mapTrack.value(1));    }}/* 亮/暗换肤,0是亮色,1是暗色 */void TransmitterSwitch::setUIStyle(int style){    if(style == 0)    {        EPUIStyle.setUIStyle(enum_UIStyle::UI_Light);    }    else if(style == 1)    {        EPUIStyle.setUIStyle(enum_UIStyle::UI_Dark);    }else {        LH_WRITE_ERROR(QString("错误的样式类型: %1").arg(style));    }}/* 设置回调函数 */void TransmitterSwitch::setTrackCallBack(trackCallBack cb){    if(cb == nullptr)    {        return;    }    m_trackCB = cb;}/* 设置WebAPI路径,不获取数据,不创建卡片 */void TransmitterSwitch::setWebAPIInfoOnly(const InitData& data){    if(m_fromWebAPI == nullptr)    {        m_fromWebAPI = new FromWebAPI;    }    if(data.url.isEmpty() || data.serverID.isEmpty() || data.serverKey.isEmpty())    {        LH_WRITE_ERROR("WebAPI info is empty");        return;    }    if(!m_fromWebAPI->initWebApi(data.url, data.serverID, data.serverKey))    {        LH_WRITE_ERROR("WebAPI init failed");        return;    }}/* 设置频率信息,给离线版使用 */void TransmitterSwitch::setFrequencyInfo(const ExecPlanInfo& info, bool useOnlineDB){    /* 清空频率信息 */    ChnContainer.clearAllChannel();    /* 清空卡片 */    PData.clearAllPlanItem();    /* 清空所有按钮 */    for(auto it = m_listFrequencyBtn.begin(); it != m_listFrequencyBtn.end(); ++it)    {        delete *it;    }    m_listFrequencyBtn.clear();    ChannelInfo chnInfo;    chnInfo.ChannelID = info.ChannelID;    chnInfo.ChannelName = info.ChannelName;    GInfo.setChannelInfo(chnInfo);    GInfo.setDatabasePath(info.DatabasePath);    LH_WRITE_LOG(QString("频率ID: %1, 频率名称: %2, 在线离线模式: %3")                    .arg(GInfo.getChannelInfo().ChannelID)                    .arg(GInfo.getChannelInfo().ChannelName)                    .arg(useOnlineDB ? "在线" : "离线"));    /* 设置在线还是离线模式 */    setUseOnlineDB(useOnlineDB);    /* 设置频率模式,单频率模式或多频率 */    if(GInfo.getChannelInfo().ChannelID < 0)    {        /* 多频率模式 */        GInfo.setOneFrequency(false);    } else    {        /* 单频率模式 */        GInfo.setOneFrequency(true);        setOneFrequencyMode();    }    /* 创建获取到的卡片信息 */    createAllCard();    // LH_WRITE_LOG_DEBUG(QString("创建频率卡片成功,频率ID:%1").arg(GInfo.getChannelInfo().ChannelID));}/* 设置一页的卡片数量 */void TransmitterSwitch::setOnePageCardNum(int horNum, int verNum){    if(horNum <= 0 || verNum <= 0)    {        LH_WRITE_ERROR(QString("错误的卡片数量: %1, %2").arg(horNum).arg(verNum));        return;    }    m_cardHorNumber = horNum;    m_cardVerNumber = verNum;    update();}/* 清空卡片,用于ESM8C上位机关闭使用EQM数据库的时候调用 */void TransmitterSwitch::clearAll(){    /* 删除所有的卡片 */    PData.deleteAllCard();    /* 删除所有按钮 */    for(auto it = m_listFrequencyBtn.begin(); it != m_listFrequencyBtn.end(); ++it)    {        delete *it;    }    m_listFrequencyBtn.clear();    /* 清空频率信息 */    ChnContainer.clearAllChannel();    /* 删除数据库连接实例 */    if(m_fromWebAPI != nullptr)    {        delete m_fromWebAPI;        m_fromWebAPI = nullptr;    }    if(m_fromSQLite != nullptr)    {        delete m_fromSQLite;        m_fromSQLite = nullptr;    }}/* 获取一个频率的计划数据,只应用于本地数据库,下载到下位机用 */void TransmitterSwitch::getOnePlanData(QList<OnePlanItemInfo>* listPlan, ExecPlanConfig* config, int channelID){    // LH_WRITE_LOG_DEBUG(QString("当前是离线模式"));    if(!GInfo.isOneFrequency())    {        LH_WRITE_LOG(QString("只应用于单个频率模式"));        return;    }        if(listPlan == nullptr)    {        LH_WRITE_ERROR("传入的指针为空");        return;    }    if(config == nullptr)    {        LH_WRITE_ERROR("传入的配置指针为空");        return;    }    /* 获取唯一的频率卡片 */    auto pCard = PData.findPlanCard(GInfo.getChannelInfo().ChannelID);    if(pCard == nullptr)    {        LH_WRITE_ERROR("没有选中频率卡片");        return;    }    pCard->getAllPlanInfo(*listPlan);        /* 获取页面配置 */    config->isUsingPlan = ui->pBtn_defaultPlan->isChecked() ? 1 : 0;    config->execMdoe = ui->rBtn_moment->isChecked() ? 0 : 1;}/* 设置计划信息 */void TransmitterSwitch::setOnePlanData(QList<OnePlanItemInfo>& listPlan, ExecPlanConfig& config, int channelID){    /* 设置计划信息 */    if(!GInfo.isOneFrequency())    {        LH_WRITE_LOG(QString("只应用于单个频率模式"));        return;    }    /* 给计划设置频率信息 */    for(auto& it : listPlan)    {        it.ChannelID = GInfo.getChannelInfo().ChannelID;        it.ChannelName = GInfo.getChannelInfo().ChannelName;    }    /* 获取唯一的频率卡片 */    auto pCard = PData.findPlanCard(GInfo.getChannelInfo().ChannelID);    if(pCard == nullptr)    {        LH_WRITE_ERROR("没有选中频率卡片");        return;    }    pCard->setPlanList(listPlan);        /* 设置页面配置 */    ui->pBtn_defaultPlan->setChecked(config.isUsingPlan == 1 ? true : false);    if(config.execMdoe == 0)    {        ui->rBtn_moment->setChecked(true);    }else {        ui->rBtn_day->setChecked(true);    }}/* 点击了添加计划按钮 */void TransmitterSwitch::do_pBtnAddExecPlan(){    /* 获取当前选中的窗口 */    auto pCard = PData.getCurrentPlanCard();    ChannelInfo chnInfo;    if(pCard == nullptr)    {        LH_WRITE_LOG_DEBUG("没有选中频率卡片");        TipWidget::display(TipWidget::OPERATOR_WARN, "没有选中频率卡片", this);        return;    }    /* 判断有没有在倒计时中,如果在就不能操作 */    if(isFrequencyInCountdown(pCard->getChannelInfo().ChannelID))    {        TipWidget::display(TipWidget::OPERATOR_WARN, QString("<%1>正在倒计时中,无法添加计划").arg(pCard->getChannelInfo().ChannelName), this);        return;    }    /* 创建新增窗口 */    std::shared_ptr<ManagerPlan> mp = std::make_shared<ManagerPlan>(Enum_Mode::Mode_Add);    mp->setFrequencyID(pCard->getChannelInfo());    mp->setFromWebAPI(m_fromWebAPI);    mp->setFromSQLite(m_fromSQLite);    connect(mp.get(), &ManagerPlan::signal_callBack, this, &TransmitterSwitch::do_callBack);    mp->exec();    /* 判断是否点击了OK */    if(!mp->isOK())    {        return;    }    /* 获取计划信息 */    auto& mapPlanInfo = mp->getPlanInfo();    /* 遍历所有的频率 */    bool isSuccess = true;    for(auto begin = mapPlanInfo.begin(), end = mapPlanInfo.end(); begin != end; begin++)    {        /* 获取频率ID */        int chnID = begin.key();        /* 获取计划列表 */        auto& list = begin.value();        /* 查找这个频率的Card */           auto pCard = PData.findPlanCard(chnID);        if(pCard == nullptr)        {            LH_WRITE_ERROR(QString("没有找到频率ID为%1的卡片").arg(chnID));            continue;        }        /* 设置计划列表 */        pCard->setPlanList(list);        if(!GInfo.isOnlineDB())        {            /* 离线模式不需要写入数据库 */            continue;        }        /* 写入数据库 */        QList<OnePlanItemInfo> listPlan;        pCard->getAllPlanInfo(listPlan);        if(!m_fromWebAPI->insertData(chnID, listPlan))        {            LH_WRITE_ERROR(QString("频率ID为%1的计划写入数据库失败").arg(chnID));            isSuccess = false;            TipWidget::display(TipWidget::OPERATOR_FAIL, QString("频率:%1 计划写入数据库失败!").arg(pCard->getChannelInfo().ChannelName), this);        }    }    if(isSuccess)    {        TipWidget::display(TipWidget::OPERATOR_OK, "添加计划成功", this);    }    /* 调用回调函数 */    if(m_trackCB != nullptr)    {        m_trackCB(1, g_mapTrack.value(1));    }}/* 点击了修改按钮 */void TransmitterSwitch::do_pBtnModifyExecPlan(){    /* 先判断是不是单频率模式,如果是,设置这个频率卡片被点击了 */    if(GInfo.isOneFrequency())    {        auto pCard = PData.findPlanCard(GInfo.getChannelInfo().ChannelID);        if(pCard != nullptr)        {            pCard->clickedCard();        }    }    auto pCard = PData.getCurrentPlanCard();    if(pCard == nullptr)    {        LH_WRITE_ERROR("没有选中频率卡片");        TipWidget::display(TipWidget::OPERATOR_WARN, "没有选中频率卡片", this);        return;    }    /* 判断有没有在倒计时中,如果在就不能操作 */    if(isFrequencyInCountdown(pCard->getChannelInfo().ChannelID))    {        TipWidget::display(TipWidget::OPERATOR_WARN, QString("<%1>正在倒计时中,无法修改计划").arg(pCard->getChannelInfo().ChannelName), this);        return;    }    /* 创建新增窗口 */    std::shared_ptr<ManagerPlan> mp = std::make_shared<ManagerPlan>(Enum_Mode::Mode_Modify);    /* 设置频率信息 */    mp->setFrequencyID(pCard->getChannelInfo());    mp->setFromWebAPI(m_fromWebAPI);    mp->setFromSQLite(m_fromSQLite);    connect(mp.get(), &ManagerPlan::signal_callBack, this, &TransmitterSwitch::do_callBack);    mp->exec();    /* 判断是否点击了OK */    if(!mp->isOK())    {        return;    }    /* 获取计划信息 */    auto& mapPlanInfo = mp->getPlanInfo();    auto list = mapPlanInfo.find(pCard->getChannelInfo().ChannelID);    pCard->setPlanList(*list);    /* 在线模式写入数据库,离线模式不需要写入 */    if(GInfo.isOnlineDB())    {        int chnID = pCard->getChannelInfo().ChannelID;        QList<OnePlanItemInfo> listPlan;        pCard->getAllPlanInfo(listPlan);        if(!m_fromWebAPI->insertData(chnID, listPlan))        {            LH_WRITE_ERROR(QString("频率ID为%1的计划写入数据库失败").arg(chnID));            TipWidget::display(TipWidget::OPERATOR_FAIL, QString("频率<%1>计划写入数据库失败").arg(pCard->getChannelInfo().ChannelName), this);        }    }        TipWidget::display(TipWidget::OPERATOR_OK, "修改计划成功", this);    /* 调用回调函数 */    if(m_trackCB != nullptr)    {        m_trackCB(1, g_mapTrack.value(1));    }}/* 点击了刷新按钮 */void TransmitterSwitch::do_pBtnRefresh(){    getExecPlanFromEQM();}/* 点击了“是否开启计划”按钮 */void TransmitterSwitch::do_pBtnIsOpenPlan(){    /* 判断有无权限 */    // if(GInfo.getUserPermission() != eUserPermission::User_Administrator)    // {    //     TipWidget::display(TipWidget::OPERATOR_WARN, "仅管理员可修改", this);    //     return;    // }    if(!GInfo.isOnlineDB())    {        return;    }    if(m_fromWebAPI == nullptr)    {        LH_WRITE_ERROR("未初始化WebAPI");        return;    }    /* 保存“默认计划”和“执行模式” */    ConfigData config1;    config1.key = static_cast<int>(enum_ExecPlanConfig::OpenPlan);    config1.value = ui->pBtn_defaultPlan->isChecked() ? 1 : 0;    config1.updateTime = QDateTime::currentDateTime();    CfgData.updateConfigData(config1);    /* 更新“计划是否更新”标志位,在更新前需要先获取数据库的标志位,如果依旧为1,那么本地是否更改都设置为1 */    ConfigData config3;    if(!m_fromWebAPI->getConfigData(static_cast<int>(enum_ExecPlanConfig::IsChanged), config3))    {        config3.key = static_cast<int>(enum_ExecPlanConfig::IsChanged);    }    /* 只要数据库和本地更新标志位有一个为true,说明还未被读走,则设置标志位为true */    config3.value = 1;    config3.updateTime = QDateTime::currentDateTime();    CfgData.updateConfigData(config3);    /* 将配置写入数据库 */    if(m_fromWebAPI->insertConfigData(CfgData.getMapConfigData()))    {        QString str = QString("执行计划状态设置为: %1").arg(ui->pBtn_defaultPlan->isChecked() ? "开启" : "关闭");        LH_WRITE_LOG(str);        /* 调用回调函数 */        if(m_trackCB != nullptr)        {            m_trackCB(1, g_mapTrack.value(1));        }    }}/* 点击了“执行模式”按钮 */void TransmitterSwitch::do_pBtnExecMode(){    /* 判断有无权限 */    // if(GInfo.getUserPermission() != eUserPermission::User_Administrator)    // {    //     TipWidget::display(TipWidget::OPERATOR_WARN, "仅管理员可修改", this);    //     return;    // }    if(!GInfo.isOnlineDB())    {        return;    }    if(m_fromWebAPI == nullptr)    {        LH_WRITE_ERROR("未初始化WebAPI");        return;    }    /* 保存“默认计划”和“执行模式” */    ConfigData config1;    config1.key = static_cast<int>(enum_ExecPlanConfig::ExecMode);    config1.value = ui->rBtn_moment->isChecked() ? 0 : 1;    config1.updateTime = QDateTime::currentDateTime();    CfgData.updateConfigData(config1);    /* 更新“计划是否更新”标志位,在更新前需要先获取数据库的标志位,如果依旧为1,那么本地是否更改都设置为1 */    ConfigData config3;    if(!m_fromWebAPI->getConfigData(static_cast<int>(enum_ExecPlanConfig::IsChanged), config3))    {        config3.key = static_cast<int>(enum_ExecPlanConfig::IsChanged);    }    /* 只要数据库和本地更新标志位有一个为true,说明还未被读走,则设置标志位为true */    config3.value = 1;    config3.updateTime = QDateTime::currentDateTime();    CfgData.updateConfigData(config3);    /* 将配置写入数据库 */    if(m_fromWebAPI->insertConfigData(CfgData.getMapConfigData()))    {        QString str = QString("执行计划模式设置为: %1").arg(ui->rBtn_moment->isChecked() ? "按时刻执行" : "按天执行");        LH_WRITE_LOG(str);        /* 调用回调函数 */        if(m_trackCB != nullptr)        {            m_trackCB(1, g_mapTrack.value(1));        }    }}/* 点击了清空计划按钮 */void TransmitterSwitch::do_pBtnClearPlan(){    /* 先判断是不是单频率模式,如果是,设置这个频率卡片被点击了 */    if(GInfo.isOneFrequency())    {        auto pCard = PData.findPlanCard(GInfo.getChannelInfo().ChannelID);        if(pCard != nullptr)        {            pCard->clickedCard();        }    }        /* 先判断有没有选中的频率卡片 */    auto pCard = PData.getCurrentPlanCard();    if(pCard == nullptr)    {        TipWidget::display(TipWidget::OPERATOR_FAIL, "没有选中频率卡片", this);        return;    }    /* 判断有没有在倒计时中,如果在就不能操作 */    if(isFrequencyInCountdown(pCard->getChannelInfo().ChannelID))    {        TipWidget::display(TipWidget::OPERATOR_WARN, QString("<%1>正在倒计时中,无法清空计划").arg(pCard->getChannelInfo().ChannelName), this);        return;    }    /* 跳出弹窗警告 */    Warning w(this);    w.setQSS(EPUIStyle.getQSSPath());    w.setText("确定删除对应频率开关机计划?");    bool flag = false;    connect(&w,&Warning::signal_ok,this,[&](){        flag = true;    });    w.exec();    if(!flag)    {        return;    }    /* 清空计划 */    pCard->clearPlanItem();    if(GInfo.isOnlineDB())    {        /* 删除数据库中的计划 */        if(!m_fromWebAPI->deleteOneChnPlan(pCard->getChannelInfo().ChannelID))        {            LH_WRITE_ERROR(QString("频率ID为%1的计划删除失败").arg(pCard->getChannelInfo().ChannelID));            TipWidget::display(TipWidget::OPERATOR_FAIL, QString("频率<%1>计划删除失败").arg(pCard->getChannelInfo().ChannelName), this);        }else {            TipWidget::display(TipWidget::OPERATOR_OK, "清空计划成功", this);        }    }else {        /* 离线模式不需要删除数据库中的计划 */        TipWidget::display(TipWidget::OPERATOR_OK, "清空计划成功", this);    }    /* 调用回调函数 */    if(m_trackCB != nullptr)    {        m_trackCB(1, g_mapTrack.value(1));    }}/* 点击了复制到其他频率按钮 */void TransmitterSwitch::do_pBtnCopyToOther(){    /* 判断是不是的那频率模式,如果是直接弹窗提示 */    if(GInfo.isOneFrequency())    {        TipWidget::display(TipWidget::OPERATOR_OK, "只有一个频率,无需复制", this);        return;    }    /* 先判断有没有选中的频率卡片 */    auto pCard = PData.getCurrentPlanCard();    if(pCard == nullptr)    {        TipWidget::display(TipWidget::OPERATOR_WARN, "没有选中频率卡片", this);        return;    }    /* 判断卡片有没有计划 */    if(pCard->isPlanEmpty())    {        TipWidget::display(TipWidget::OPERATOR_WARN, "当前频率没有计划", this);        return;    }    std::shared_ptr<CopyToOther> cto = std::make_shared<CopyToOther>(this);    cto->setQSSPath(EPUIStyle.getQSSPath());    cto->setFrequencyList(pCard->getChannelInfo(), ChnContainer.getMapChannel());    cto->exec();    /* 判断有没有点击OK */    if(!cto->isOk())    {        return;    }    /* 获取选中的频率列表 */    auto list = cto->getSelectedFrequencyList();    /* 获取当前频率的计划列表 */    QList<PlanInfo> listPlan;    pCard->getPlanList(listPlan);    /* 遍历所有的频率 */    bool isSuccess = true;    for(auto& it : list)    {        auto pTmpCard = PData.findPlanCard(it.ChannelID);        if(pTmpCard == nullptr)        {            LH_WRITE_ERROR(QString("没有找到频率ID为%1的卡片").arg(it.ChannelID));            continue;        }        /* 判断有没有在倒计时中,如果在就不能操作 */        if(isFrequencyInCountdown(pTmpCard->getChannelInfo().ChannelID))        {            TipWidget::display(TipWidget::OPERATOR_WARN, QString("<%1>正在倒计时中,无法变更计划").arg(pCard->getChannelInfo().ChannelName), this);            continue;        }        /* 设置计划列表 */        pTmpCard->setPlanList(listPlan);        QList<OnePlanItemInfo> tmpListPlan;        pTmpCard->getAllPlanInfo(tmpListPlan);        /* 写入数据库 */        if(!m_fromWebAPI->insertData(it.ChannelID, tmpListPlan))        {            LH_WRITE_ERROR(QString("频率ID为%1的计划写入数据库失败").arg(it.ChannelID));            TipWidget::display(TipWidget::OPERATOR_FAIL, QString("频率<%1>计划写入数据库失败").arg(it.ChannelName), this);            isSuccess = false;        }    }    if(isSuccess)    {        TipWidget::display(TipWidget::OPERATOR_OK, "复制计划成功", this);    }    /* 调用回调函数 */    if(m_trackCB != nullptr)    {        m_trackCB(1, g_mapTrack.value(1));    }}/* 导入数据 */void TransmitterSwitch::do_importData(){    /* 先判断是不是单频率模式,如果是,设置这个频率卡片被点击了 */    if(GInfo.isOneFrequency())    {        auto pCard = PData.findPlanCard(GInfo.getChannelInfo().ChannelID);        if(pCard != nullptr)        {            pCard->clickedCard();        }    }    /* 判断数据库是在线还是离线 */    if(GInfo.isOnlineDB())    {        importTemplateFromEQM();    } else    {        importTemplateFromSQLite();    } }/* 导出数据 */void TransmitterSwitch::do_exportData(){    /* 先判断是不是单频率模式,如果是,设置这个频率卡片被点击了 */    if(GInfo.isOneFrequency())    {        auto pCard = PData.findPlanCard(GInfo.getChannelInfo().ChannelID);        if(pCard != nullptr)        {            pCard->clickedCard();        }    }    /* 判断是否是在线模式 */    /* 先获取选中的卡片 */    auto pCard = PData.getCurrentPlanCard();    if(pCard == nullptr)    {        LH_WRITE_ERROR("没有选中频率卡片");        TipWidget::display(TipWidget::OPERATOR_WARN, "未选中频率卡片", this);        return;    }    /* 判断该卡片的计划列表是否为空 */    if(pCard->isPlanEmpty())    {        TipWidget::display(TipWidget::OPERATOR_WARN, "当前频率没有计划", this);        return;    }    ChannelInfo info = pCard->getChannelInfo();    do_saveTemplateToDB(info);    }/* 将模版写入数据库 */void TransmitterSwitch::do_saveTemplateToDB(ChannelInfo info){    if(GInfo.isOnlineDB())    {        saveTemplateToEQM(info);    }else {        saveTemplateToSQLite(info);    }}/* 保存计划到EQM数据库 */void TransmitterSwitch::do_pBtn_savePlan(){    /* 跳出弹窗提示 */    Warning w(this);    w.setQSS(EPUIStyle.getQSSPath());    w.setText("将计划保存到数据库?");    w.exec();    if(!w.isOk())    {        return;    }    saveExecPlanToEQM();}/* 删除一个模版 */void TransmitterSwitch::do_deleteTemplate(OneTemplateInfo info){    bool isSuccess = true;    if(GInfo.isOnlineDB())    {        deleteTemplateFromEQM(info);    }else     {        deleteTemplateFromSQLite(info);    }    }/* 点击了管理模板按钮 */void TransmitterSwitch::do_pBtnManageTemplate(){    if(GInfo.isOnlineDB())    {        manageTemplateFromEQM();    }else     {        manageTemplateFromSQLite();    }}/* 从EQM数据库获取计划 */void TransmitterSwitch::do_pBtn_getPlan(){    /* 跳出弹窗提示 */    Warning w(this);    w.setQSS(EPUIStyle.getQSSPath());    w.setText("从数据库获取计划,将清空当前所有的计划,请注意保存当前计划!");    w.exec();    if(!w.isOk())    {        return;    }    getExecPlanFromEQM();}/* 切换亮色/暗色外观 */void TransmitterSwitch::do_setUIStyle(){        this->setStyleSheet(EPUIStyle.StrQSS_TransmitterSwitch);    /* 给所有的按钮设置样式 */    ui->pBtn_allFrequency->setStyleSheet(EPUIStyle.StrQSS_PBtnFrequency);    // LH_WRITE_LOG(QString("频率按钮设置样式:%1").arg(EPUIStyle.StrQSS_PBtnFrequency));    for(auto& it : m_listFrequencyBtn)    {        it->setStyleSheet(EPUIStyle.StrQSS_PBtnFrequency);    }}/* 选择了一个频率按钮,取消其他的选择 */void TransmitterSwitch::do_selectFrequencyBtn(){    /* 获取信号发送者 */    auto btn = qobject_cast<QPushButton*>(sender());    if(btn == nullptr)    {        return;    }    /* 取消其他按钮的选择 */    for(auto& it : m_listFrequencyBtn)    {        if(it != btn)        {            it->setChecked(false);        }    }    if(btn != ui->pBtn_allFrequency)    {        ui->pBtn_allFrequency->setChecked(false);        /* 设置当前按钮的选择状态 */        btn->setChecked(true);        /* 设置该按钮对应的卡片状态 */        auto var = btn->property(m_userData_Btn.c_str());        auto pCard = var.value<PBtnUserData2*>()->getCard();        pCard->clickedCard();    }else {        ui->pBtn_allFrequency->setChecked(true);        /* 取消所有的卡片选择状态 */        PData.clearAllSelectedCard();    }    /* 显示当前按钮对应的卡片,隐藏其他卡片 */    showOneCard(btn);    }/* 调用了回调函数 */void TransmitterSwitch::do_callBack(int actionID){    if(m_trackCB == nullptr)    {        LH_WRITE_ERROR("回调函数为空");        return;    }    if(actionID < 0 || actionID >= static_cast<int>(g_mapTrack.size()))    {        LH_WRITE_ERROR(QString("错误的actionID: %1").arg(actionID));        return;    }    m_trackCB(actionID, g_mapTrack.value(actionID));}/* 添加一个频率,包括左侧按钮和右侧卡片 */void TransmitterSwitch::createOneCard(const ChannelInfo& chnInfo){    /* 创建按钮 */    QPushButton* pBtn = new QPushButton(this);    pBtn->setObjectName(chnInfo.ChannelName);    pBtn->setText(chnInfo.ChannelName);    pBtn->setCheckable(true);    pBtn->setMinimumHeight(40);    PBtnUserData2* userData = new PBtnUserData2();    userData->setChannelInfo(chnInfo);    // pBtn->setUserData(m_userData_Btn, userData);    QVariant var;    var.setValue(userData);    pBtn->setProperty(m_userData_Btn.c_str(), var);    /* 设置按钮的样式表 */    pBtn->setStyleSheet(EPUIStyle.StrQSS_PBtnFrequency);    /* 连接信号和槽 */    connect(pBtn, &QPushButton::clicked, this, &TransmitterSwitch::do_selectFrequencyBtn);    m_listFrequencyBtn.push_back(pBtn);    auto vLayout = qobject_cast<QVBoxLayout*>(ui->widget_frequency->layout());    /* 减1是去掉最下面的弹簧 */    vLayout->insertWidget(vLayout->count() - 1, pBtn);    /* 创建卡片 */    PlanCard* pCard = PData.createOneCard(chnInfo);    pCard->setParent(ui->scrollAreaContents_Card);    m_flowlayout->addWidget(pCard);    userData->setCard(pCard);  /* 设置按钮的卡片指针 */    /* 排序 */}/* 删除一个频率 */void TransmitterSwitch::deleteOneCard(int channelID){    /* 删除按钮 */    for(auto it = m_listFrequencyBtn.begin(); it != m_listFrequencyBtn.end(); ++it)    {        // auto userData = static_cast<PBtnUserData2*>((*it)->userData(m_userData_Btn));        auto userData = (*it)->property(m_userData_Btn.c_str()).value<PBtnUserData2*>();        if(userData != nullptr && userData->getChannelInfo().ChannelID == channelID)        {            delete *it;            m_listFrequencyBtn.erase(it);            break;        }    }    /* 删除卡片 */    PData.deleteOneCard(channelID);}/* 创建所有频率卡片 */void TransmitterSwitch::createAllCard(){    /* 删除所有的卡片 */    PData.deleteAllCard();    /* 删除所有按钮 */    for(auto it = m_listFrequencyBtn.begin(); it != m_listFrequencyBtn.end(); ++it)    {        delete *it;    }    m_listFrequencyBtn.clear();    if(!GInfo.isOneFrequency())    {        for(const auto& it : ChnContainer.getMapChannel())        {            /* 创建一个按钮和卡片 */            createOneCard(it);        }    }else {        /* 创建一个按钮和卡片 */        createOneCard(GInfo.getChannelInfo());    }    /* 隐藏重新显示一下,调用显示事件,重新设置卡片大小 */    this->hide();    QEventLoop loop;    loop.processEvents();    this->show();}/* 显示某个卡片,隐藏其他卡片 */void TransmitterSwitch::showOneCard(QPushButton *btn){    /* 判断是否是显示全部卡片的按钮 */    if(btn == ui->pBtn_allFrequency)    {        /* 设置卡片间的横向间距 */        m_flowlayout->setHorizontalSpacing(m_cardHorSpacing);        /* 显示全部卡片 */        for(auto& it : m_listFrequencyBtn)        {            // auto ud = it->userData(m_userData_Btn);            PBtnUserData2* userData = it->property(m_userData_Btn.c_str()).value<PBtnUserData2*>();            if(userData != nullptr)            {                auto pCard = userData->getCard();                if(pCard != nullptr)                {                    pCard->show();                }            }        }        /* 刷新布局,刷新了才会让FlowLayout重新布局 */        ui->scrollAreaContents_Card->updateGeometry();        return;    }    /* 设置卡片间的横向间距 */    m_flowlayout->setHorizontalSpacing(0);    /* 不是显示全部的按钮,隐藏所有卡片 */    for(auto& it : m_listFrequencyBtn)    {        // auto ud = it->userData(m_userData_Btn);        PBtnUserData2* userData = it->property(m_userData_Btn.c_str()).value<PBtnUserData2*>();        if(userData != nullptr)        {            auto pCard = userData->getCard();            if(pCard != nullptr)            {                pCard->hide();            }        }    }    /* 显示当前卡片 */    // auto ud = btn->userData(m_userData_Btn);    // PBtnUserData2* userData = static_cast<PBtnUserData2*>(ud);    PBtnUserData2* userData = btn->property(m_userData_Btn.c_str()).value<PBtnUserData2*>();    if(userData != nullptr)    {        auto pCard = userData->getCard();        if(pCard != nullptr)        {            pCard->show();        }    }    /* 刷新布局,刷新了才会让FlowLayout重新布局 */    ui->scrollAreaContents_Card->updateGeometry();}/* 计算并设置设置卡片大小 */void TransmitterSwitch::setCardSize(){    /* 获取滚动条的区域 */    int vsb = 0;    if(ui->scrollArea->verticalScrollBar()->isVisible())    {        vsb = ui->scrollArea->verticalScrollBar()->width();    }    /* 去掉滚动条的宽度和阴影的宽度,再减去一个横向间距,和滚动条有些距离,不挨着太紧 */    int saWidth = ui->scrollArea->width() - vsb - m_cardHorSpacing - 2;     int saHeight = ui->scrollArea->height();    int cardWidth = ( saWidth - (m_cardHorNumber - 1) * m_cardHorSpacing ) / m_cardHorNumber;    int cardHeight = ( saHeight - (m_cardVerNumber - 1) * m_cardVerSpacing ) / m_cardVerNumber;    /* 设置卡片大小 */    PData.setCardSize(cardWidth, cardHeight);    // LH_WRITE_LOG_DEBUG(QString("卡片大小:%1*%2").arg(cardWidth).arg(cardHeight));}/* 计算并设置提示文本的位置 */void TransmitterSwitch::setTipTextPos(){    if(m_tipText != nullptr)    {        QPoint pos = ui->label_Tip->mapTo(this, QPoint(0, 0));        m_tipText->move(pos.x() - m_tipText->width(), pos.y() + 32 );    }}/* 设置单频率模式 */void TransmitterSwitch::setOneFrequencyMode(){    /* 先判断是在线还是离线模式 */    if(GInfo.isOnlineDB())    {        auto chnInfo = ChnContainer.getChannel(GInfo.getChannelInfo().ChannelID);        if(chnInfo.ChannelID < 0)        {            LH_WRITE_ERROR(QString("没有找到频率ID为%1的频率信息").arg(GInfo.getChannelInfo().ChannelID));            return;        }else {            /* 设置频率信息 */            GInfo.setChannelInfo(chnInfo);        }        /* 如果设置了特定的频率,删除其他的频率 */        ChnContainer.deleteOtherChannel(GInfo.getChannelInfo().ChannelID);    }else     {        /* 清空所有频率 */        ChnContainer.clearAllChannel();        /* 设置频率信息 */        ChnContainer.addChannel(GInfo.getChannelInfo());    }        /* 隐藏复制到其他频率的按钮 */    ui->pBtn_cloneToOther->hide();    /* 隐藏全部频率按钮 */    ui->pBtn_allFrequency->hide();}/* 设置使用在线或者使用离线数据库,主要是保存模版 */void TransmitterSwitch::setUseOnlineDB(bool useOnlineDB){    GInfo.setOnlineDB(useOnlineDB);    if(GInfo.isOnlineDB())    {        /* 在线模式,获取数据库频率信息 */        if(!m_fromWebAPI->getChannelInfo(ChnContainer.getMapChannel()))        {            LH_WRITE_ERROR("获取频率信息失败");            TipWidget::display(TipWidget::OPERATOR_FAIL, "获取频率信息失败", this);            return;        }else {            LH_WRITE_LOG("获取频率信息成功!");        }    }else     {        /* 如果使用离线数据库,初始化SQLite */        if(m_fromSQLite == nullptr)        {            m_fromSQLite = new FromSQLite;            m_fromSQLite->initDB(GInfo.getDatabasePath());        }    }    }/* 从EQM数据库导入模版 */void TransmitterSwitch::importTemplateFromEQM(){    if(m_fromWebAPI == nullptr)    {        LH_WRITE_ERROR("没有初始化FromWebAPI");        return;    }    QMultiMap<int, OneTemplateInfo> tabList;    /* 判断有没有选中卡片 */    auto pCard = PData.getCurrentPlanCard();    bool isSuccess = true;    if(pCard == nullptr)    {        /* 没有选中卡片,获取全部的频率 */        if(!m_fromWebAPI->getTemplateList(tabList))        {            isSuccess = false;        }    } else     {        /* 选中了卡片,只获取这个卡片的频率列表 */        QList<OneTemplateInfo> list;        if(m_fromWebAPI->getTemplateList(pCard->getChannelInfo().ChannelID, list))        {            for(auto it = list.begin(), end = list.end(); it != end; it++)            {                tabList.insert(it->channelInfo.ChannelID, *it);            }        }else {            isSuccess = false;            LH_WRITE_ERROR(QString("获取频率ID为%1的模版列表失败").arg(pCard->getChannelInfo().ChannelID));        }    }    if(isSuccess == false)    {        TipWidget::display(TipWidget::OPERATOR_FAIL, "获取模版列表失败", this);        return;    }        /* 将模板列表添加频率信息 */    for(auto it = tabList.begin(), end = tabList.end(); it != end; it++)    {        auto chnInfo = ChnContainer.getChannel(it->channelInfo.ChannelID);        it->channelInfo = chnInfo;    }    std::shared_ptr<ImportTemplate> it = std::make_shared<ImportTemplate>();    it->setQSSPath(EPUIStyle.getQSSPath());    it->setTemplateList(tabList);    it->exec();    /* 判断有没有点击OK */    if(!it->isOk())    {        return;    }    /* 获取选中的模版 */    auto tmpList = it->getSelectedTemplateList();    /* 判断有没有选中需要导入模版 */    if(tmpList.isEmpty())    {        TipWidget::display(TipWidget::OPERATOR_WARN, "无模板导入", this);        return;    }    QMap<int, QList<OnePlanItemInfo>> mapPlan;    m_fromWebAPI->getTemplateData(tmpList, mapPlan);    /* 将所有的模板数据插入到卡片中 */    for(auto begin = mapPlan.begin(), end = mapPlan.end(); begin != end; begin++)    {        auto pCard = PData.findPlanCard(begin.key());        if(pCard == nullptr)        {            LH_WRITE_ERROR(QString("没有找到频率ID为%1的卡片").arg(begin.key()));            continue;        }        /* 判断有没有在倒计时中,如果在就不能操作 */        if(isFrequencyInCountdown(pCard->getChannelInfo().ChannelID))        {            TipWidget::display(TipWidget::OPERATOR_WARN, QString("<%1>正在倒计时中,无法导入模版").arg(pCard->getChannelInfo().ChannelName), this);            continue;        }        /* 设置计划列表 */        pCard->setPlanList(begin.value());        /* 写入数据库 */        if(!m_fromWebAPI->insertData(begin.key(), begin.value()))        {            LH_WRITE_ERROR(QString("频率ID为%1的计划写入数据库失败").arg(begin.key()));            TipWidget::display(TipWidget::OPERATOR_FAIL, QString("频率<%1>计划写入数据库失败").arg(pCard->getChannelInfo().ChannelName), this);            isSuccess = false;        }    }    if(isSuccess)    {        TipWidget::display(TipWidget::OPERATOR_OK, "导入模版成功", this);    }    /* 调用回调函数 */    if(m_trackCB != nullptr)    {        m_trackCB(4, g_mapTrack.value(4));    }}/* 从SQLite导入模版 */void TransmitterSwitch::importTemplateFromSQLite(){    if(m_fromSQLite == nullptr)    {        LH_WRITE_ERROR("没有初始化FromSQLite");        return;    }    QMultiMap<int, OneTemplateInfo> tabList;    /* 获取当前选中的卡片 */    auto pCard = PData.getCurrentPlanCard();    bool isSuccess = true;    /* 选中了卡片,只获取这个卡片的频率列表 */    QList<OneTemplateInfo> list;    if(m_fromSQLite->getTemplateList(pCard->getChannelInfo().ChannelID, list))    {        for(auto it = list.begin(), end = list.end(); it != end; it++)        {            tabList.insert(it->channelInfo.ChannelID, *it);        }    }else {        isSuccess = false;        LH_WRITE_ERROR(QString("获取频率ID为%1的模版列表失败").arg(pCard->getChannelInfo().ChannelID));    }    if(isSuccess == false)    {        TipWidget::display(TipWidget::OPERATOR_FAIL, "获取模版列表失败", this);        return;    }        /* 将模板列表添加频率信息 */    for(auto it = tabList.begin(), end = tabList.end(); it != end; it++)    {        auto chnInfo = GInfo.getChannelInfo();        it->channelInfo = chnInfo;    }    std::shared_ptr<ImportTemplate> it = std::make_shared<ImportTemplate>();    it->setQSSPath(EPUIStyle.getQSSPath());    it->setTemplateList(tabList);    it->exec();    /* 判断有没有点击OK */    if(!it->isOk())    {        return;    }    /* 获取选中的模版 */    auto tmpList = it->getSelectedTemplateList();    /* 判断有没有选中需要导入模版 */    if(tmpList.isEmpty())    {        TipWidget::display(TipWidget::OPERATOR_WARN, "无模板导入", this);        return;    }    QList<OnePlanItemInfo> listPlan;    if(!m_fromSQLite->getTemplateData(tmpList.first(), listPlan))    {        LH_WRITE_ERROR("获取模版数据失败");        TipWidget::display(TipWidget::OPERATOR_FAIL, "导入模版数据失败", this);        return;    }    /* 设置计划列表 */    pCard->setPlanList(listPlan);    TipWidget::display(TipWidget::OPERATOR_OK, "导入模版成功", this);}/* 将模版写入数据库 */void TransmitterSwitch::saveTemplateToEQM(ChannelInfo info){    if(m_fromWebAPI == nullptr)    {        LH_WRITE_ERROR("没有初始化FromWebAPI");        return;    }    auto pCard = PData.findPlanCard(info.ChannelID);    if(pCard == nullptr)    {        LH_WRITE_ERROR(QString("没有找到频率ID为%1的卡片").arg(info.ChannelID));        return;    }    int chnID = info.ChannelID;    /* 获取所有的模板名称 */    QList<OneTemplateInfo> list;    if(!m_fromWebAPI->getTemplateList(chnID, list))    {        LH_WRITE_ERROR(QString("获取频率ID为%1的模版列表失败").arg(chnID));        TipWidget::display(TipWidget::OPERATOR_FAIL, "获取模版列表失败", this);        return;    }    /* 弹出导出页面 */    std::shared_ptr<SaveToTemplate> stt = std::make_shared<SaveToTemplate>();    stt->setQSS(EPUIStyle.getQSSPath());    stt->setTemplateList(list);    stt->exec();    if(!stt->isOk())    {        return;    }    /* 获取一天的数据 */    QList<OnePlanItemInfo> listTmp;    pCard->getAllPlanInfo(listTmp);    /* 保存到模板 */    if(m_fromWebAPI->saveTemplate(stt->getTemplateName(), listTmp))    {        TipWidget::display(TipWidget::OPERATOR_OK, "保存模版成功", this);    }else {        TipWidget::display(TipWidget::OPERATOR_FAIL, "保存模版失败", this);    }    /* 调用回调函数 */    if(m_trackCB != nullptr)    {        m_trackCB(3, g_mapTrack.value(3));    }    }/* 保存计划到SQLite数据库 */void TransmitterSwitch::saveTemplateToSQLite(ChannelInfo info){    if(m_fromSQLite == nullptr)    {        LH_WRITE_ERROR("没有初始化FromSQLite");        return;    }    auto pCard = PData.findPlanCard(info.ChannelID);    if(pCard == nullptr)    {        LH_WRITE_ERROR(QString("没有找到频率ID为%1的卡片").arg(info.ChannelID));        return;    }    int chnID = info.ChannelID;    /* 获取所有的模板名称 */    QList<OneTemplateInfo> list;    if(!m_fromSQLite->getTemplateList(chnID, list))    {        LH_WRITE_ERROR(QString("获取频率ID为%1的模版列表失败").arg(chnID));        TipWidget::display(TipWidget::OPERATOR_FAIL, "获取模版列表失败", this);        return;    }    /* 弹出导出页面 */    std::shared_ptr<SaveToTemplate> stt = std::make_shared<SaveToTemplate>();    stt->setQSS(EPUIStyle.getQSSPath());    stt->setTemplateList(list);    stt->exec();    if(!stt->isOk())    {        return;    }    /* 获取一天的数据 */    QList<OnePlanItemInfo> listTmp;    pCard->getAllPlanInfo(listTmp);    /* 保存到模板 */    if(m_fromSQLite->saveTemplate(stt->getTemplateName(), listTmp))    {        TipWidget::display(TipWidget::OPERATOR_OK, "保存模版成功", this);    }else {        TipWidget::display(TipWidget::OPERATOR_FAIL, "保存模版失败", this);    }    /* 调用回调函数 */    if(m_trackCB != nullptr)    {        m_trackCB(3, g_mapTrack.value(3));    }}/* 从EQM数据库中删除一个模版 */void TransmitterSwitch::deleteTemplateFromEQM(OneTemplateInfo info){    if(m_fromWebAPI == nullptr)    {        LH_WRITE_ERROR("没有初始化FromWebAPI");        return;    }    /* 删除模版 */    if(m_fromWebAPI->deleteTemplate(info))    {        TipWidget::display(TipWidget::OPERATOR_OK, "删除模版成功", this);    }else {        TipWidget::display(TipWidget::OPERATOR_FAIL, "从数据库删除模版失败", this);        LH_WRITE_ERROR("从EQM数据库删除模版失败");    }}/* 从SQLite数据库中删除一个模版 */void TransmitterSwitch::deleteTemplateFromSQLite(OneTemplateInfo info){    if(m_fromSQLite == nullptr)    {        LH_WRITE_ERROR("没有初始化FromSQLite");        return;    }    if(m_fromSQLite->deleteTemplate(info))    {        TipWidget::display(TipWidget::OPERATOR_OK, "删除模版成功", this);    }else {        TipWidget::display(TipWidget::OPERATOR_FAIL, "从数据库删除模版失败", this);        LH_WRITE_ERROR("从SQLite数据库删除模版失败");    }}/* 管理EQM数据库的模版数据 */void TransmitterSwitch::manageTemplateFromEQM(){    if(m_fromWebAPI == nullptr)    {        LH_WRITE_ERROR("没有初始化FromWebAPI");        return;    }    /* int是频率ID */    QMultiMap<int, OneTemplateInfo> tabList;    /* 获取全部的频率 */    if(!m_fromWebAPI->getTemplateList(tabList))    {        TipWidget::display(TipWidget::OPERATOR_FAIL, "获取模版列表失败", this);        return;    }    /* 判断是不是单频率模式,如果是,则删除其他的频率 */    if(GInfo.isOneFrequency())    {        for(auto it = tabList.begin(), end = tabList.end(); it != end; it++)        {            if(it.key() != GInfo.getChannelInfo().ChannelID)            {                tabList.erase(it);            }        }    }        /* 将模板列表添加频率信息 */    for(auto it = tabList.begin(), end = tabList.end(); it != end; it++)    {        auto chnInfo = ChnContainer.getChannel(it->channelInfo.ChannelID);        it->channelInfo = chnInfo;    }    std::shared_ptr<TemplateManager> tm = std::make_shared<TemplateManager>();    tm->setQSSPath(EPUIStyle.getQSSPath());    tm->setTemplateList(tabList);    tm->setWebAPI(m_fromWebAPI);    tm->exec();    /* 判断是否点击了OK */    if(!tm->isOk())    {        return;    }    bool isSuccess = true;    /* 获取删除的计划列表 */    auto list = tm->getDeleteTemplateList();    if(!m_fromWebAPI->deleteTemplateList(list))    {        LH_WRITE_ERROR("删除模版失败");        TipWidget::display(TipWidget::OPERATOR_FAIL, "删除模版失败", this);        isSuccess = false;    }    /* 更新模版列表 */    auto mapTmp = tm->getModifyTemplateList();    if(!m_fromWebAPI->modifyTemplateList(mapTmp))    {        LH_WRITE_ERROR("修改模版失败");        TipWidget::display(TipWidget::OPERATOR_FAIL, "修改模版失败", this);        isSuccess = false;    }    /* 更新模板名称 */    auto mapTmpName = tm->getModifyTemplateNameList();    if(!m_fromWebAPI->updateTemplateName(mapTmpName))    {        LH_WRITE_ERROR("修改模版名称失败");        TipWidget::display(TipWidget::OPERATOR_FAIL, "修改模版名称失败", this);        isSuccess = false;    }        if(isSuccess)    {        TipWidget::display(TipWidget::OPERATOR_OK, "修改模版成功", this);    }}/* 管理SQLite数据库的模版数据 */void TransmitterSwitch::manageTemplateFromSQLite(){    if (m_fromSQLite == nullptr)    {        LH_WRITE_ERROR("没有初始化FromSQLite");        return;    }    QList<OneTemplateInfo> listTemplate;    /* 获取全部的频率 */    if(!m_fromSQLite->getTemplateList(GInfo.getChannelInfo().ChannelID, listTemplate))    {        TipWidget::display(TipWidget::OPERATOR_FAIL, "获取模版列表失败", this);        return;    }        /* int是频率ID */    QMultiMap<int, OneTemplateInfo> mapTemplate;    /* 将模板列表添加频率信息 */    for(auto it = listTemplate.begin(), end = listTemplate.end(); it != end; it++)    {        it->channelInfo = GInfo.getChannelInfo();        mapTemplate.insert(it->channelInfo.ChannelID, *it);    }    /* 打开模板管理页面 */    std::shared_ptr<TemplateManager> tm = std::make_shared<TemplateManager>();    tm->setQSSPath(EPUIStyle.getQSSPath());    tm->setTemplateList(mapTemplate);    tm->setFromSQLite(m_fromSQLite);    tm->exec();    /* 判断是否点击了OK */    if(!tm->isOk())    {        return;    }    bool isSuccess = true;    /* 获取删除的计划列表 */    auto list = tm->getDeleteTemplateList();    if(!m_fromSQLite->deleteTemplateList(list))    {        LH_WRITE_ERROR("删除模版失败");        TipWidget::display(TipWidget::OPERATOR_FAIL, "删除模版失败", this);        isSuccess = false;    }    /* 更新模版列表 */    auto mapTmp = tm->getModifyTemplateList();    if(!m_fromSQLite->modifyTemplateList(mapTmp))    {        LH_WRITE_ERROR("修改模版失败");        TipWidget::display(TipWidget::OPERATOR_FAIL, "修改模版失败", this);        isSuccess = false;    }    /* 更新模板名称 */    auto mapTmpName = tm->getModifyTemplateNameList();    if(!m_fromSQLite->updateTemplateName(mapTmpName))    {        LH_WRITE_ERROR("修改模版名称失败");        TipWidget::display(TipWidget::OPERATOR_FAIL, "修改模版名称失败", this);        isSuccess = false;    }        if(isSuccess)    {        TipWidget::display(TipWidget::OPERATOR_OK, "修改模版成功", this);    }}/* 判断当前频率是否在倒计时 */bool TransmitterSwitch::isFrequencyInCountdown(int channelID){    auto pCard = PData.findPlanCard(channelID);    if(pCard == nullptr)    {        LH_WRITE_ERROR(QString("没有找到频率ID为%1的卡片").arg(channelID));        return false;    }    QList<PlanInfo> list;    pCard->getPlanList(list);    bool isNear = false;    QDateTime nowTime = QDateTime::currentDateTime();    /* 先判断特殊日 */    for(const auto& it : list)    {        if(it.onWeekDay == enum_WeekDay::WeekDay_Special)        {            if(isInCountdownTime(nowTime, it.onWeekDay, it.onDateTime))            {                /* 找到特殊日的计划 */                isNear = true;                break;            }            if(isInCountdownTime(nowTime, it.offWeekDay, it.offDateTime))            {                /* 找到特殊日的计划 */                isNear = true;                break;            }        }    }    if(isNear)    {        /* 找到特殊日的计划,直接返回 */        return true;    }    /* 判断正常日 */    for(const auto& it : list)    {        if(it.onWeekDay != enum_WeekDay::WeekDay_Special)        {            if(isInCountdownTime(nowTime, it.onWeekDay, it.onDateTime))            {                /* 找到正常日的计划 */                isNear = true;                break;            }            if(isInCountdownTime(nowTime, it.offWeekDay, it.offDateTime))            {                /* 找到正常日的计划 */                isNear = true;                break;            }        }    }    return isNear;}/* 判断两个时间点是否在十分钟之内 */bool TransmitterSwitch::isInCountdownTime(const QDateTime& nowTime, const enum_WeekDay weekDay, const QDateTime& time){    // 10分钟后    int tenMinutes = 10 * 60;    QDateTime afterTenMins = nowTime.addSecs(tenMinutes);    enum_WeekDay nowWeekDay = static_cast<enum_WeekDay>(nowTime.date().dayOfWeek());    enum_WeekDay afterWeekDay = static_cast<enum_WeekDay>(afterTenMins.date().dayOfWeek());    /* 先判断是否是特殊日 */    if(weekDay == enum_WeekDay::WeekDay_Special)    {        if(time <= afterTenMins && time > nowTime)        {            /* 在10分钟之内 */            return true;        }    }    /* 正常日,判断执行时间是否在这两天 */    if(weekDay != nowWeekDay || weekDay != afterWeekDay)    {        /* 执行时间不在这两天,直接返回false */        return false;    }    /* 正常日,先判断十分钟后有没有跨天 */    if(nowWeekDay == afterWeekDay)    {        /* 在同一天 */        if(time.time() <= afterTenMins.time() && time.time() >= nowTime.time())        {            /* 在10分钟之内 */            return true;        }    }else {        /* 跨天了,判断时间 */        if(weekDay == nowWeekDay)        {            /* 执行时间在今天 */            if(time.time() >= nowTime.time())            {                /* 在今天的10分钟之内 */                return true;            }        } else        {            /* 执行在明天 */            if(time.time() <= afterTenMins.time())            {                return true;            }        }    }    return false; /* 不在10分钟之内 */}/* 事件过滤器 */bool TransmitterSwitch::eventFilter(QObject *watched, QEvent *event){    if(watched == ui->label_Tip)    {        if(event->type() == QEvent::Enter)        {            m_tipText->show();            return true;        }else if(event->type() == QEvent::Leave)        {            m_tipText->hide();        }    }    return QWidget::eventFilter(watched,event);}/* 窗口缩放事件 */void TransmitterSwitch::resizeEvent(QResizeEvent *event){    /* 设置提示文本的位置 */    setTipTextPos();    setCardSize();    QWidget::resizeEvent(event);}/* 显示事件 */void TransmitterSwitch::showEvent(QShowEvent *event){    /* 设置提示文本的位置 */    setTipTextPos();    setCardSize();    QWidget::showEvent(event);}
 |