#include "LogViewTelegramEdit.hpp" #include "LogViewInjectionThread.hpp" #include "LogViewTelegramDialog.hpp" #include "LogViewTelegramEditModel.hpp" #include "LogViewTelegramSelectionDialog.hpp" #include #include #include #include #include #include #include #include #include #include #include #include namespace N_LogView { QString TelegramEdit::s_DIR() { return QStringLiteral("Dir"); } QString TelegramEdit::s_EDIT_TELEGRAM_GROUP() { return QStringLiteral("EditTelegrams"); } QString TelegramEdit::s_TELEGRAMLIST_FILE_ID() { return QStringLiteral("RDETGL"); } QString TelegramEdit::s_TELEGRAMLIST_FILES() { return tr("Telegrammliste-Dateien (*.tgl);;Alle Dateien (*)"); } TelegramEdit::TelegramEdit(QWidget *parent) : QObject(parent) , m_addTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/list-add.png")), tr("Add Telegram"), this)) , m_editTeleAction(new QAction(QIcon(QLatin1String(":/image/Edit.png")), tr("Edit Telegram"), this)) , m_copyTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/edit-copy.png")), tr("Copy Telegram"), this)) , m_pasteTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/edit-paste.png")), tr("Paste Telegram"), this)) , m_deleteTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/list-remove.png")), tr("Delete Telegram"), this)) , m_moveTeleUpAction(new QAction(QIcon(QLatin1String(":icons/16x16/go-up.png")), tr("Move up"), this)) , m_moveTeleDownAction(new QAction(QIcon(QLatin1String(":icons/16x16/go-down.png")), tr("Move down"), this)) , m_teleListLoad(new QAction(QIcon(QLatin1String(":icons/16x16/document-open-data.png")), tr("Load Telegram list"), this)) , m_teleListAppend(new QAction(QIcon(), tr("Telegrammliste anhaengen"), this)) , m_teleListSave(new QAction(QIcon(QLatin1String(":icons/16x16/document-save.png")), tr("Save Telegram list"), this)) , m_tableView(new QTableView(parent)) , m_DoLoop(false) , m_InjectionThread(nullptr) , m_EditModel(new TelegramEditModel(this)) , m_logger(getLogger("LogViewTelegramEdit")) { m_addTeleAction->setShortcut(tr("Ctrl+A")); m_editTeleAction->setShortcut(tr("Ctrl+E")); m_copyTeleAction->setShortcut(tr("Ctrl+C")); m_pasteTeleAction->setShortcut(tr("Ctrl+V")); m_deleteTeleAction->setShortcut(Qt::Key_Delete); m_moveTeleUpAction->setShortcut(tr("Ctrl+U")); m_moveTeleDownAction->setShortcut(tr("Ctrl+D")); m_teleListLoad->setShortcut(tr("Ctrl+L")); m_teleListAppend->setShortcut(tr("Ctrl+K")); m_teleListSave->setShortcut(tr("Ctrl+S")); m_addTeleAction->setEnabled(true); m_copyTeleAction->setEnabled(false); m_pasteTeleAction->setEnabled(false); m_deleteTeleAction->setEnabled(false); m_moveTeleUpAction->setEnabled(false); m_moveTeleDownAction->setEnabled(false); m_teleListLoad->setEnabled(true); m_teleListAppend->setEnabled(true); m_teleListSave->setEnabled(false); connect(m_addTeleAction, &QAction::triggered, this, &TelegramEdit::addTelegram); connect(m_editTeleAction, &QAction::triggered, this, &TelegramEdit::editTelegram); connect(m_copyTeleAction, &QAction::triggered, this, &TelegramEdit::copy); connect(m_pasteTeleAction, &QAction::triggered, this, &TelegramEdit::paste); connect(m_deleteTeleAction, &QAction::triggered, this, &TelegramEdit::deleteTelegram); connect(m_moveTeleUpAction, &QAction::triggered, this, &TelegramEdit::moveUp); connect(m_moveTeleDownAction, &QAction::triggered, this, &TelegramEdit::moveDown); connect(m_teleListLoad, &QAction::triggered, this, &TelegramEdit::loadTelegramListReplace); connect(m_teleListAppend, &QAction::triggered, this, &TelegramEdit::loadTelegramListAppend); connect(m_teleListSave, &QAction::triggered, this, &TelegramEdit::saveTelegramList); m_tableView->setModel(m_EditModel); m_tableView->verticalHeader()->hide(); m_tableView->setContextMenuPolicy(Qt::CustomContextMenu); m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); m_tableView->setSelectionMode(QAbstractItemView::SingleSelection); connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TelegramEdit::onSelectionChanged); connect(m_tableView, &QTableView::doubleClicked, this, &TelegramEdit::editTelegram); connect(m_tableView, &QTableView::customContextMenuRequested, this, &TelegramEdit::tableViewCustomContextMenu); m_tableView->addAction(m_addTeleAction); m_tableView->addAction(m_editTeleAction); m_tableView->addAction(m_copyTeleAction); m_tableView->addAction(m_pasteTeleAction); m_tableView->addAction(m_deleteTeleAction); m_tableView->addAction(m_moveTeleUpAction); m_tableView->addAction(m_moveTeleDownAction); } void TelegramEdit::setInjectionThread(LogViewInjectionThread *a_injectionThread) { m_InjectionThread = a_injectionThread; } void TelegramEdit::appendTelegram(const QSharedPointer &telegram) { m_EditModel->appendTelegram(telegram); m_teleListSave->setEnabled(true); } void TelegramEdit::tableViewCustomContextMenu(const QPoint &pos) { QMenu menu; menu.addAction(m_addTeleAction); menu.addAction(m_editTeleAction); menu.addAction(m_copyTeleAction); menu.addAction(m_pasteTeleAction); menu.addAction(m_deleteTeleAction); menu.addSeparator(); menu.addAction(m_moveTeleUpAction); menu.addAction(m_moveTeleDownAction); menu.addSeparator(); const bool itemSelected = m_tableView->currentIndex().isValid(); bool isCentral = false; QSharedPointer tele = m_EditModel->telegram(m_tableView->currentIndex().row()); if (tele) isCentral = (tele->getProtocol() == N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral); if (isInjectionPossible()) { QAction *action = menu.addAction(QIcon(QLatin1String(":/image/InjectCentral.png")), tr("Injektiere Zentral-Telegramm")); action->setEnabled(itemSelected && isCentral); connect(action, &QAction::triggered, this, &TelegramEdit::injectCentralTelegram); action = menu.addAction(QIcon(QLatin1String(":/image/InjectTetra.png")), tr("Injektiere Tetra-Telegramm")); action->setEnabled(itemSelected && isCentral); connect(action, &QAction::triggered, this, &TelegramEdit::injectTetraTelegram); menu.addSeparator(); action = menu.addAction(QIcon(QLatin1String(":icons/16x16/mail-send.png")), tr("Sende Telegramm")); action->setEnabled(itemSelected && isCentral); connect(action, &QAction::triggered, this, &TelegramEdit::sendCurrentTelegram); if (m_DoLoop) action = menu.addAction(QIcon(QLatin1String(":icons/16x16/media-playback-stop.png")), tr("Stop Loopen")); else { action = menu.addAction(QIcon(QLatin1String(":icons/16x16/media-playback-start.png")), tr("Loop Telegramme")); action->setEnabled(itemSelected); } connect(action, &QAction::triggered, this, &TelegramEdit::loopTelegrams); action = menu.addAction(QIcon(QLatin1String(":icons/16x16/media-play-normal.png")), tr("Sende Sequenz")); action->setEnabled(itemSelected); connect(action, &QAction::triggered, this, &TelegramEdit::sequenceTelegrams); menu.addSeparator(); } menu.addAction(m_teleListLoad); menu.addAction(m_teleListAppend); menu.addAction(m_teleListSave); menu.exec(m_tableView->viewport()->mapToGlobal(pos)); } void TelegramEdit::addTelegram() { LogViewTelegramSelectionDialog telegramSelectionDialog(m_tableView); if (QDialog::Accepted == telegramSelectionDialog.exec()) { QSharedPointer newTelegram = QSharedPointer(new LogViewTelegram(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral, telegramSelectionDialog.getSelectedTelegramId())); m_curEditTelegramRow = m_EditModel->appendTelegram(newTelegram); LogViewTelegramDialog *editTelegramDialog = new LogViewTelegramDialog(m_tableView, false); connect(editTelegramDialog, &LogViewTelegramDialog::finished, this, &TelegramEdit::editTelegramDialogFinished); connect(editTelegramDialog, &LogViewTelegramDialog::sendTelegram, this, &TelegramEdit::sendTelegram); editTelegramDialog->showDialog(newTelegram); m_teleListSave->setEnabled(true); } } QSharedPointer TelegramEdit::currentSelectedTelegram() const { return m_EditModel->telegram(currentSelectedIndex().row()); } QModelIndex TelegramEdit::currentSelectedIndex() const { return m_tableView->currentIndex(); } void TelegramEdit::editTelegramDialogFinished() { m_EditModel->emitDataChanged(m_curEditTelegramRow); } void TelegramEdit::editTelegram() { m_curEditTelegramRow = currentSelectedIndex().row(); if (m_curEditTelegramRow < 0) return; LogViewTelegramDialog *editTelegramDialog = new LogViewTelegramDialog(m_tableView, false); connect(editTelegramDialog, &LogViewTelegramDialog::finished, this, &TelegramEdit::editTelegramDialogFinished); editTelegramDialog->showDialog(currentSelectedTelegram()); } void TelegramEdit::showTelegram() { LogViewTelegramDialog *showTelegramDialog = new LogViewTelegramDialog(m_tableView, true); showTelegramDialog->showDialog(currentSelectedTelegram()); } void TelegramEdit::deleteTelegram() { const QModelIndexList indexList = m_tableView->selectionModel()->selectedIndexes(); QSet rows; rows.reserve(indexList.size()); for (const QModelIndex &index : indexList) rows += index.row(); m_EditModel->removeTelegrams(rows); m_teleListSave->setEnabled(m_EditModel->rowCount() > 0); } void TelegramEdit::injectCentralTelegram() { injectTelegram(true); } void TelegramEdit::injectTetraTelegram() { injectTelegram(false); } void TelegramEdit::injectTelegram(bool a_bAsCentralTelegram) { injectTelegram(currentSelectedTelegram(), a_bAsCentralTelegram); } void TelegramEdit::injectTelegram(const QSharedPointer &a_telegram, bool a_bAsCentralTelegram) { if (!isInjectionPossible()) { WARNING_LOG(m_logger) << "Try to inject a telegramm but the injection thread is not running"; return; } if (a_telegram.isNull()) { WARNING_LOG(m_logger) << "Try to inject a telegramm but no telegramm selected"; return; } a_telegram->actualizeGpsTime(); m_InjectionThread->sendTelegram(a_telegram.data(), a_bAsCentralTelegram); } void TelegramEdit::sendCurrentTelegram() { sendTelegram(currentSelectedTelegram()); } void TelegramEdit::sendTelegram(const QSharedPointer &a_telegram) { injectTelegram(a_telegram, true); } void TelegramEdit::loopTelegrams() { if (m_DoLoop) { m_DoLoop = false; m_deleteTeleAction->setEnabled(m_tableView->currentIndex().isValid()); } else { m_DoLoop = true; m_deleteTeleAction->setEnabled(false); m_currentRowToSend = currentSelectedIndex().row(); if (m_currentRowToSend < 0) return; QSharedPointer tele = currentSelectedTelegram(); sendTelegram(tele); QTimer::singleShot(tele->getWaitTime(), this, &TelegramEdit::loopNextTelegram); } } void TelegramEdit::loopNextTelegram() { if (!m_DoLoop) return; ++m_currentRowToSend; if (m_currentRowToSend >= m_tableView->model()->rowCount()) m_currentRowToSend = 0; QSharedPointer tele = telegramAtRow(m_currentRowToSend); if (!tele) return; sendTelegram(tele); QTimer::singleShot(tele->getWaitTime(), this, &TelegramEdit::loopNextTelegram); } void TelegramEdit::sequenceTelegrams() { m_currentRowToSend = currentSelectedIndex().row(); if (m_currentRowToSend < 0) return; QSharedPointer tele = currentSelectedTelegram(); sendTelegram(tele); QTimer::singleShot(tele->getWaitTime(), this, &TelegramEdit::sequenceNextTelegram); } void TelegramEdit::sequenceNextTelegram() { ++m_currentRowToSend; if (m_currentRowToSend >= m_tableView->model()->rowCount()) return; QSharedPointer tele = telegramAtRow(m_currentRowToSend); if (!tele) return; sendTelegram(tele); QTimer::singleShot(tele->getWaitTime(), this, &TelegramEdit::sequenceNextTelegram); } QSharedPointer TelegramEdit::telegramAtRow(int row) { return m_EditModel->telegram(row); } void TelegramEdit::copy() { m_copyTelegram = currentSelectedTelegram(); m_pasteTeleAction->setEnabled(m_copyTelegram != nullptr); if (!m_copyTelegram) return; m_copyTelegram = QSharedPointer(new LogViewTelegram(*m_copyTelegram.data())); } void TelegramEdit::paste() { if (!m_copyTelegram) return; int row = currentSelectedIndex().row() + 1; m_EditModel->pasteRows(row, m_copyTelegram); } void TelegramEdit::moveUp() { const QModelIndex idx = currentSelectedIndex(); if (m_EditModel->moveUp(idx.row())) { m_tableView->clearSelection(); m_tableView->setCurrentIndex(m_EditModel->index(idx.row() - 1, idx.column(), idx.parent())); m_moveTeleUpAction->setEnabled(idx.row() > 1); m_moveTeleDownAction->setEnabled(true); } } void TelegramEdit::moveDown() { const QModelIndex idx = currentSelectedIndex(); if (m_EditModel->moveDown(idx.row())) { m_tableView->clearSelection(); m_tableView->setCurrentIndex(m_EditModel->index(idx.row() + 1, idx.column(), idx.parent())); m_moveTeleUpAction->setEnabled(true); m_moveTeleDownAction->setEnabled(idx.row() < m_EditModel->rowCount() - 2); } } void TelegramEdit::saveTelegramList() { QSettings settings; QString newFilename = QFileDialog::getSaveFileName(m_tableView, tr("Dateiname der Telegrammliste"), settings.value(s_DIR()).toString(), s_TELEGRAMLIST_FILES()); if (!newFilename.isEmpty()) { if (!newFilename.contains(QLatin1Char('.'))) newFilename += QLatin1String(".tgl"); QDir dir; settings.beginGroup(s_EDIT_TELEGRAM_GROUP()); settings.setValue(s_DIR(), dir.filePath(newFilename)); settings.endGroup(); QFile telegramFile(newFilename); telegramFile.open(QIODevice::WriteOnly); QDataStream stream(&telegramFile); uint32_t version = 1; stream << s_TELEGRAMLIST_FILE_ID() << version; int rows = m_tableView->model()->rowCount(); stream << rows; for (int i = 0; i < rows; i++) { QSharedPointer telegram = telegramAtRow(i); if (!telegram) continue; const QByteArray &data = telegram->getData(); const QString name = telegram->getName(); const unsigned int waitTime = telegram->getWaitTime(); stream << waitTime << name << telegram->getGpsTimeField() << data.size(); stream.writeRawData(data.data(), data.size()); } telegramFile.close(); } } void TelegramEdit::loadTelegramListAppend() { loadTelegramList(true); } void TelegramEdit::loadTelegramListReplace() { loadTelegramList(false); } void TelegramEdit::loadTelegramList(bool checkAppend) { QSettings settings; QString newFilename = QFileDialog::getOpenFileName(m_tableView, tr("Dateiname der Telegrammliste"), settings.value(s_DIR()).toString(), s_TELEGRAMLIST_FILES()); if (!newFilename.isEmpty()) { QDir dir; settings.beginGroup(s_EDIT_TELEGRAM_GROUP()); settings.setValue(s_DIR(), dir.filePath(newFilename)); settings.endGroup(); { if (!checkAppend) m_EditModel->clearTelegrams(); } QFile telegramFile(newFilename); telegramFile.open(QIODevice::ReadOnly); QDataStream stream(&telegramFile); QString id; stream >> id; if (id != s_TELEGRAMLIST_FILE_ID()) { QMessageBox::critical(m_tableView, tr("Error"), tr("%1 does not contain telegram data").arg(newFilename)); return; } uint32_t version = 0; stream >> version; if (version != 1) { QMessageBox::critical(m_tableView, tr("Error"), tr("Wrong telegram list file version")); return; } int rows = 0; QVector gpsFieldOffset; stream >> rows; for (int i = 0; i < rows; i++) { uint32_t waitTime = 0; QString name; int telegramSize = 0; stream >> waitTime >> name >> gpsFieldOffset >> telegramSize; if (telegramSize > 0) { DEBUG_LOG(m_logger) << "telegramSize=" << telegramSize; QByteArray buf(telegramSize, Qt::Uninitialized); stream.readRawData(buf.data(), telegramSize); NGL::NGLLoggerHelper::hexDumpHelper(m_logger, NGL::LogLevel::Debug, buf); LogViewTelegram *telegram = new LogViewTelegram(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral, 0, buf); telegram->setWaitTime(waitTime); telegram->setName(name); telegram->setGpsTimeField(gpsFieldOffset); m_EditModel->appendTelegram(QSharedPointer(telegram)); } } telegramFile.close(); m_teleListSave->setEnabled(m_EditModel->rowCount() > 0); } } bool TelegramEdit::isInjectionPossible() const { return m_InjectionThread ? m_InjectionThread->isSendingPossible() : false; } void TelegramEdit::onSelectionChanged() { const QModelIndex idx = currentSelectedIndex(); m_editTeleAction->setEnabled(idx.isValid()); m_copyTeleAction->setEnabled(idx.isValid()); m_deleteTeleAction->setEnabled(idx.isValid()); m_moveTeleUpAction->setEnabled(idx.row() > 0); m_moveTeleDownAction->setEnabled(idx.isValid() && idx.row() < m_EditModel->rowCount() - 1); } }