diff --git a/DownloadDCFirmware/mainwindow.cpp b/DownloadDCFirmware/mainwindow.cpp new file mode 100644 index 0000000..a636de8 --- /dev/null +++ b/DownloadDCFirmware/mainwindow.cpp @@ -0,0 +1,350 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include +#include +#include +#include +#include + + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) + , m_serial(new QSerialPort(this)) + , m_width(70) { + + 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(); + +#if 0 + 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("Update tool version: %1 - %2 %3").arg(APP_VERSION).arg(APP_BUILD_DATE).arg(APP_BUILD_TIME).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); + // ui->updateStatus->installEventFilter(this); + + m_startTimer = new QTimer(this); + connect(m_startTimer, SIGNAL(timeout()), m_worker, SLOT(start())); + 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(showErrorMessage(QStringList)),this, SLOT(onShowErrorMessage(QStringList))); + 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))); +#endif +} + +MainWindow::~MainWindow() { + //delete m_startTimer; + //delete m_exitTimer; + delete ui; +} + +bool MainWindow::openSerialPort() { + // const SettingsDialog::Settings p = m_settings->settings(); + //m_serial->setPortName(p.name); + //m_serial->setBaudRate(p.baudRate); + //m_serial->setDataBits(p.dataBits); + //m_serial->setParity(p.parity); + //m_serial->setStopBits(p.stopBits); + ///m_serial->setFlowControl(p.flowControl); + m_serial->setPortName(""); + m_serial->setBaudRate(QSerialPort::Baud115200); + m_serial->setDataBits(QSerialPort::DataBits::Data8); + m_serial->setParity(QSerialPort::Parity::NoParity); + m_serial->setStopBits(QSerialPort::StopBits::OneStop); + m_serial->setFlowControl(QSerialPort::FlowControl::HardwareControl); + if (m_serial->open(QIODevice::ReadWrite)) { + //m_console->setEnabled(true); + //m_console->setLocalEchoEnabled(p.localEchoEnabled); + //m_ui->actionConnect->setEnabled(false); + //m_ui->actionDisconnect->setEnabled(true); + //m_ui->actionConfigure->setEnabled(false); + //showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6") + // .arg(p.name, p.stringBaudRate, p.stringDataBits, + // p.stringParity, p.stringStopBits, p.stringFlowControl)); + return true; + } else { + //QMessageBox::critical(this, tr("Error"), m_serial->errorString()); + + //showStatusMessage(tr("Open error")); + } + return false; +} + +bool MainWindow::closeSerialPort() { + if (m_serial->isOpen()) { + m_serial->close(); + return true; + } + return false; + //m_console->setEnabled(false); + //m_ui->actionConnect->setEnabled(true); + //m_ui->actionDisconnect->setEnabled(false); + //m_ui->actionConfigure->setEnabled(true); + //showStatusMessage(tr("Disconnected")); +} + +#if 0 +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, 1)); + } 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); + // ueberpruefen: hauptfenster schickt sich selber ein event + // QApplication::postEvent(this, new ProgressEvent(this, progress)); + // 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 !!!"; + } + } + + 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(5 * 1000); + + scrollDownTextEdit(); + ui->updateStatus->setEnabled(false); +} + +void MainWindow::onQuit() { + m_exitTimer->stop(); + int errorCode = 0; + + qCritical() + << QString("ON QUIT: CURRENT STEP %1") + .arg(m_worker->getSmap()[m_worker->currentStep()]); + + // TODO: replace SEND_LAST_VERSION with UPDATE_SUCCEEDED + if (m_worker->currentStep() != Worker::UPDATE_STEP::SEND_LAST_VERSION) { + errorCode = -1; + } + qCritical() << QString("ON QUIT: EXIT CODE %1").arg(errorCode); + qApp->exit(errorCode); +} + +void MainWindow::scrollDownTextEdit() { + // Utils::printInfoMsg(QString("SCROLL-DOWN-TEXT_EDIT CALLED AT ") + // + QDateTime::currentDateTime().toString(Qt::ISODateWithMs)); + + 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) { + // Utils::printInfoMsg(QString("ON APPEND CALLED AT ") + // + QDateTime::currentDateTime().toString(Qt::ISODateWithMs)); + + QString editText = ui->updateStatus->toPlainText(); + scrollDownTextEdit(); + + if (!suffix.isNull() && suffix.size() > 0) { + //qInfo() << "TEXT" << text << "SUFFIX" << suffix; + if (suffix == Worker::UPDATE_STEP_SUCCESS || suffix == Worker::UPDATE_STEP_FAIL) { + ui->updateStatus->insertPlainText(QString("\n").leftJustified(m_width-3, '=') + " "); + // editText += QString("\n").leftJustified(m_width-3, '='); + // editText += " "; + } + QString const &add = (QString("\n") + text).leftJustified(m_width - (2 + suffix.size())) + suffix; + ui->updateStatus->insertPlainText(add); + // editText += add; + } else { + QString const &add = text.leftJustified(m_width-9); + ui->updateStatus->insertPlainText(add); + //editText += add; + } + + // debug + // QString editText = ui->updateStatus->toPlainText(); + // Utils::printLineEditInfo(editText.split('\n', QString::SplitBehavior::SkipEmptyParts)); + // ui->updateStatus->setText(editText.trimmed()); + + scrollDownTextEdit(); +} + +void MainWindow::onReplaceLast(QStringList newTextLines, QString suffix) { + // Utils::printInfoMsg(QString("ON REPLACE LAST (LIST) CALLED AT ") + // + QDateTime::currentDateTime().toString(Qt::ISODateWithMs)); + int const s = newTextLines.size(); + if (s > 0) { + QString editText = ui->updateStatus->toPlainText(); + QStringList lines = editText.split('\n', QString::SplitBehavior::SkipEmptyParts); + 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) { + // Utils::printInfoMsg(QString("ON REPLACE LAST (TEXT) CALLED AT ") + // + QDateTime::currentDateTime().toString(Qt::ISODateWithMs)); + QString editText = ui->updateStatus->toPlainText(); + QStringList lines = editText.split('\n', QString::SplitBehavior::SkipEmptyParts); + if (lines.size() > 0) { + // removing the last line is really meant for refreshing the last line + // with a string very similar than the original one, typically only + // followed by a suffix. + if (lines.last().contains(text)) { + lines.removeLast(); + } + if (!suffix.isNull() && suffix.size() > 0 && suffix != "\n") { + QString const add = text.leftJustified(m_width-10) + suffix; + if (!add.isEmpty()) { + lines += text.leftJustified(m_width-10) + suffix; + } + } else { + QString const add = text.leftJustified(m_width-10); + if (!add.isEmpty()) { + lines += text.leftJustified(m_width-10); + } + } + } + + Utils::printLineEditInfo(lines); + ui->updateStatus->setText(lines.join('\n').trimmed()); + scrollDownTextEdit(); +} + +void MainWindow::onShowMessage(QString title, QString text) { + this->statusBar()->clearMessage(); + this->statusBar()->showMessage( // timeout: 10000 + QString(title + " " + text).leftJustified(80, ' '), 10000); +} + +void MainWindow::onShowErrorMessage(QString title, QString text) { + onShowMessage(title, text); +} + +void MainWindow::onShowStatusMessage(QString title, QString text) { + onShowMessage(title, text); +} + +void MainWindow::onShowErrorMessage(QStringList lst) { + if (lst.size() >= 2) { + onShowMessage(lst.at(0), lst.at(1)); + } + if (lst.size() == 1) { + onShowMessage(lst.at(0), ""); + } +} + +void MainWindow::onShowStatusMessage(QStringList lst) { + if (lst.size() >= 2) { + onShowMessage(lst.at(0), lst.at(1)); + } + if (lst.size() == 1) { + onShowMessage(lst.at(0), ""); + } +} +#endif diff --git a/DownloadDCFirmware/mainwindow.h b/DownloadDCFirmware/mainwindow.h new file mode 100644 index 0000000..72a2ea1 --- /dev/null +++ b/DownloadDCFirmware/mainwindow.h @@ -0,0 +1,58 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class MainWindow; } +QT_END_NAMESPACE + + +class MainWindow : public QMainWindow { + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +public slots: + //void onAppendText(QString, QString suffix = ""); + //void onReplaceLast(QStringList, QString suffix = ""); + //void onReplaceLast(QString, QString suffix = ""); + //void onShowErrorMessage(QString, QString); + //void onShowStatusMessage(QString, QString); + //void onShowErrorMessage(QStringList); + //void onShowStatusMessage(QStringList); + //void onStopStartTimer(); + //void onRestartExitTimer(); + //void onEnableExit(); + //void onDisableExit(); + +signals: + +private slots: +// void onQuit(); + +private: +// void scrollDownTextEdit(); +// void onShowMessage(QString, QString); + + bool openSerialPort(); + bool closeSerialPort(); + + Ui::MainWindow *ui; + QSerialPort *m_serial; +// Worker *m_worker; + int const m_width; +// QTimer *m_startTimer; +// QTimer *m_exitTimer; +// bool m_progressRunning; + //int m_progressValue; +// UpdateDcEvent::UpdateStep m_updateStep; +}; +#endif // MAINWINDOW_H diff --git a/DownloadDCFirmware/mainwindow.ui b/DownloadDCFirmware/mainwindow.ui new file mode 100644 index 0000000..4740c63 --- /dev/null +++ b/DownloadDCFirmware/mainwindow.ui @@ -0,0 +1,62 @@ + + + MainWindow + + + + 0 + 0 + 800 + 480 + + + + + Source Code Pro + + + + MainWindow + + + + + + 10 + 10 + 781 + 441 + + + + + + + true + + + + Misc Fixed + 11 + 75 + true + + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustToContents + + + + + + + + + + diff --git a/DownloadDCFirmware/receiver_thread.cpp b/DownloadDCFirmware/receiver_thread.cpp new file mode 100644 index 0000000..e69de29 diff --git a/DownloadDCFirmware/receiver_thread.h b/DownloadDCFirmware/receiver_thread.h new file mode 100644 index 0000000..e69de29 diff --git a/DownloadDCFirmware/sender_thread.cpp b/DownloadDCFirmware/sender_thread.cpp new file mode 100644 index 0000000..e69de29 diff --git a/DownloadDCFirmware/sender_thread.h b/DownloadDCFirmware/sender_thread.h new file mode 100644 index 0000000..e69de29 diff --git a/common/include/message_handler.h b/common/include/message_handler.h new file mode 100755 index 0000000..98c4d7e --- /dev/null +++ b/common/include/message_handler.h @@ -0,0 +1,23 @@ +#ifndef MESSAGE_HANDLER_H_INCLUDED +#define MESSAGE_HANDLER_H_INCLUDED + +#include +#ifdef __linux__ +#include +#endif + +int getDebugLevel(); +void setDebugLevel(int newDebugLevel); + +bool messageHandlerInstalled(); +QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler); + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +// typedef void (*QtMessageHandler)(QtMsgType, const char *); +void atbDebugOutput(QtMsgType type, const char *msg); +#elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +// typedef void (*QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &); +void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg); +#endif + +#endif // MESSAGE_HANDLER_H_INCLUDED diff --git a/common/src/message_handler.cpp b/common/src/message_handler.cpp new file mode 100755 index 0000000..996bd2f --- /dev/null +++ b/common/src/message_handler.cpp @@ -0,0 +1,97 @@ +#include "message_handler.h" + +#include +#include +#include +#include +#include + + +static char const *DBG_NAME[] = { "DBG ", "WARN ", "CRIT ", "FATAL", "INFO " }; +static bool installedMsgHandler = false; +static int debugLevel = LOG_NOTICE; + +int getDebugLevel() { return debugLevel; } +void setDebugLevel(int newDebugLevel) { + debugLevel = newDebugLevel; +} + +bool messageHandlerInstalled() { + return installedMsgHandler; +} + +QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler) { + installedMsgHandler = (handler != 0); + static QtMessageHandler prevHandler = nullptr; + if (handler) { + prevHandler = qInstallMessageHandler(handler); + return prevHandler; + } else { + return qInstallMessageHandler(prevHandler); + } +} + +/// +/// \brief Print message according to given debug level. +/// +/// \note Install this function using qInstallMsgHandler(). +/// +/// int main(int argc, char **argv) { +/// installMsgHandler(atbDebugOutput); +/// QApplication app(argc, argv); +/// ... +/// return app.exec(); +/// } +/// +#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { + Q_UNUSED(context); + QString const localMsg = QString(DBG_NAME[type]) + msg.toLocal8Bit(); + + switch (debugLevel) { + case LOG_DEBUG: { // debug-level message + syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str()); + } break; + case LOG_INFO: { // informational message + if (type != QtDebugMsg) { + syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str()); + } + } break; + case LOG_NOTICE: { // normal, but significant, condition + if (type != QtDebugMsg) { + syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str()); + } + } break; + case LOG_WARNING: { // warning conditions + if (type != QtInfoMsg && type != QtDebugMsg) { + syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str()); + } + } break; + case LOG_ERR: { // error conditions + if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) { + syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str()); + } + } break; + case LOG_CRIT: { // critical conditions + if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) { + syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str()); + } + } break; + case LOG_ALERT: { // action must be taken immediately + if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) { + syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str()); + } + } break; + case LOG_EMERG: { // system is unusable + if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) { + syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str()); + } + } break; + default: { + //fprintf(stderr, "%s No ErrorLevel defined! %s\n", + // datetime.toStdString().c_str(), msg.toStdString().c_str()); + } + } +} +#endif +