ToolDialog.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. #include "ToolDialog.h"
  2. #include <QImage>
  3. #include <QFileInfo>
  4. #include <QFileDialog>
  5. #include <QElapsedTimer>
  6. #include <QGridLayout>
  7. #include <QToolBar>
  8. //////////////////////////////////////////////////////////////////////////
  9. #include "Qsci/qsciapis.h"
  10. #include "Qsci/qscilexercpp.h"
  11. #include "Qsci/qscilexercpp.h"
  12. #include "Qsci/qscilexerlua.h"
  13. #include "Qsci/qsciscintilla.h"
  14. #include "Qsci/qscilexerjavascript.h"
  15. //////////////////////////////////////////////////////////////////////////
  16. ToolDialogImpl::ToolDialogImpl(QWidget* parent, DllTool* pDllTool)
  17. : DllToolDialog(parent)
  18. , m_pDllTool(pDllTool)
  19. {
  20. ui.setupUi(this);
  21. this->setWindowFlags(Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint /*| Qt::WindowStaysOnTopHint*/);
  22. m_fValue1 = 11;
  23. m_fValue2 = 22;
  24. m_fValue3 = 33;
  25. m_fValue4 = 44;
  26. m_fValue5 = 55;
  27. m_ValueMap.insert("V1", &m_fValue1);
  28. m_ValueMap.insert("V2", &m_fValue2);
  29. m_ValueMap.insert("V3", &m_fValue3);
  30. m_ValueMap.insert("VO1", &m_fValue4);
  31. m_ValueMap.insert("VO2", &m_fValue5);
  32. // 设置比例
  33. QList<int> sizes;
  34. sizes << 1000 << 5000;
  35. ui.splitter->setSizes(sizes);
  36. connect(this, SIGNAL(sigUpdateUI()), this, SLOT(on_UpdateUI()));
  37. ///////////////////////////////>>////////////////
  38. initScriptEdit();
  39. initEngine();
  40. initDebugger();
  41. }
  42. ToolDialogImpl::~ToolDialogImpl()
  43. {
  44. if (scriptEdit != nullptr)
  45. {
  46. delete scriptEdit;
  47. scriptEdit = nullptr;
  48. }
  49. }
  50. VPEnum::RETURN_VALUE ToolDialogImpl::Execute()
  51. {
  52. //return VPEnum::RETURN_VALUE::Success;
  53. try
  54. {
  55. //m_strCodes = scriptEdit->text();
  56. QScriptValue result = m_pEngine->evaluate(m_strCodes);
  57. if (result.isError())
  58. {
  59. QString err = QString::fromLatin1("script syntax evaluate error: %1 %2")
  60. .arg(result.property("lineNumber").toInt32())
  61. .arg(result.toString());
  62. qWarning() << "Error Msg" << err;
  63. }
  64. }
  65. catch (...)
  66. {
  67. qWarning() << "Execute() Error";
  68. }
  69. emit sigUpdateUI();
  70. return VPEnum::RETURN_VALUE::Success;
  71. }
  72. /// <summary>
  73. ///
  74. /// </summary>
  75. /// <param name="bRun"></param>
  76. void ToolDialogImpl::Running(bool bRun)
  77. {
  78. }
  79. /// <summary>
  80. ///
  81. /// </summary>
  82. /// <param name="ar"></param>
  83. /// <param name="bIsOut"></param>
  84. /// <returns></returns>
  85. bool ToolDialogImpl::Serialized(QDataStream& ar, bool bIsOut)
  86. {
  87. int paranum;//参数数量
  88. if (bIsOut)//保存参数流程
  89. {
  90. paranum = 1;
  91. ar << paranum;//先保存参数数量
  92. ar << (int)1 << m_strCodes;
  93. }
  94. else//加载参数流程,参数加载顺序一定要跟保存顺序一致
  95. {
  96. int nFumctionNameSize = 0;
  97. int para;
  98. ar >> paranum;//读取参数数量
  99. for (int i = 0; i < paranum; i++)
  100. {
  101. ar >> para;
  102. switch (para)
  103. {
  104. case 1: ar >> m_strCodes; break;
  105. default:
  106. {
  107. qWarning() << "Serialized(In) Error";
  108. return false;
  109. }
  110. break;
  111. }
  112. }
  113. scriptEdit->setText(m_strCodes);
  114. }
  115. return true;
  116. }
  117. QScriptValue ToolDialogImpl::Sleep(QScriptContext* context, QScriptEngine* engine, void* pargs)
  118. {
  119. ToolDialogImpl* pDlg = (ToolDialogImpl*)pargs;
  120. Q_UNUSED(engine);
  121. QScriptValue id = context->argument(0);
  122. int nValue = id.toString().toInt();
  123. Utility::qSleep(nValue);
  124. return 1;
  125. }
  126. QScriptValue ToolDialogImpl::SetRealValue(QScriptContext* context, QScriptEngine* engine, void* pargs)
  127. {
  128. ToolDialogImpl* pDlg = (ToolDialogImpl*)pargs;
  129. Q_UNUSED(engine);
  130. QScriptValue skey = context->argument(0);
  131. QString strKey = skey.toString();
  132. QScriptValue sVar = context->argument(1);
  133. float fValue = sVar.toString().toFloat();
  134. if (pDlg->m_ValueMap[strKey] != nullptr)
  135. {
  136. *pDlg->m_ValueMap[strKey] = fValue;
  137. }
  138. else
  139. {
  140. qWarning() << "SetRealValue Error Key" << strKey << "is Null";
  141. }
  142. return 1;
  143. }
  144. QScriptValue ToolDialogImpl::GetRealValue(QScriptContext* context, QScriptEngine* engine, void* pargs)
  145. {
  146. ToolDialogImpl* pDlg = (ToolDialogImpl*)pargs;
  147. Q_UNUSED(engine);
  148. Q_UNUSED(pargs);
  149. QScriptValue sVar = context->argument(0);
  150. QString strKey = sVar.toString();
  151. float fValue = 0;
  152. if (pDlg->m_ValueMap.value(strKey) != nullptr)
  153. {
  154. fValue = *pDlg->m_ValueMap.value(strKey);
  155. }
  156. else
  157. {
  158. qWarning() << "GetRealValue Error Key" << strKey << "is Null";
  159. }
  160. return fValue;
  161. }
  162. void ToolDialogImpl::on_UpdateUI()
  163. {
  164. }
  165. /// <summary>
  166. /// 确定
  167. /// </summary>
  168. void ToolDialogImpl::on_btnOK_clicked()
  169. {
  170. this->hide();
  171. }
  172. /// <summary>
  173. /// 取消按钮
  174. /// </summary>
  175. void ToolDialogImpl::on_btnCancel_clicked()
  176. {
  177. // 将本工具的恢复到打开工具之前的状态
  178. RecoverData();
  179. }
  180. /// <summary>
  181. /// 测试按钮
  182. /// </summary>
  183. void ToolDialogImpl::on_btnExecute_clicked()
  184. {
  185. QElapsedTimer toolTimer;
  186. toolTimer.start();
  187. // 发送事件
  188. ToolEvent* pToolEvent = new ToolEvent(m_strPouName, m_strInstanceName, TOOL_EVENT_TYPE::TOOL_TRIGGER);
  189. QCoreApplication::sendEvent(m_pEventTarget, pToolEvent);
  190. // 统计返回值
  191. VPEnum::RETURN_VALUE ret = pToolEvent->ret;
  192. double nExecTime = toolTimer.elapsed();
  193. QString str;
  194. str = QString("耗时: %1 ms").arg(nExecTime, 0, 'G', 5);
  195. ui.label_time->setText(str);
  196. str = QString("状态: %1 ").arg(QMetaEnum::fromType<VPEnum::RETURN_VALUE>().key((short)ret));
  197. ui.label_state->setText(str);
  198. delete pToolEvent;
  199. }
  200. void ToolDialogImpl::initScriptEdit()
  201. {
  202. int nSize = ui.stackedWidget->count();
  203. ui.stackedWidget->setCurrentIndex(1);
  204. scriptEdit = new QsciScintilla(ui.widgetEditor);
  205. QsciLexerJavaScript* scriptLexer =
  206. new QsciLexerJavaScript(); //创建一个词法分析器
  207. scriptLexer->setDefaultPaper("#b3b3b3");
  208. scriptEdit->setLexer(scriptLexer); //设置词法分析器
  209. scriptEdit->setMarginType(0, QsciScintilla::MarginType::NumberMargin); //设置编号为0的页边显示行号。
  210. scriptEdit->setMarginLineNumbers(0, true); //启用行号
  211. scriptEdit->setMarginWidth(0, 26);
  212. QsciAPIs* apis = new QsciAPIs(scriptLexer); //代码提示
  213. apis->add(QString("local"));
  214. apis->prepare();
  215. //开启自动缩进
  216. scriptEdit->setAutoIndent(true);
  217. //设置缩进的显示方式
  218. //scriptEdit->setIndentationGuides(QsciScintilla::SC_IV_LOOKBOTH);
  219. //显示选中的行号
  220. scriptEdit->setCaretLineVisible(true);
  221. //显示选中行号的背景色
  222. scriptEdit->setCaretLineBackgroundColor(Qt::lightGray);
  223. //左侧行号显示的背景色
  224. scriptEdit->setMarginsBackgroundColor(Qt::gray);
  225. //设置括号匹配
  226. scriptEdit->setBraceMatching(QsciScintilla::BraceMatch::SloppyBraceMatch);
  227. scriptEdit->setFolding(QsciScintilla::FoldStyle::BoxedTreeFoldStyle);//折叠样式
  228. scriptEdit->setFoldMarginColors(Qt::gray, Qt::lightGray);//折叠栏颜色
  229. scriptEdit->setAutoCompletionThreshold(3);//设置每输入一个字符就会出现自动补全的提示
  230. scriptEdit->setFont(QFont("Courier New")); //设置字体
  231. scriptEdit->SendScintilla(QsciScintilla::SCI_SETCODEPAGE, QsciScintilla::SC_CP_UTF8); //设置编码为UTF-8
  232. connect(scriptEdit, SIGNAL(textChanged()), this, SLOT(documentWasModified()));
  233. QVBoxLayout* vLayout = new QVBoxLayout();
  234. vLayout->setContentsMargins(1, 1, 1, 1);
  235. vLayout->setObjectName(QStringLiteral("vLayout"));
  236. vLayout->addWidget(scriptEdit);
  237. ui.widgetEditor->setLayout(vLayout);
  238. }
  239. void ToolDialogImpl::initEngine()
  240. {
  241. m_pEngine = new QScriptEngine();
  242. // Sleep
  243. m_pEngine->globalObject().setProperty("Sleep", m_pEngine->newFunction(&ToolDialogImpl::Sleep, this));
  244. // SetRealValue
  245. m_pEngine->globalObject().setProperty("SetRealValue", m_pEngine->newFunction(&ToolDialogImpl::SetRealValue, this));
  246. // GetRealValue
  247. m_pEngine->globalObject().setProperty("GetRealValue", m_pEngine->newFunction(&ToolDialogImpl::GetRealValue, this));
  248. }
  249. void ToolDialogImpl::initDebugger()
  250. {
  251. QWidget* widget = (ui.widgetDebug);
  252. m_pDebugger = new QScriptEngineDebugger();
  253. m_pDebugger->setAutoShowStandardWindow(false);
  254. QAction* interruptAction = m_pDebugger->action(QScriptEngineDebugger::InterruptAction);
  255. QAction* continueAction = m_pDebugger->action(QScriptEngineDebugger::ContinueAction);
  256. QAction* stepIntoAction = m_pDebugger->action(QScriptEngineDebugger::StepIntoAction);
  257. QAction* stepOverAction = m_pDebugger->action(QScriptEngineDebugger::StepOverAction);
  258. QAction* stepOutAction = m_pDebugger->action(QScriptEngineDebugger::StepOutAction);
  259. QToolBar* toolBar = new QToolBar;
  260. //toolBar->addAction(interruptAction);
  261. //toolBar->addAction(continueAction);
  262. toolBar->addAction(stepIntoAction);
  263. toolBar->addAction(stepOverAction);
  264. toolBar->addAction(stepOutAction);
  265. QWidget* codeWidget = m_pDebugger->widget(QScriptEngineDebugger::CodeWidget);
  266. QWidget* consoleWidget = m_pDebugger->widget(QScriptEngineDebugger::ConsoleWidget);
  267. QWidget* debugOutputWidget = m_pDebugger->widget(QScriptEngineDebugger::DebugOutputWidget);
  268. QWidget* errorLogWidget = m_pDebugger->widget(QScriptEngineDebugger::ErrorLogWidget);
  269. QLayout* layout = new QVBoxLayout;
  270. QTabWidget* tab = new QTabWidget(widget);
  271. layout->addWidget(toolBar);
  272. layout->addWidget(codeWidget);
  273. layout->addWidget(tab);
  274. layout->setContentsMargins(0, 0, 0, 0);
  275. int index = 0;
  276. tab->insertTab(index, consoleWidget, tr("console"));
  277. // tab->insertTab(index++, localsWidget,tr("locals"));
  278. tab->insertTab(index++, debugOutputWidget, tr("debug"));
  279. tab->insertTab(index++, errorLogWidget, tr("error"));
  280. tab->setMaximumHeight(200);
  281. widget->setLayout(layout);
  282. }
  283. void ToolDialogImpl::on_btnImport_clicked()
  284. {
  285. QString ScriptDir = "./Script.js";
  286. QString fileName(ScriptDir);
  287. QFile scriptFile(fileName);
  288. scriptFile.open(QIODevice::ReadOnly);
  289. QTextStream stream(&scriptFile);
  290. stream.setCodec(QTextCodec::codecForName("UTF-8"));
  291. QString contents = stream.readAll();
  292. scriptFile.close();
  293. scriptEdit->setText(contents);
  294. }
  295. void ToolDialogImpl::on_btnExport_clicked()
  296. {
  297. m_strCodes = scriptEdit->text();
  298. QString ScriptDir = "./Script.js";
  299. QFile writeFile(ScriptDir);
  300. if (!writeFile.open(QIODevice::WriteOnly))
  301. {
  302. return;
  303. }
  304. QTextStream out(&writeFile);
  305. out.setCodec(QTextCodec::codecForName("UTF-8"));
  306. out << m_strCodes;
  307. writeFile.close();
  308. }
  309. void ToolDialogImpl::on_btnCheck_clicked()
  310. {
  311. m_strCodes = scriptEdit->text();
  312. QScriptSyntaxCheckResult syntaxCheckResult =
  313. m_pEngine->checkSyntax(m_strCodes);
  314. if (syntaxCheckResult.state() != QScriptSyntaxCheckResult::Valid)
  315. {
  316. QString err = QString::fromLatin1("%1 %2 %3")
  317. .arg(syntaxCheckResult.errorLineNumber())
  318. .arg(syntaxCheckResult.errorColumnNumber())
  319. .arg(syntaxCheckResult.errorMessage());
  320. qWarning() << err;
  321. return;
  322. }
  323. QScriptValue result = m_pEngine->evaluate(m_strCodes);
  324. if (result.isError())
  325. {
  326. QString err = QString::fromLatin1("%1: %2")
  327. .arg(result.property("lineNumber").toInt32())
  328. .arg(result.toString());
  329. qWarning() << err;
  330. return;
  331. }
  332. }
  333. void ToolDialogImpl::on_btnEdit_clicked()
  334. {
  335. ui.stackedWidget->setCurrentIndex(1);
  336. }
  337. void ToolDialogImpl::on_cbEnDebug_stateChanged(int arg1)
  338. {
  339. if (arg1 > 0)
  340. {
  341. m_pDebugger->attachTo(m_pEngine);
  342. ui.stackedWidget->setCurrentIndex(0);
  343. m_pDebugger->action(QScriptEngineDebugger::StepIntoAction)->trigger();
  344. try
  345. {
  346. m_strCodes = scriptEdit->text();
  347. QScriptValue result = m_pEngine->evaluate(m_strCodes);
  348. if (result.isError())
  349. {
  350. QString err = QString::fromLatin1("script syntax evaluate error: %1 %2")
  351. .arg(result.property("lineNumber").toInt32())
  352. .arg(result.toString());
  353. qWarning() << "Error Msg" << err;
  354. }
  355. }
  356. catch (...)
  357. {
  358. qWarning() << "Execute() Error";
  359. }
  360. }
  361. else
  362. {
  363. m_pDebugger->detach();
  364. ui.stackedWidget->setCurrentIndex(1);
  365. }
  366. }
  367. /// <summary>
  368. ///
  369. /// </summary>
  370. void ToolDialogImpl::documentWasModified()
  371. {
  372. m_strCodes = scriptEdit->text();
  373. }
  374. void ToolDialogImpl::on_btnAddInterface_clicked()
  375. {
  376. // 通知exe端添加对应的接口数据结构
  377. QList<DLL_INF> dynInfs;
  378. DLL_INF inf;
  379. inf.strName = "Name";
  380. inf.Direction = INF_DIRECTION::INF_DIR_IN;
  381. inf.value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  382. inf.value.type = VALUE_TYPE::Type_Float;
  383. inf.value.Ptr = (void**)&this->m_fValue1;
  384. inf.nIndex = m_pDllTool->GetInterfaceSize();
  385. inf.bDynamic = true;// 设置为动态接口
  386. m_pDllTool->AddInterface(inf);// 动态添加
  387. dynInfs.push_back(inf);// 添加到通知集合中
  388. // 发送同步动态端口的通知
  389. this->syncInterfacesToPou(dynInfs, true);
  390. }
  391. void ToolDialogImpl::on_btnDelInterface_clicked()
  392. {
  393. // 通知exe端添加对应的接口数据结构
  394. QList<DLL_INF> dynInfs;
  395. // 要删除的接口名字
  396. DLL_INF inf;
  397. bool bRet = m_pDllTool->DelInterface("Name");// 动态删除
  398. if (bRet)// 如果删除成功,则添加到通知集合中
  399. {
  400. dynInfs.push_back(inf);// 添加到通知集合中
  401. }
  402. inf.reset();
  403. // 发送同步动态端口的通知
  404. if (dynInfs.size() > 0)
  405. {
  406. this->syncInterfacesToPou(dynInfs, false);
  407. }
  408. }
  409. /// <summary>
  410. /// 2022-3-8 向exe中的同步最新的接口变动(一个或多个)
  411. /// </summary>
  412. /// <param name="pInfs"></param>
  413. void ToolDialogImpl::syncInterfacesToPou(QList<DLL_INF> pInfs, bool bAdd)
  414. {
  415. SyncInterfaceEvent infEvent;// = new SyncInterfaceEvent();
  416. // 携带需要同步的多个接口
  417. infEvent.setSyncValues(pInfs);
  418. // 设置要本工具的实例名称
  419. infEvent.m_strInstanceName = this->m_strInstanceName;
  420. // 增加端口
  421. infEvent.m_bAdd = bAdd;
  422. // post数值同步消息
  423. QCoreApplication::sendEvent(this->m_pPouTarget, &infEvent);
  424. // 获取事件执行状态
  425. bool bRet = infEvent.m_bSuccess;
  426. if (!bRet)
  427. {
  428. qWarning() << m_strInstanceName << " add interface error, reason: " << infEvent.m_strReason;
  429. }
  430. }
  431. /// <summary>
  432. ///
  433. /// </summary>
  434. /// <param name="nIndex"></param>
  435. /// <returns></returns>
  436. bool ToolDialogImpl::bindValuePtrByName(const QString strName, const int nIndex)
  437. {
  438. //m_pDllTool->SetValue(nIndex, mFunction.Interfaces_io[i].ho_Object);
  439. return true;
  440. }