#include "mainwindow.h" #include "ui_mainwindow.h" #include "worker.h" #include "utils.h" #include "progress_event.h" #include "update_dc_event.h" #include "plugins/interfaces.h" #include #include #include #include #if EMERGENCY_LEAVE_BL==1 static int step = 0; void MainWindow::emergencyLeaveBL() { // qCritical() << __func__ << step; switch(step) { case 0: if (m_hw->dc_openSerial(5, "115200", "ttymxc2", 1)) { qCritical() << __func__ << "open ok"; step++; QThread::msleep(2000); m_hw->dc_autoRequest(false); emit leaveBL(); } break; case 1: m_hw->bl_rebootDC(); QThread::msleep(1000); qCritical() << __func__ << "reboot ok" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs); step++; emit leaveBL(); break; case 2: case 3: case 4: case 5: case 6: m_hw->bl_startBL(); QThread::msleep(1000); qCritical() << __func__ << "start" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs); step++; emit leaveBL(); break; case 7: case 9: case 11: case 13: case 15: m_hw->bl_checkBL(); qCritical() << __func__ << "check" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs); QThread::msleep(1500); ++step; emit leaveBL(); break; case 8: case 10: case 12: case 14: case 16: qCritical() << __func__ << "is Up..." << QDateTime::currentDateTime().toString(Qt::ISODateWithMs); if (m_hw->bl_isUp()) { qCritical() << __func__ << "is Up...OK" << step << QDateTime::currentDateTime().toString(Qt::ISODateWithMs); QThread::msleep(5000); step = 16; } else { qCritical() << __func__ << "is Up...NO" << step << QDateTime::currentDateTime().toString(Qt::ISODateWithMs); } ++step; emit leaveBL(); break; case 17: case 18: case 19: qCritical() << __func__ << "stop" << QDateTime::currentDateTime().toString(Qt::ISODateWithMs); m_hw->bl_stopBL(); QThread::msleep(1000); //m_hw->dc_closeSerial(); ++step; emit leaveBL(); break; } } #endif MainWindow::MainWindow(hwinf *hw, Worker *worker, Update *update, QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , m_hw(hw) , m_worker(worker) , m_width(70) , m_progressRunning(false) , m_progressValue(0) , m_update(update) , m_updateStep(UpdateDcEvent::UpdateStep::NONE) { #if EMERGENCY_LEAVE_BL==1 QTimer *t = new QTimer(this); connect(t, SIGNAL(timeout()), this, SLOT(emergencyLeaveBL())); connect(this, SIGNAL(leaveBL()), this, SLOT(emergencyLeaveBL()), Qt::QueuedConnection); t->setSingleShot(true); t->start(1000); return; #endif this->setStatusBar(new QStatusBar(this)); QFont f; f.setStyleHint(QFont::Monospace); f.setWeight(QFont::Bold); f.setFamily("Misc Fixed"); f.setPixelSize(12); this->statusBar()->setFont(f); ui->setupUi(this); ui->updateProgress->setRange(0, 100); ui->updateProgress->reset(); QStringList lst; QString start = QDateTime::currentDateTime().toString(Qt::ISODate); lst << QString("Start: ") + start.leftJustified(m_width-10); lst << QString("").leftJustified(m_width-3, '='); lst << QString("Machine number : %1 ").arg(m_worker->machineNr()).leftJustified(m_width-3); lst << QString("Customer number : %1 ").arg(m_worker->customerNr()).leftJustified(m_width-3); lst << QString("Zone number : %1 (%2)").arg(m_worker->zoneNr()).arg(Utils::zoneName(m_worker->zoneNr())).leftJustified(m_width-3); lst << QString("APISM version : %1").arg(m_worker->apismVersion()).leftJustified(m_width-3); lst << QString("").leftJustified(m_width-3, '='); ui->updateStatus->setText(lst.join('\n')); ui->updateStatus->setEnabled(true); m_startTimer = new QTimer(this); connect(m_startTimer, SIGNAL(timeout()), m_worker, SLOT(update())); m_startTimer->setSingleShot(true); m_startTimer->start(1000); m_exitTimer = new QTimer(this); connect(m_exitTimer, SIGNAL(timeout()), ui->exit, SLOT(click())); m_exitTimer->setSingleShot(true); m_exitTimer->start(1800 * 1000); connect(ui->exit, SIGNAL(clicked()),this,SLOT(onQuit())); connect(m_worker, SIGNAL(disableExit()),this,SLOT(onDisableExit())); connect(m_worker, SIGNAL(enableExit()),this,SLOT(onEnableExit())); connect(m_worker, SIGNAL(stopStartTimer()),this,SLOT(onStopStartTimer())); connect(m_worker, SIGNAL(restartExitTimer()),this,SLOT(onRestartExitTimer())); connect(m_worker, SIGNAL(appendText(QString,QString)),this,SLOT(onAppendText(QString,QString))); connect(m_worker, SIGNAL(showErrorMessage(QString,QString)),this, SLOT(onShowErrorMessage(QString,QString))); connect(m_worker, SIGNAL(showStatusMessage(QString,QString)),this, SLOT(onShowStatusMessage(QString,QString))); connect(m_worker, SIGNAL(replaceLast(QString,QString)),this,SLOT(onReplaceLast(QString,QString))); connect(m_worker, SIGNAL(replaceLast(QStringList,QString)),this, SLOT(onReplaceLast(QStringList,QString))); } MainWindow::~MainWindow() { delete m_startTimer; delete m_exitTimer; delete ui; } void MainWindow::customEvent(QEvent *event) { if (event->type() == ProgressEvent::type()) { ProgressEvent *pevent = (ProgressEvent *)event; int const progress = pevent->progressPercent(); QObject const *sender = pevent->sender(); if (sender == this) { switch(progress) { case 0: { ui->updateProgress->reset(); } break; case START_PROGRESS_LOOP: { m_progressRunning = true; ui->updateProgress->reset(); m_progressValue = 10; QApplication::postEvent(this, new ProgressEvent(this, m_progressValue)); } break; case STOP_PROGRESS_LOOP: { m_progressRunning = false; m_progressValue -= 10; m_worker->setProgress(m_progressValue/10); } break; default: { if (m_progressRunning) { m_progressValue = progress; ui->updateProgress->setValue(progress/10); QApplication::postEvent(this, new ProgressEvent(this, progress+10)); QThread::msleep(500); } } } } else if (sender == m_worker) { switch(progress) { case 0: { ui->updateProgress->reset(); } break; case START_PROGRESS_LOOP: { QApplication::postEvent(this, new ProgressEvent(this, START_PROGRESS_LOOP)); } break; case STOP_PROGRESS_LOOP: { QApplication::postEvent(this, new ProgressEvent(this, STOP_PROGRESS_LOOP)); } break; default:{ ui->updateProgress->setValue(progress); }} } else { qCritical() << "!!! UNKNOWN SENDER !!!"; } } else if (event->type() == UpdateDcEvent::type()) { UpdateDcEvent *pevent = (UpdateDcEvent *)event; UpdateDcEvent::UpdateStep const updateStep = pevent->updateStep(); QObject const *sender = pevent->sender(); if (sender == m_worker) { QDateTime const &recv = QDateTime::currentDateTime(); QDateTime const &send = pevent->sendDateTime(); qint64 const delay = recv.toMSecsSinceEpoch() - send.toMSecsSinceEpoch(); switch(updateStep) { case UpdateDcEvent::UpdateStep::NONE: break; case UpdateDcEvent::UpdateStep::DC_REBOOT: { m_hw->bl_rebootDC(); QString msg = QDateTime::currentDateTime().toString(Qt::ISODateWithMs) + QString(": reset device controller (delay=%1ms").arg(delay); emit m_worker->showStatusMessage("dc update", msg); Utils::printInfoMsg(msg.toUpper()); m_updateStep = UpdateDcEvent::UpdateStep::DC_REBOOT; } break; case UpdateDcEvent::UpdateStep::BL_START: { QString const &msg = recv.toString(Qt::ISODateWithMs) + QString(": start bootloader (%1, delay=%2ms)").arg(pevent->count()).arg(delay); emit m_worker->showStatusMessage("dc update", msg); Utils::printInfoMsg(msg.toUpper()); m_hw->bl_startBL(); if (pevent->count() == BL_START_COUNT) { m_updateStep = UpdateDcEvent::UpdateStep::BL_START; } } break; case UpdateDcEvent::UpdateStep::BL_CHECK: { if (m_updateStep != UpdateDcEvent::UpdateStep::BL_IS_UP) { QString const &msg = recv.toString(Qt::ISODateWithMs) + QString(": request bootloader version (%1, delay=%2ms)").arg(pevent->count()).arg(delay); emit m_worker->showStatusMessage("dc update", msg); Utils::printInfoMsg(msg.toUpper()); m_hw->bl_checkBL(); //m_updateStep = UpdateDcEvent::UpdateStep::BL_CHECK; } } break; case UpdateDcEvent::UpdateStep::BL_IS_UP: { QString msg = recv.toString(Qt::ISODateWithMs) + QString(": check running bootloader (%1, delay=%2ms)").arg(pevent->count()).arg(delay); emit m_worker->showStatusMessage("dc update", msg); Utils::printInfoMsg(msg.toUpper()); if (m_updateStep != UpdateDcEvent::UpdateStep::BL_IS_UP) { if (m_hw->bl_isUp()) { msg = recv.toString(Qt::ISODateWithMs) + QString(": bootloader running (%1, delay=%2ms)").arg(pevent->count()).arg(delay); emit m_worker->showStatusMessage("dc update", msg); Utils::printInfoMsg(msg.toUpper()); m_updateStep = UpdateDcEvent::UpdateStep::BL_IS_UP; } else { msg = recv.toString(Qt::ISODateWithMs) + QString(": bootloader stop requested (%1, delay=%2ms)").arg(pevent->count()).arg(delay); emit m_worker->showStatusMessage("dc update", msg); Utils::printInfoMsg(msg.toUpper()); if (m_updateStep == UpdateDcEvent::UpdateStep::BL_STOP) { msg = QDateTime::currentDateTime().toString(Qt::ISODateWithMs) + QString(": bootloader down (%1, delay=%2ms)").arg(pevent->count()).arg(delay); emit m_worker->showStatusMessage("dc update", msg); Utils::printInfoMsg(msg.toUpper()); m_updateStep = UpdateDcEvent::UpdateStep::BL_IS_DOWN; } } } } break; case UpdateDcEvent::UpdateStep::BL_STOP: { QString const &msg = QDateTime::currentDateTime().toString(Qt::ISODateWithMs) + QString(": stop bootloader (%1, delay=%2ms)").arg(pevent->count()).arg(delay); emit m_worker->showStatusMessage("dc update", msg); Utils::printInfoMsg(msg.toUpper()); //if (m_bootLoaderIsUp) { m_hw->bl_stopBL(); m_updateStep = UpdateDcEvent::UpdateStep::BL_STOP; //} } break; default: ; } } } QThread::yieldCurrentThread(); } void MainWindow::onStopStartTimer() { m_startTimer->stop(); } void MainWindow::onDisableExit() { ui->exit->setEnabled(false); } void MainWindow::onEnableExit() { ui->exit->setEnabled(true); } void MainWindow::onRestartExitTimer() { m_exitTimer->stop(); m_exitTimer->start(60 * 1000); } void MainWindow::onQuit() { m_exitTimer->stop(); qCritical() << QString("ON QUIT: EXIT CODE %1").arg(m_worker->returnCode()); qApp->exit(m_worker->returnCode()); } void MainWindow::scrollDownTextEdit() { ui->updateStatus->setEnabled(true); QTextCursor tmpCursor = ui->updateStatus->textCursor(); tmpCursor.movePosition(QTextCursor::End); ui->updateStatus->setTextCursor(tmpCursor); ui->updateStatus->ensureCursorVisible(); } void MainWindow::onAppendText(QString text, QString suffix) { QString editText = ui->updateStatus->toPlainText(); if (!suffix.isNull() && suffix.size() > 0) { //qInfo() << "TEXT" << text << "SUFFIX" << suffix; if (suffix == Worker::UPDATE_STEP_SUCCESS || suffix == Worker::UPDATE_STEP_FAIL) { editText += QString("\n").leftJustified(m_width-3, '='); editText += " "; } editText += (QString("\n") + text).leftJustified(m_width - (2 + suffix.size()) ) + suffix; } else { editText += text.leftJustified(m_width-9); } Utils::printLineEditInfo(editText.split('\n')); ui->updateStatus->setPlainText(editText.trimmed()); scrollDownTextEdit(); } void MainWindow::onReplaceLast(QStringList newTextLines, QString suffix) { int const s = newTextLines.size(); if (s > 0) { QString editText = ui->updateStatus->toPlainText(); QStringList lines = editText.split('\n'); QString newText; if (lines.size() >= s) { for (int i = 0; i < s; ++i) { lines.removeLast(); } if (lines.size() > 0) { newText = lines.join('\n'); newText += '\n'; } QStringList newLines; for (int i = 0; i < s; ++i) { if (i == 0 && !suffix.isNull() && suffix.size() > 0 && suffix != "\n") { newLines += Utils::rstrip(newTextLines.at(i).leftJustified(m_width-10) + suffix); } else { newLines += Utils::rstrip(newTextLines.at(i).leftJustified(m_width-10)); } } lines += newLines; newText += newLines.join(' '); } ui->updateStatus->setText(newText); Utils::printLineEditInfo(lines); scrollDownTextEdit(); } } void MainWindow::onReplaceLast(QString text, QString suffix) { //qInfo() << "REPL TEXT" << text << "SUFFIX" << suffix; QString editText = ui->updateStatus->toPlainText(); QStringList lines = editText.split('\n'); if (lines.size() > 0) { lines.removeLast(); if (!suffix.isNull() && suffix.size() > 0 && suffix != "\n") { lines += text.leftJustified(m_width-10) + suffix; } else { lines += text.leftJustified(m_width-10); } } Utils::printLineEditInfo(lines); ui->updateStatus->setText(lines.join('\n').trimmed()); scrollDownTextEdit(); } void MainWindow::onShowErrorMessage(QString title, QString text) { this->statusBar()->clearMessage(); this->statusBar()->showMessage( // timeout: 10000 QString(title + " " + text).leftJustified(80, ' '), 10000); }