/** * @RDE_HEADER@ * Display Panel Simulator widget; manages the LED-lines and servers * $Id$ * $HeadURL$ * $Author$ * Created by Florian Schult, SLSE, 2016-03-18 */ //===Include specifications================================================== #include "displayPanelSimulatorWidget.h" #include "ui_displayPanelSimulatorWidget.h" #include "displayPanelSimulatorTcpServer.h" #include "nglsettings.h" #include "debugmessages.h" #include "ui_debugmessages.h" #include #include #include #include #include #include #include #include DisplayPanelSimulatorWidget::DisplayPanelSimulatorWidget() : QMainWindow() , m_servers() , m_ui(new Ui::DisplayPanelSimulatorWidget) , m_ports() , m_ledLines() , m_mode() , m_message() , m_debugMessages(new DebugMessages(this)) , m_statusLabel(new QLabel(this)) , m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("DispSim.DisplayPanelSimulatorWidget")) , m_charSize() { m_ui->setupUi(this); restoreGeometry(NGLSettings::instance()->windowGeometry()); restoreState(NGLSettings::instance()->windowState()); m_statusLabel->setStyleSheet(QStringLiteral("QLabel {color: red;}")); m_statusLabel->setContentsMargins(0, 0, 0, 1); m_ui->statusBar->addPermanentWidget(m_statusLabel); connect(m_ui->fullscreenAction, &QAction::toggled, this, &DisplayPanelSimulatorWidget::onFullscreenAction); connect(m_ui->debugInfosAction, &QAction::triggered, this, &DisplayPanelSimulatorWidget::onDebugInfosAction); connect(m_ui->exitAction, &QAction::triggered, this, &DisplayPanelSimulatorWidget::onExitAction); connect(m_ui->saveSettingsAction, &QAction::triggered, this, &DisplayPanelSimulatorWidget::onSaveSettingsAction); DEBUG_LOG(m_logger) << "DisplayPanelSimulatorWidget finished"; } DisplayPanelSimulatorWidget::~DisplayPanelSimulatorWidget() { qDeleteAll(m_servers); delete m_ui; } //---Private slots----------------------------------------------------------- void DisplayPanelSimulatorWidget::onExitAction() { close(); } void DisplayPanelSimulatorWidget::onSaveSettingsAction() { NGLSettings::instance()->setPorts(m_ports); NGLSettings::instance()->setLastMode(m_mode.name); INFO_LOG(m_logger) << "Save settings action triggered"; } void DisplayPanelSimulatorWidget::onDebugInfosAction() { m_debugMessages->show(); m_debugMessages->raise(); m_debugMessages->activateWindow(); INFO_LOG(m_logger) << "Debug console triggered"; } void DisplayPanelSimulatorWidget::writeMultiLiners(const QString &string) { QString fullString = string.leftJustified((m_mode.letters * m_mode.lines), QLatin1Char(' '), true); for (int i = 0; i < fullString.size(); i += m_mode.letters) m_ledLines[i / m_mode.letters]->setText(fullString.mid(i, m_mode.letters)); } void DisplayPanelSimulatorWidget::onErrorMsg(int port, const QString &string, MsgLvl lvl) { if (lvl < MSGLVL_ERROR) return; m_statusLabel->setText(tr("%1: %2 %3 <|> %4").arg(levelName(lvl), tr("Port")).arg(port).arg(string)); } void DisplayPanelSimulatorWidget::onFullscreenAction(bool fullscreen) { if (fullscreen) { NGLSettings::instance()->setPreFullscreenWindowState(saveState()); NGLSettings::instance()->setPreFullscreenWindowGeometry(saveGeometry()); this->setWindowState(Qt::WindowFullScreen); } else { this->setWindowState(Qt::WindowNoState); restoreState(NGLSettings::instance()->preFullscreenwindowState()); restoreGeometry(NGLSettings::instance()->preFullscreenwindowGeometry()); } } //---Protected methods------------------------------------------------------- void DisplayPanelSimulatorWidget::changeEvent(QEvent *event) { if (event->type() == QEvent::LanguageChange) m_ui->retranslateUi(this); QMainWindow::changeEvent(event); } void DisplayPanelSimulatorWidget::closeEvent(QCloseEvent *event) { hide(); NGLSettings::instance()->setFullscreen(m_ui->fullscreenAction->isChecked()); m_ui->fullscreenAction->setChecked(false); NGLSettings::instance()->setWindowGeometry(saveGeometry()); NGLSettings::instance()->setWindowState(saveState()); event->accept(); QMainWindow::closeEvent(event); } void DisplayPanelSimulatorWidget::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Escape) m_ui->fullscreenAction->setChecked(false); QMainWindow::keyPressEvent(event); } //---Private Methods---------------------------------------------------------- // Note: Can return comma separated list which is special case. QString DisplayPanelSimulatorWidget::findFullMode(const QString &stubMode, const ModeMap &map) { QStringList retVal; for (auto it = map.begin(); it != map.end(); ++it) { if (it.key().startsWith(stubMode, Qt::CaseInsensitive)) retVal << it.key(); } return retVal.join(QStringLiteral(", ")); } //---Public methods---------------------------------------------------------- /** * Initializes the widget itself. * * @return Result code: * 0 = Initialize ok. * 1 = Member initialisation failed. * 2 = Signal/slot initialisation failed. * 3 = Mode is ambigious. * 4 = Mode not found. */ int DisplayPanelSimulatorWidget::initialize(const QString &mode_, const QVector &ports, bool fullscreen, bool showPort, const QString &imagePath) { if (!ports.isEmpty()) { Port p; for (int i = 0; i < ports.size(); ++i) { p.name = tr("Port: %1").arg(ports[i]); p.port = ports[i]; m_ports.insert(i, p); } } else m_ports = NGLSettings::instance()->ports(); const QString mode = (mode_.isEmpty() ? NGLSettings::instance()->lastMode() : mode_); m_debugMessages->onMessage(m_ports[0].port, tr("Mode: %1").arg(mode), MSGLVL_DEBUG); DEBUG_LOG(m_logger) << "Mode: " << mode; const ModeMap modeMap = NGLSettings::instance()->modes(); QString fullmode = findFullMode(mode, modeMap); if (fullmode.contains(QLatin1Char(','))) { m_debugMessages->onMessage(m_ports[0].port, tr("Mode '%1' is ambigious: %2.").arg(mode, fullmode), MSGLVL_FATAL); ERROR_LOG(m_logger) << "Mode '" << mode << "' is ambigious: " << fullmode << "."; return 3; } if (fullmode.isEmpty()) { m_debugMessages->onMessage(m_ports[0].port, tr("Mode '%1' not found.").arg(mode), MSGLVL_FATAL); ERROR_LOG(m_logger) << "Mode '" << mode << "' not found."; return 4; } m_mode = modeMap[fullmode]; QHBoxLayout *centralLayout = static_cast(this->centralWidget()->layout()); QVBoxLayout *vLayout = new QVBoxLayout(); QLabel *label = nullptr; // Member initialisation if (m_mode.lines == 1) { // Single line modes ---------------------------------------------- for (int i = 0; i < m_ports.size(); ++i) { m_debugMessages->onMessage(m_ports[0].port, tr("Opening port %1 with mode %2").arg(m_ports[0].port).arg(m_mode.name), MSGLVL_DEBUG); DEBUG_LOG(m_logger) << "Opening port " << m_ports[0].port << " with mode " << m_mode.name; if (showPort) { // Heading label = new QLabel(this); label->setText(m_ports[i].name); label->setAlignment(Qt::AlignHCenter); vLayout->addWidget(label); } // LedLine QLedLine *ledLine = new QLedLine(this); ledLine->setCharCountAndHeight(m_mode.letters, m_mode.height); m_ledLines.append(ledLine); vLayout->addWidget(ledLine); // Server connection DisplayPanelSimulatorTcpServer *server = new DisplayPanelSimulatorTcpServer(this); m_servers.append(server); connect(server, &DisplayPanelSimulatorTcpServer::plainMessage, ledLine, &QLedLine::setText); // Text to LedLine connect(server, &DisplayPanelSimulatorTcpServer::debugMessage, m_debugMessages, &DebugMessages::onMessage); // Debug-stuff to debug window connect(server, &DisplayPanelSimulatorTcpServer::debugMessage, this, &DisplayPanelSimulatorWidget::onErrorMsg); // Debug to status bar server->start(m_ports[i].port); } // \Single line modes ---------------------------------------------- } else { // Multi line modes ---------------------------------------------- m_debugMessages->onMessage(m_ports[0].port, tr("Opening port %1 with mode %2").arg(m_ports[0].port).arg(m_mode.name), MSGLVL_DEBUG); DEBUG_LOG(m_logger) << "Opening port " << m_ports[0].port << " with mode " << m_mode.name; int linesNeeded = m_mode.lines; if (showPort) { //Heading label = new QLabel(this); label->setText(m_ports[0].name); label->setAlignment(Qt::AlignHCenter); vLayout->addWidget(label); } // Server connection DisplayPanelSimulatorTcpServer *server = new DisplayPanelSimulatorTcpServer(this); m_servers.append(server); connect(server, &DisplayPanelSimulatorTcpServer::plainMessage, this, &DisplayPanelSimulatorWidget::writeMultiLiners); // Text to LedLine connect(server, &DisplayPanelSimulatorTcpServer::debugMessage, m_debugMessages, &DebugMessages::onMessage); // Debug-stuff to debug window connect(server, &DisplayPanelSimulatorTcpServer::debugMessage, this, &DisplayPanelSimulatorWidget::onErrorMsg); // Debug to status bar server->start(m_ports[0].port); for (int i = 0; i < linesNeeded; ++i) { // LedLine QLedLine *ledLine = new QLedLine(this); ledLine->setCharCountAndHeight(m_mode.letters, m_mode.height); m_ledLines.append(ledLine); vLayout->addWidget(ledLine); } // \Multi line modes ---------------------------------------------- } // Graphic show ------------------------------------------- // Todo: Zentriert? Nein, gibt keine Flag, evtl. extra Image erstellen und prependen etc. QImage image(imagePath.isEmpty() ? QStringLiteral("./rheinmetall.jpg") : imagePath); if (!image.isNull()) { scaleImage(image); for (int i = 0; i < m_ledLines.size(); ++i) { const QImage lineImage = image.copy(0, (m_charSize.height() * i), image.width(), m_charSize.height()); m_ledLines[i]->setImage(lineImage); } } // \Graphic show ------------------------------------------- vLayout->setContentsMargins(0, 0, 0, 0); vLayout->setSpacing(0); centralLayout->addLayout(vLayout); centralLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); INFO_LOG(m_logger) << "All LedLines initialised"; fullscreen |= NGLSettings::instance()->fullscreen(); m_ui->fullscreenAction->setChecked(fullscreen); show(); return 0; } void DisplayPanelSimulatorWidget::scaleImage(QImage &image) { m_charSize = m_ledLines[0]->charSize(); // Width per QLedChar times QLedChars per QLedLine; and Height per QLedChar times QLedLines needed QSize maxPxSize((m_charSize.width() * m_mode.letters), (m_charSize.height() * (m_mode.lines == 1 ? m_ports.size() : m_mode.lines))); image = image.scaled(maxPxSize, Qt::KeepAspectRatio); } //===========================================================================