#include "ToolDialog.h" #include #include #include #include #include #include ////////////////////////////////////////////////////////////////////////// #include "Qsci/qsciapis.h" #include "Qsci/qscilexercpp.h" #include "Qsci/qscilexercpp.h" #include "Qsci/qscilexerlua.h" #include "Qsci/qsciscintilla.h" #include "Qsci/qscilexerjavascript.h" ////////////////////////////////////////////////////////////////////////// ToolDialogImpl::ToolDialogImpl(QWidget* parent, DllTool* pDllTool) : DllToolDialog(parent) , m_pDllTool(pDllTool) { ui.setupUi(this); this->setWindowFlags(Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint /*| Qt::WindowStaysOnTopHint*/); m_fValue1 = 11; m_fValue2 = 22; m_fValue3 = 33; m_fValue4 = 44; m_fValue5 = 55; m_ValueMap.insert("V1", &m_fValue1); m_ValueMap.insert("V2", &m_fValue2); m_ValueMap.insert("V3", &m_fValue3); m_ValueMap.insert("VO1", &m_fValue4); m_ValueMap.insert("VO2", &m_fValue5); // 设置比例 QList sizes; sizes << 1000 << 5000; ui.splitter->setSizes(sizes); connect(this, SIGNAL(sigUpdateUI()), this, SLOT(on_UpdateUI())); ///////////////////////////////>>//////////////// initScriptEdit(); initEngine(); initDebugger(); } ToolDialogImpl::~ToolDialogImpl() { if (scriptEdit != nullptr) { delete scriptEdit; scriptEdit = nullptr; } } VPEnum::RETURN_VALUE ToolDialogImpl::Execute() { //return VPEnum::RETURN_VALUE::Success; try { //m_strCodes = scriptEdit->text(); QScriptValue result = m_pEngine->evaluate(m_strCodes); if (result.isError()) { QString err = QString::fromLatin1("script syntax evaluate error: %1 %2") .arg(result.property("lineNumber").toInt32()) .arg(result.toString()); qWarning() << "Error Msg" << err; } } catch (...) { qWarning() << "Execute() Error"; } emit sigUpdateUI(); return VPEnum::RETURN_VALUE::Success; } /// /// /// /// void ToolDialogImpl::Running(bool bRun) { } /// /// /// /// /// /// bool ToolDialogImpl::Serialized(QDataStream& ar, bool bIsOut) { int paranum;//参数数量 if (bIsOut)//保存参数流程 { paranum = 1; ar << paranum;//先保存参数数量 ar << (int)1 << m_strCodes; } else//加载参数流程,参数加载顺序一定要跟保存顺序一致 { int nFumctionNameSize = 0; int para; ar >> paranum;//读取参数数量 for (int i = 0; i < paranum; i++) { ar >> para; switch (para) { case 1: ar >> m_strCodes; break; default: { qWarning() << "Serialized(In) Error"; return false; } break; } } scriptEdit->setText(m_strCodes); } return true; } QScriptValue ToolDialogImpl::Sleep(QScriptContext* context, QScriptEngine* engine, void* pargs) { ToolDialogImpl* pDlg = (ToolDialogImpl*)pargs; Q_UNUSED(engine); QScriptValue id = context->argument(0); int nValue = id.toString().toInt(); Utility::qSleep(nValue); return 1; } QScriptValue ToolDialogImpl::SetRealValue(QScriptContext* context, QScriptEngine* engine, void* pargs) { ToolDialogImpl* pDlg = (ToolDialogImpl*)pargs; Q_UNUSED(engine); QScriptValue skey = context->argument(0); QString strKey = skey.toString(); QScriptValue sVar = context->argument(1); float fValue = sVar.toString().toFloat(); if (pDlg->m_ValueMap[strKey] != nullptr) { *pDlg->m_ValueMap[strKey] = fValue; } else { qWarning() << "SetRealValue Error Key" << strKey << "is Null"; } return 1; } QScriptValue ToolDialogImpl::GetRealValue(QScriptContext* context, QScriptEngine* engine, void* pargs) { ToolDialogImpl* pDlg = (ToolDialogImpl*)pargs; Q_UNUSED(engine); Q_UNUSED(pargs); QScriptValue sVar = context->argument(0); QString strKey = sVar.toString(); float fValue = 0; if (pDlg->m_ValueMap.value(strKey) != nullptr) { fValue = *pDlg->m_ValueMap.value(strKey); } else { qWarning() << "GetRealValue Error Key" << strKey << "is Null"; } return fValue; } void ToolDialogImpl::on_UpdateUI() { } /// /// 确定 /// void ToolDialogImpl::on_btnOK_clicked() { this->hide(); } /// /// 取消按钮 /// void ToolDialogImpl::on_btnCancel_clicked() { // 将本工具的恢复到打开工具之前的状态 RecoverData(); } /// /// 测试按钮 /// void ToolDialogImpl::on_btnExecute_clicked() { QElapsedTimer toolTimer; toolTimer.start(); // 发送事件 ToolEvent* pToolEvent = new ToolEvent(m_strPouName, m_strInstanceName, TOOL_EVENT_TYPE::TOOL_TRIGGER); QCoreApplication::sendEvent(m_pEventTarget, pToolEvent); // 统计返回值 VPEnum::RETURN_VALUE ret = pToolEvent->ret; double nExecTime = toolTimer.elapsed(); QString str; str = QString("耗时: %1 ms").arg(nExecTime, 0, 'G', 5); ui.label_time->setText(str); str = QString("状态: %1 ").arg(QMetaEnum::fromType().key((short)ret)); ui.label_state->setText(str); delete pToolEvent; } void ToolDialogImpl::initScriptEdit() { int nSize = ui.stackedWidget->count(); ui.stackedWidget->setCurrentIndex(1); scriptEdit = new QsciScintilla(ui.widgetEditor); QsciLexerJavaScript* scriptLexer = new QsciLexerJavaScript(); //创建一个词法分析器 scriptLexer->setDefaultPaper("#b3b3b3"); scriptEdit->setLexer(scriptLexer); //设置词法分析器 scriptEdit->setMarginType(0, QsciScintilla::MarginType::NumberMargin); //设置编号为0的页边显示行号。 scriptEdit->setMarginLineNumbers(0, true); //启用行号 scriptEdit->setMarginWidth(0, 26); QsciAPIs* apis = new QsciAPIs(scriptLexer); //代码提示 apis->add(QString("local")); apis->prepare(); //开启自动缩进 scriptEdit->setAutoIndent(true); //设置缩进的显示方式 //scriptEdit->setIndentationGuides(QsciScintilla::SC_IV_LOOKBOTH); //显示选中的行号 scriptEdit->setCaretLineVisible(true); //显示选中行号的背景色 scriptEdit->setCaretLineBackgroundColor(Qt::lightGray); //左侧行号显示的背景色 scriptEdit->setMarginsBackgroundColor(Qt::gray); //设置括号匹配 scriptEdit->setBraceMatching(QsciScintilla::BraceMatch::SloppyBraceMatch); scriptEdit->setFolding(QsciScintilla::FoldStyle::BoxedTreeFoldStyle);//折叠样式 scriptEdit->setFoldMarginColors(Qt::gray, Qt::lightGray);//折叠栏颜色 scriptEdit->setAutoCompletionThreshold(3);//设置每输入一个字符就会出现自动补全的提示 scriptEdit->setFont(QFont("Courier New")); //设置字体 scriptEdit->SendScintilla(QsciScintilla::SCI_SETCODEPAGE, QsciScintilla::SC_CP_UTF8); //设置编码为UTF-8 connect(scriptEdit, SIGNAL(textChanged()), this, SLOT(documentWasModified())); QVBoxLayout* vLayout = new QVBoxLayout(); vLayout->setContentsMargins(1, 1, 1, 1); vLayout->setObjectName(QStringLiteral("vLayout")); vLayout->addWidget(scriptEdit); ui.widgetEditor->setLayout(vLayout); } void ToolDialogImpl::initEngine() { m_pEngine = new QScriptEngine(); // Sleep m_pEngine->globalObject().setProperty("Sleep", m_pEngine->newFunction(&ToolDialogImpl::Sleep, this)); // SetRealValue m_pEngine->globalObject().setProperty("SetRealValue", m_pEngine->newFunction(&ToolDialogImpl::SetRealValue, this)); // GetRealValue m_pEngine->globalObject().setProperty("GetRealValue", m_pEngine->newFunction(&ToolDialogImpl::GetRealValue, this)); } void ToolDialogImpl::initDebugger() { QWidget* widget = (ui.widgetDebug); m_pDebugger = new QScriptEngineDebugger(); m_pDebugger->setAutoShowStandardWindow(false); QAction* interruptAction = m_pDebugger->action(QScriptEngineDebugger::InterruptAction); QAction* continueAction = m_pDebugger->action(QScriptEngineDebugger::ContinueAction); QAction* stepIntoAction = m_pDebugger->action(QScriptEngineDebugger::StepIntoAction); QAction* stepOverAction = m_pDebugger->action(QScriptEngineDebugger::StepOverAction); QAction* stepOutAction = m_pDebugger->action(QScriptEngineDebugger::StepOutAction); QToolBar* toolBar = new QToolBar; //toolBar->addAction(interruptAction); //toolBar->addAction(continueAction); toolBar->addAction(stepIntoAction); toolBar->addAction(stepOverAction); toolBar->addAction(stepOutAction); QWidget* codeWidget = m_pDebugger->widget(QScriptEngineDebugger::CodeWidget); QWidget* consoleWidget = m_pDebugger->widget(QScriptEngineDebugger::ConsoleWidget); QWidget* debugOutputWidget = m_pDebugger->widget(QScriptEngineDebugger::DebugOutputWidget); QWidget* errorLogWidget = m_pDebugger->widget(QScriptEngineDebugger::ErrorLogWidget); QLayout* layout = new QVBoxLayout; QTabWidget* tab = new QTabWidget(widget); layout->addWidget(toolBar); layout->addWidget(codeWidget); layout->addWidget(tab); layout->setContentsMargins(0, 0, 0, 0); int index = 0; tab->insertTab(index, consoleWidget, tr("console")); // tab->insertTab(index++, localsWidget,tr("locals")); tab->insertTab(index++, debugOutputWidget, tr("debug")); tab->insertTab(index++, errorLogWidget, tr("error")); tab->setMaximumHeight(200); widget->setLayout(layout); } void ToolDialogImpl::on_btnImport_clicked() { QString ScriptDir = "./Script.js"; QString fileName(ScriptDir); QFile scriptFile(fileName); scriptFile.open(QIODevice::ReadOnly); QTextStream stream(&scriptFile); stream.setCodec(QTextCodec::codecForName("UTF-8")); QString contents = stream.readAll(); scriptFile.close(); scriptEdit->setText(contents); } void ToolDialogImpl::on_btnExport_clicked() { m_strCodes = scriptEdit->text(); QString ScriptDir = "./Script.js"; QFile writeFile(ScriptDir); if (!writeFile.open(QIODevice::WriteOnly)) { return; } QTextStream out(&writeFile); out.setCodec(QTextCodec::codecForName("UTF-8")); out << m_strCodes; writeFile.close(); } void ToolDialogImpl::on_btnCheck_clicked() { m_strCodes = scriptEdit->text(); QScriptSyntaxCheckResult syntaxCheckResult = m_pEngine->checkSyntax(m_strCodes); if (syntaxCheckResult.state() != QScriptSyntaxCheckResult::Valid) { QString err = QString::fromLatin1("%1 %2 %3") .arg(syntaxCheckResult.errorLineNumber()) .arg(syntaxCheckResult.errorColumnNumber()) .arg(syntaxCheckResult.errorMessage()); qWarning() << err; return; } QScriptValue result = m_pEngine->evaluate(m_strCodes); if (result.isError()) { QString err = QString::fromLatin1("%1: %2") .arg(result.property("lineNumber").toInt32()) .arg(result.toString()); qWarning() << err; return; } } void ToolDialogImpl::on_btnEdit_clicked() { ui.stackedWidget->setCurrentIndex(1); } void ToolDialogImpl::on_cbEnDebug_stateChanged(int arg1) { if (arg1 > 0) { m_pDebugger->attachTo(m_pEngine); ui.stackedWidget->setCurrentIndex(0); m_pDebugger->action(QScriptEngineDebugger::StepIntoAction)->trigger(); try { m_strCodes = scriptEdit->text(); QScriptValue result = m_pEngine->evaluate(m_strCodes); if (result.isError()) { QString err = QString::fromLatin1("script syntax evaluate error: %1 %2") .arg(result.property("lineNumber").toInt32()) .arg(result.toString()); qWarning() << "Error Msg" << err; } } catch (...) { qWarning() << "Execute() Error"; } } else { m_pDebugger->detach(); ui.stackedWidget->setCurrentIndex(1); } } /// /// /// void ToolDialogImpl::documentWasModified() { m_strCodes = scriptEdit->text(); } void ToolDialogImpl::on_btnAddInterface_clicked() { // 通知exe端添加对应的接口数据结构 QList dynInfs; DLL_INF inf; inf.strName = "Name"; inf.Direction = INF_DIRECTION::INF_DIR_IN; inf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE; inf.value.type = VALUE_TYPE::Type_Float; inf.value.Ptr = (void**)&this->m_fValue1; inf.nIndex = m_pDllTool->GetInterfaceSize(); inf.bDynamic = true;// 设置为动态接口 m_pDllTool->AddInterface(inf);// 动态添加 dynInfs.push_back(inf);// 添加到通知集合中 // 发送同步动态端口的通知 this->syncInterfacesToPou(dynInfs, true); } void ToolDialogImpl::on_btnDelInterface_clicked() { // 通知exe端添加对应的接口数据结构 QList dynInfs; // 要删除的接口名字 DLL_INF inf; bool bRet = m_pDllTool->DelInterface("Name");// 动态删除 if (bRet)// 如果删除成功,则添加到通知集合中 { dynInfs.push_back(inf);// 添加到通知集合中 } inf.reset(); // 发送同步动态端口的通知 if (dynInfs.size() > 0) { this->syncInterfacesToPou(dynInfs, false); } } /// /// 2022-3-8 向exe中的同步最新的接口变动(一个或多个) /// /// void ToolDialogImpl::syncInterfacesToPou(QList pInfs, bool bAdd) { SyncInterfaceEvent infEvent;// = new SyncInterfaceEvent(); // 携带需要同步的多个接口 infEvent.setSyncValues(pInfs); // 设置要本工具的实例名称 infEvent.m_strInstanceName = this->m_strInstanceName; // 增加端口 infEvent.m_bAdd = bAdd; // post数值同步消息 QCoreApplication::sendEvent(this->m_pPouTarget, &infEvent); // 获取事件执行状态 bool bRet = infEvent.m_bSuccess; if (!bRet) { qWarning() << m_strInstanceName << " add interface error, reason: " << infEvent.m_strReason; } } /// /// /// /// /// bool ToolDialogImpl::bindValuePtrByName(const QString strName, const int nIndex) { //m_pDllTool->SetValue(nIndex, mFunction.Interfaces_io[i].ho_Object); return true; }