fillBlank.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. #include "fillBlank.h"
  2. #include "ui_fillBlank.h"
  3. #include <QFile>
  4. #include "fbFillBlankBody.h"
  5. #include "audioPlay.h"
  6. #include "fbBlank.h"
  7. #include "CCommonTools.h"
  8. #include "CSqlite3DBProc.h"
  9. //#include "MsgDlg.h"
  10. #include "CAppInfo.h"
  11. #include "logproc.h"
  12. fillBlank::fillBlank(CSubQuestionStruct &sqs, QWidget *parent) :
  13. CQuestionBaseWidget(parent),
  14. ui(new Ui::fillBlank), m_sqs(sqs)
  15. {
  16. ui->setupUi(this);
  17. setAttribute(Qt::WA_DeleteOnClose);
  18. b_isPressed = false;
  19. m_bAnswerChange = false;
  20. m_sAnswer = "";
  21. m_nTimeStap = 0;
  22. setStyleSheet(g_appInfoPtr->m_sQssStr);
  23. m_pTimer = new QTimer;
  24. m_pTimer->setInterval(5*1000);
  25. connect(m_pTimer, &QTimer::timeout, this, &fillBlank::onTimeout);
  26. m_pTimer->start();
  27. this->installEventFilter(this);
  28. }
  29. fillBlank::~fillBlank()
  30. {
  31. if (m_bAnswerChange)
  32. {
  33. updateAnswer();
  34. m_bAnswerChange = false;
  35. }
  36. m_pTimer->stop();
  37. RELEASE_PTR(m_pTimer);
  38. delete ui;
  39. }
  40. int fillBlank::setUI(const int nWidth)
  41. {
  42. setGeometry(0, 0, nWidth, g_appInfoPtr->m_fRate*300);
  43. ui->btn_mark->setGeometry(0, g_appInfoPtr->m_fRate*24, g_appInfoPtr->m_fRate*20, g_appInfoPtr->m_fRate*20);
  44. ui->list_choiceQuestion->setGeometry(ui->btn_mark->x() + ui->btn_mark->width() + g_appInfoPtr->m_fRate*20,
  45. g_appInfoPtr->m_fRate*20, width() - g_appInfoPtr->m_fRate*80, g_appInfoPtr->m_fRate*280);
  46. m_nListHeight = 0;
  47. QString sBodyStr = m_sqs.sBody;
  48. QString sAnswer = m_sqs.sStudentAnswer;
  49. Json::Reader reader;
  50. Json::Value jBody = Json::Value::null;
  51. if(!reader.parse(m_sqs.sBody.toStdString(), jBody))
  52. {
  53. // ShowMsg(QString::fromLocal8Bit("解析题干出错!"), g_appInfoPtr->m_answerWidget);
  54. myDebug()<<QString::fromLocal8Bit("解析题干出错!");
  55. }
  56. initBody(jBody, m_sqs.nShowNumber);
  57. Json::Value jAnswer = Json::Value::null;
  58. if(!sAnswer.isEmpty())
  59. {
  60. Json::Reader reader;
  61. if(!reader.parse(sAnswer.toStdString(), jAnswer))
  62. {
  63. // ShowMsg(QString::fromLocal8Bit("解析答案出错!"), g_appInfoPtr->m_answerWidget);
  64. myDebug()<<QString::fromLocal8Bit("解析答案出错!");
  65. }
  66. }
  67. QStringList sAnswerList;
  68. if(m_sqs.sSubjectiveTempAns.isEmpty())
  69. {
  70. QString sAnswerStrList;
  71. int nSize = jAnswer["sections"].size();
  72. for (int i = 0; i < nSize; i++)
  73. {
  74. Json::Value blocks = jAnswer["sections"][i];
  75. for (int j = 0; j < (int)blocks["blocks"].size(); j++)
  76. {
  77. if (blocks["blocks"][j]["type"].asString() == "text")
  78. {
  79. sAnswerStrList += blocks["blocks"][j]["value"].asString().c_str();
  80. }
  81. }
  82. }
  83. sAnswerList = sAnswerStrList.split("##");
  84. }
  85. else
  86. {
  87. sAnswerList = m_sqs.sSubjectiveTempAns.split("##");
  88. }
  89. int nCount = sBodyStr.count("______");
  90. for(int i = 0; i < nCount; i++)
  91. {
  92. fbBlank *wBlank = new fbBlank(i+1);
  93. if(sAnswerList.count() > i)
  94. {
  95. wBlank->setAnswer(sAnswerList[i]);
  96. }
  97. connect(wBlank, &fbBlank::answerChanged, this, &fillBlank::onAnswerChanged);
  98. QListWidgetItem *listItem = new QListWidgetItem;
  99. int nBlankHeight = wBlank->setUI(ui->list_choiceQuestion->width());
  100. m_nListHeight += nBlankHeight;
  101. listItem->setSizeHint(QSize(ui->list_choiceQuestion->width(), nBlankHeight));
  102. ui->list_choiceQuestion->addItem(listItem);
  103. ui->list_choiceQuestion->setItemWidget(listItem, wBlank);
  104. }
  105. ui->list_choiceQuestion->setGeometry(ui->btn_mark->x() + ui->btn_mark->width() + g_appInfoPtr->m_fRate*20,
  106. g_appInfoPtr->m_fRate*20, width() - g_appInfoPtr->m_fRate*80, m_nListHeight + g_appInfoPtr->m_fRate*10);
  107. setGeometry(0, 0, nWidth, ui->list_choiceQuestion->y() + m_nListHeight + g_appInfoPtr->m_fRate*30);
  108. setMarkStyle();
  109. return height();
  110. }
  111. void fillBlank::setMarkStyle()
  112. {
  113. QString sMaredStyle = QString(R"(QPushButton#btn_mark
  114. {
  115. outline:none;
  116. border-image:url(:/images/btn-mark-hover.png);
  117. })");
  118. QString sUnmaredStyle = QString(R"(QPushButton#btn_mark
  119. {
  120. outline:none;
  121. border-image:url(:/images/btn-mark.png);
  122. })");
  123. if(m_sqs.bMarked)
  124. {
  125. ui->btn_mark->setStyleSheet(sMaredStyle);
  126. }
  127. else
  128. {
  129. ui->btn_mark->setStyleSheet(sUnmaredStyle);
  130. }
  131. }
  132. void fillBlank::initBody(Json::Value jBody, int nOrderIndex)
  133. {
  134. int nIndex = 1;
  135. bool isSetItemNo = false;
  136. int nSectionSize = jBody["sections"].size();
  137. Json::Value jSections = Json::Value::null;
  138. for(int i = 0; i < nSectionSize; i++)
  139. {
  140. Json::Value jblocks = Json::Value::null;
  141. int nBlockSize = jBody["sections"][i]["blocks"].size();
  142. for(int j = 0; j < nBlockSize; j++)
  143. {
  144. if(jBody["sections"][i]["blocks"][j]["type"].asString() == "audio")
  145. {
  146. if(jblocks != Json::Value::null ||
  147. jSections != Json::Value::null)
  148. {
  149. if(jblocks != Json::Value::null)
  150. {
  151. Json::Value jBlockItem = Json::Value::null;
  152. jBlockItem["blocks"] = jblocks;
  153. jblocks = Json::Value::null;
  154. jSections.append(jBlockItem);
  155. }
  156. Json::Value jQuestionBody = Json::Value::null;
  157. jQuestionBody["sections"] = jSections;
  158. jSections = Json::Value::null;
  159. jblocks = Json::Value::null;
  160. fbFillBlankBody *wFB = new fbFillBlankBody(jQuestionBody);
  161. if(!isSetItemNo)
  162. {
  163. wFB->setQuesionNo(QString::fromLocal8Bit("%1.").arg(QString::number(nOrderIndex)));
  164. isSetItemNo = true;
  165. }
  166. QListWidgetItem *listItem = new QListWidgetItem;
  167. int nQBHeight = wFB->setUI(ui->list_choiceQuestion->width());
  168. m_nListHeight += nQBHeight;
  169. listItem->setSizeHint(QSize(ui->list_choiceQuestion->width(), nQBHeight));
  170. ui->list_choiceQuestion->addItem(listItem);
  171. ui->list_choiceQuestion->setItemWidget(listItem, wFB);
  172. }
  173. nIndex++;
  174. QString sAudioName = jBody["sections"][i]["blocks"][j]["ext2"].asString().c_str();
  175. QString sAudioUrl = jBody["sections"][i]["blocks"][j]["value"].asString().c_str();
  176. audioPlay *wAP = new audioPlay(sAudioName, sAudioUrl, m_sqs.nLimitedPlayTimes);
  177. connect(wAP, &audioPlay::playedCountChange, this, [&](){audioPlayCountChange();});
  178. QListWidgetItem *listItem = new QListWidgetItem;
  179. int nAPHeight = wAP->setUI(ui->list_choiceQuestion->width());
  180. m_nListHeight += nAPHeight;
  181. listItem->setSizeHint(QSize(ui->list_choiceQuestion->width(), nAPHeight));
  182. ui->list_choiceQuestion->addItem(listItem);
  183. ui->list_choiceQuestion->setItemWidget(listItem, wAP);
  184. }
  185. else
  186. {
  187. jblocks.append(jBody["sections"][i]["blocks"][j]);
  188. }
  189. }
  190. if(jblocks != Json::Value::null)
  191. {
  192. Json::Value jBlockItem = Json::Value::null;
  193. jBlockItem["blocks"] = jblocks;
  194. jblocks = Json::Value::null;
  195. jSections.append(jBlockItem);
  196. }
  197. }
  198. if(jSections != Json::Value::null)
  199. {
  200. Json::Value jQuestionBody = Json::Value::null;
  201. jQuestionBody["sections"] = jSections;
  202. jSections = Json::Value::null;
  203. fbFillBlankBody *wFB = new fbFillBlankBody(jQuestionBody);
  204. if(!isSetItemNo)
  205. {
  206. wFB->setQuesionNo(QString::fromLocal8Bit("%1.").arg(QString::number(nOrderIndex)));
  207. isSetItemNo = true;
  208. }
  209. QListWidgetItem *listItem = new QListWidgetItem;
  210. int nQBHeight = wFB->setUI(ui->list_choiceQuestion->width());
  211. m_nListHeight += nQBHeight;
  212. listItem->setSizeHint(QSize(ui->list_choiceQuestion->width(), nQBHeight));
  213. ui->list_choiceQuestion->addItem(listItem);
  214. ui->list_choiceQuestion->setItemWidget(listItem, wFB);
  215. }
  216. }
  217. void fillBlank::on_btn_mark_clicked()
  218. {
  219. if(!b_isPressed)
  220. {
  221. b_isPressed = true;
  222. ui->btn_mark->setStyleSheet("QPushButton{border-image:url(:/images/icon-marked.png);}");
  223. }
  224. else
  225. {
  226. b_isPressed = false;
  227. ui->btn_mark->setStyleSheet("QPushButton{border-image:url(:/images/icon-unmark.png);}");
  228. }
  229. m_sqs.bMarked = b_isPressed;
  230. setMarkStyle();
  231. emit markedItem(b_isPressed, m_sqs.nOrder);
  232. }
  233. void fillBlank::onTimeout()
  234. {
  235. if(m_bAnswerChange)
  236. {
  237. updateAnswer();
  238. m_bAnswerChange = false;
  239. }
  240. }
  241. void fillBlank::onAnswerChanged()
  242. {
  243. myDebug()<<"onAnswerChanged";
  244. bool answered = false;
  245. QString sAnsStr = generateAnswer(answered);
  246. m_nTimeStap = g_appInfoPtr->serverMTime();
  247. m_sAnswer = sAnsStr;
  248. m_bAnswerChange = true;
  249. m_sqs.bAnswered = answered;
  250. emit questionAnswered(answered, m_sqs.nOrder);
  251. }
  252. QString fillBlank::generateAnswer(bool &answered)
  253. {
  254. Json::Value jAnswer = Json::Value::null;
  255. answered = false;
  256. QString sAnsStr = "";
  257. int nNumber = 1;
  258. for(int i = 0; i < ui->list_choiceQuestion->count(); i++)
  259. {
  260. CBaseWidget *baseWidget = dynamic_cast<CBaseWidget*>(ui->list_choiceQuestion->itemWidget(ui->list_choiceQuestion->item(i)));
  261. if(baseWidget->widgetType() == wt_blank)
  262. {
  263. fbBlank *wBlank = dynamic_cast<fbBlank*>(baseWidget);
  264. QString sAnswerStr = wBlank->getAnswer();
  265. if(!sAnswerStr.isEmpty())
  266. {
  267. answered = true;
  268. }
  269. if(nNumber == 1)
  270. {
  271. sAnsStr = sAnswerStr;
  272. }
  273. else
  274. {
  275. sAnsStr = sAnsStr + "##" + sAnswerStr;
  276. }
  277. nNumber++;
  278. }
  279. }
  280. return sAnsStr;
  281. }
  282. void fillBlank::updateAnswer()
  283. {
  284. Json::Value jAudioPlayedInfo = Json::Value::null;
  285. for(int i = 0; i < ui->list_choiceQuestion->count(); i++)
  286. {
  287. CBaseWidget *baseWidget = dynamic_cast<CBaseWidget*>(ui->list_choiceQuestion->itemWidget(ui->list_choiceQuestion->item(i)));
  288. if(baseWidget->widgetType() == wt_aduioPlay)
  289. {
  290. audioPlay *wAp = dynamic_cast<audioPlay*>(baseWidget);
  291. QString sAudioName = "";
  292. int nCount = 0;
  293. wAp->getPalyedCount(sAudioName, nCount);
  294. Json::Value jPlayedInfo = Json::Value::null;
  295. jPlayedInfo["name"] = sAudioName.toStdString();
  296. jPlayedInfo["times"] = nCount;
  297. jAudioPlayedInfo.append(jPlayedInfo);
  298. }
  299. }
  300. QString sAudioPalyedInfo = "";
  301. if(jAudioPlayedInfo != Json::Value::null)
  302. {
  303. sAudioPalyedInfo = jAudioPlayedInfo.toStyledString().c_str();
  304. }
  305. Json::Value jAnswer = Json::Value::null;
  306. Json::Value jAnswerItem = Json::Value::null;
  307. if (!m_sqs.sAnswerType.isEmpty())
  308. {
  309. jAnswerItem["answerType"] = m_sqs.sAnswerType.toStdString();
  310. }
  311. jAnswerItem["audioPlayTimes"] = sAudioPalyedInfo.toStdString();
  312. jAnswerItem["isSign"] = m_sqs.bMarked;
  313. jAnswerItem["order"] = m_sqs.nOrder;
  314. jAnswerItem["studentAnswer"] = m_sAnswer.toStdString();
  315. jAnswer.append(jAnswerItem);
  316. QString sUploadAnswer = jAnswer.toStyledString().c_str();
  317. qDebug()<<sUploadAnswer;
  318. m_sqs.nVersion++;
  319. m_sqs.bUpload = false;
  320. m_sqs.sSubjectiveTempAns = m_sAnswer;
  321. m_sqs.sUploadAnswer = sUploadAnswer;
  322. emit uploadAnswer(m_sqs.nOrder, m_nTimeStap, sUploadAnswer);
  323. }
  324. bool fillBlank::eventFilter(QObject *obj, QEvent *ev)
  325. {
  326. if(obj == this)
  327. {
  328. //判断事件
  329. if(ev->type() == QEvent::Hide)
  330. {
  331. if(m_bAnswerChange)
  332. {
  333. myDebug()<<"fillBlank::QEvent::Hide";
  334. updateAnswer();
  335. m_bAnswerChange = false;
  336. }
  337. }
  338. }
  339. return QWidget::eventFilter(obj, ev);
  340. }
  341. void fillBlank::handinPaper()
  342. {
  343. myDebug()<<"fillBlank::handinPaper";
  344. m_pTimer->stop();
  345. if(m_bAnswerChange)
  346. {
  347. updateAnswer();
  348. m_bAnswerChange = false;
  349. }
  350. }
  351. void fillBlank::audioPlayCountChange()
  352. {
  353. m_bAnswerChange = true;
  354. }
  355. int fillBlank::widgetType()
  356. {
  357. return wt_question;
  358. }