442 lines
13 KiB
C++
Executable File
442 lines
13 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Notifcation plugin for TAB connection states
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Philipp Dassow, SLST, 2017-09-19
|
|
*/
|
|
|
|
|
|
#include "nme_battery_info_dialog.h"
|
|
#include "nme_notification_gui_plugin.h"
|
|
#include "nme_shutdown_dialog.h"
|
|
|
|
#include <LtsSession/lts_session.h>
|
|
#include <LtsNotification/lts_notification.h>
|
|
#include <LtsWidgets/lts_base_layout_widget.h>
|
|
#include <QCoreApplication>
|
|
#include <QMessageBox>
|
|
#include <QPainter>
|
|
#include <QPixmap>
|
|
|
|
|
|
namespace NmeaManagement
|
|
{
|
|
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
|
{
|
|
return std::make_shared<InterfaceImpl>(session);
|
|
}
|
|
|
|
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
|
: GuiPluginBase::Interface(session, NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("NmeaGuiPlugin"))
|
|
, m_tabDtc(nullptr)
|
|
, m_tabFtc(nullptr)
|
|
, m_notiBattery(nullptr)
|
|
, m_notiOwnPosition(nullptr)
|
|
{
|
|
m_oudatedFirstBatteryTimer = new QTimer(this);
|
|
m_oudatedSecondBatteryTimer = new QTimer(this);
|
|
connect(m_oudatedFirstBatteryTimer, &QTimer::timeout, this,&InterfaceImpl::onOutdatedFirstBatteryTimerTimeout);
|
|
connect(m_oudatedSecondBatteryTimer, &QTimer::timeout, this,&InterfaceImpl::onOutdatedSecondBatteryTimerTimeout);
|
|
}
|
|
|
|
InterfaceImpl::~InterfaceImpl()
|
|
{
|
|
delete m_notiBattery;
|
|
delete m_notiOwnPosition;
|
|
}
|
|
|
|
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
|
{
|
|
QVector<LtsWidgets::PluginData> ret;
|
|
|
|
LtsWidgets::PluginData plData;
|
|
plData.menuGroup = menuGroup();
|
|
plData.menuText = tr("Shutdown Radio Master");
|
|
plData.identifier = QLatin1String("ShutdownRadioMaster");
|
|
plData.menuIcon = QIcon(QLatin1String("icon:application-exit.svg"));
|
|
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
|
plData.directFunc = [this](const LtsWidgets::PluginData &)
|
|
{
|
|
NmeBatteryInfoDialog *batteryDialog = new NmeBatteryInfoDialog(m_currentBatteryStateForId, m_tabDtc, m_tabFtc);
|
|
m_session->addWidget(batteryDialog, menuGroup(), QStringLiteral("batteryInfo"), LtsWidgets::LayoutArea::eDialogTab);
|
|
};
|
|
|
|
if (m_notiBattery != nullptr /*|| m_notiOwnPosition != nullptr*/)
|
|
return QVector<LtsWidgets::PluginData>();
|
|
|
|
//TODO: Uncomment if necessary
|
|
// m_notiOwnPosition = m_session->createNotification(QStringLiteral("Show own position"));
|
|
// m_notiOwnPosition->setToolTip(tr("Show own position"));
|
|
// m_notiOwnPosition->setIcon(QIcon(QStringLiteral("icon:/position.svg")));
|
|
// m_notiOwnPosition->setAction([this](){
|
|
|
|
// //TODO: What to do if something like that happend
|
|
// });
|
|
|
|
m_notiBattery = m_session->createNotification(QStringLiteral("Radio Master Battery State"));
|
|
updateBatteryLevel();
|
|
m_notiBattery->setAction([this](){
|
|
NmeBatteryInfoDialog *batteryDialog = new NmeBatteryInfoDialog(m_currentBatteryStateForId, m_tabDtc, m_tabFtc);
|
|
m_session->addWidget(batteryDialog, menuGroup(), QStringLiteral("batteryInfo"), LtsWidgets::LayoutArea::eDialogTab);
|
|
|
|
});
|
|
//setToolTip();
|
|
|
|
// ret.append(plData);
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool InterfaceImpl::fetchInterfaces()
|
|
{
|
|
//Dual Use while migrating from NmeaService to Nmea Tab Plugin
|
|
|
|
if (!m_session->getDtc<TrainingAreaBase::DataInterface>(m_tabDtc))
|
|
return false;
|
|
|
|
if (!m_session->getFtc<TrainingAreaBase::DataInterface>(m_tabFtc))
|
|
return false;
|
|
|
|
if(!m_tabDtc->enableBatteryInfo())
|
|
return false;
|
|
|
|
if(!m_tabDtc->enableBatteryAlarm())
|
|
return false;
|
|
|
|
if(!m_tabDtc->enableServiceControl())
|
|
return false;
|
|
|
|
if(!m_tabFtc->enableSetDevicePower())
|
|
return false;
|
|
|
|
connect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::batteryInfoChanged, this, &InterfaceImpl::onBatteryChanged);
|
|
connect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::serviceControlChanged, this, &InterfaceImpl::onShutdownStateChanged);
|
|
return true;
|
|
}
|
|
|
|
void InterfaceImpl::clearInterfaces()
|
|
{
|
|
|
|
disconnect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::batteryInfoChanged, this, &InterfaceImpl::onBatteryChanged);
|
|
disconnect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::serviceControlChanged, this, &InterfaceImpl::onShutdownStateChanged);
|
|
m_tabDtc = nullptr;
|
|
m_tabFtc = nullptr;
|
|
}
|
|
/*!
|
|
* \brief InterfaceImpl::onBatteryChanged
|
|
* \param data
|
|
* \param modType
|
|
* \details
|
|
* Receives Battery State and save them if changed
|
|
* Paints new Icon and set new tooltip
|
|
* If incoming BatteryState is under 2 (40%) and lower than last received state -> Show Warning
|
|
*/
|
|
void InterfaceImpl::onBatteryChanged(const TrainingAreaBase::BatteryInfo &dataArr, DataModification modType)
|
|
{
|
|
if(dataArr.equipmentNumber() != 1)
|
|
return;
|
|
auto data = dataArr.batteryStates().at(0);
|
|
|
|
switch (modType)
|
|
{
|
|
case DataModification::eAdded:
|
|
case DataModification::eModified:
|
|
{
|
|
|
|
if(m_hasConnection == false)
|
|
{
|
|
m_hasConnection = true;
|
|
if (m_session->baseLayout() != nullptr)
|
|
m_session->baseLayout()->showMessage(tr("The radio master is connected"), tr("Connection was successfully reestablished"), LtsWidgets::LtsNotificationBox::MessageType::Success);
|
|
}
|
|
if((data.batteryPercent() / 20) < m_currentBatteryStateForId.value(data.batteryPort()).batteryPercent() / 20 && data.batteryPercent() / 20 < 2)
|
|
{
|
|
QMessageBox batteryWarnBox;
|
|
batteryWarnBox.setWindowTitle(tr("Battery Warning"));
|
|
batteryWarnBox.setText(tr("The battery (%1) has only %2 \% left").arg(QString::fromStdString(data.serialNumber())).arg(data.batteryPercent())); //*20 = Real percentage
|
|
batteryWarnBox.exec();
|
|
}
|
|
m_currentBatteryStateForId.insert(data.batteryPort(), data);
|
|
|
|
updateBatteryLevel();
|
|
|
|
if(data.batteryPort() == 0)
|
|
m_oudatedFirstBatteryTimer->start(30000);
|
|
else if(data.batteryPort() == 1)
|
|
m_oudatedSecondBatteryTimer->start(30000);
|
|
|
|
break;
|
|
}
|
|
|
|
case DataModification::eRemoved:
|
|
{
|
|
m_currentBatteryStateForId.remove(data.batteryPort());
|
|
updateBatteryLevel();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/*!
|
|
* \brief InterfaceImpl::onShutdownStateChanged
|
|
* \author Niklas Schmidt
|
|
* \param data
|
|
* \param modType
|
|
* \details
|
|
* Receives notification for the sthutdown state of RadioMaster
|
|
* Than show QMessageBox with shutdown state
|
|
*/
|
|
void InterfaceImpl::onShutdownStateChanged(const TrainingAreaBase::ServiceControl &data, DataModification modType)
|
|
{
|
|
if(data.equipmentNumber() != 1)
|
|
return;
|
|
|
|
switch (modType)
|
|
{
|
|
case DataModification::eAdded:
|
|
case DataModification::eModified:
|
|
{
|
|
|
|
if(data.serviceControlState().underlying() == TrainingAreaBase::ServiceControlEnum::STOP)
|
|
{
|
|
m_hasConnection = false;
|
|
if (m_session->baseLayout() != nullptr)
|
|
m_session->baseLayout()->showMessage(tr("The radio master is shut down"), tr("The batteries can be disconnected."), LtsWidgets::LtsNotificationBox::MessageType::Error);
|
|
|
|
|
|
}
|
|
//shutdownInfoBox.exec();
|
|
break;
|
|
}
|
|
case DataModification::eRemoved:
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
/*!
|
|
* \brief InterfaceImpl::onOutdatedFirstBatteryTimerTimeout
|
|
* \details
|
|
* Timeouted if no new incoming data is available
|
|
* Updates battery icon to unknown state
|
|
*/
|
|
void InterfaceImpl::onOutdatedFirstBatteryTimerTimeout()
|
|
{
|
|
//Default values for undefined state
|
|
if(m_currentBatteryStateForId.size() < 2)
|
|
{
|
|
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage()));
|
|
setToolTip();
|
|
m_currentBatteryStateForId.clear();
|
|
return;
|
|
}
|
|
|
|
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(99, m_currentBatteryStateForId.value(1).batteryPercent() / 20)));
|
|
setToolTip(99, m_currentBatteryStateForId.value(1).batteryPercent() / 20);
|
|
m_currentBatteryStateForId.remove(0);
|
|
|
|
}
|
|
|
|
/*!
|
|
* \brief InterfaceImpl::onOutdatedSecondBatteryTimerTimeout
|
|
* \details
|
|
* Timeouted if no new incoming data is available
|
|
* Updates battery icon to unknown state
|
|
*/
|
|
void InterfaceImpl::onOutdatedSecondBatteryTimerTimeout()
|
|
{
|
|
|
|
if(m_currentBatteryStateForId.size() < 2)
|
|
{
|
|
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage()));
|
|
setToolTip();
|
|
m_currentBatteryStateForId.clear();
|
|
return;
|
|
}
|
|
//Default values for undefined state
|
|
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(m_currentBatteryStateForId.value(0).batteryPercent() / 20, 99)));
|
|
setToolTip(m_currentBatteryStateForId.value(0).batteryPercent() / 20, 99);
|
|
m_currentBatteryStateForId.remove(1);
|
|
}
|
|
/*!
|
|
* \brief InterfaceImpl::setToolTip
|
|
* \param firstBattery
|
|
* \author Niklas Schmidt
|
|
* \param secondBattery
|
|
* \details Changes Tooltip for BatteryState Notification
|
|
*/
|
|
void InterfaceImpl::setToolTip(int firstBattery, int secondBattery)
|
|
{
|
|
QString tooltip;
|
|
if(firstBattery == 99)
|
|
tooltip = tr("First Battery Level: Unknown %1").arg(QStringLiteral("\n"));
|
|
else
|
|
tooltip = tr("First Battery Level: ") + QString::number(firstBattery * 20) + QStringLiteral("% \n");
|
|
|
|
if(secondBattery == 99)
|
|
tooltip += tr("Second Battery Level: Unknown");
|
|
else
|
|
tooltip += tr("Second Battery Level: ") + QString::number(secondBattery * 20) + QStringLiteral("%");
|
|
|
|
m_notiBattery->setToolTip(tooltip);
|
|
}
|
|
/*!
|
|
* \brief InterfaceImpl::renderBatteryImage
|
|
* \author Niklas Schmidt
|
|
* \param firstBatteryState
|
|
* \param secondBatteryState
|
|
* \details
|
|
* This method paints the icon for battery state
|
|
*
|
|
* Battery Unknown = Only Outline and Questionmark in middle
|
|
* Battery 0% = 5 Red Bars
|
|
* Battery 20% = 1 Red Bar
|
|
* Battery 40% = 2 Yellow Bar
|
|
* Battery 60% = 3 Green Bars
|
|
* Battery 80% = 4 Green Bras
|
|
* Battery 100% = 5 Green Bars
|
|
*
|
|
* BatteryState Int -> 0 = Empty ... 5 = Full | 99 = Unknown
|
|
* \return
|
|
*/
|
|
QImage InterfaceImpl::renderBatteryImage(int firstBatteryState, int secondBatteryState)
|
|
{
|
|
|
|
int firstBattery = firstBatteryState;
|
|
int secondBattery = secondBatteryState;
|
|
|
|
int size = 100;
|
|
QImage image(size, size, QImage::Format_ARGB32);
|
|
image.fill(Qt::transparent);
|
|
|
|
QPainter painter(&image);
|
|
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
|
|
|
if(firstBattery != 99)
|
|
{
|
|
painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
|
|
if(firstBattery < 3)
|
|
painter.setBrush(QBrush(Qt::yellow, Qt::SolidPattern));
|
|
if(firstBattery < 2)
|
|
painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
|
|
|
|
if(firstBattery == 0)
|
|
{
|
|
painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
|
|
firstBattery = 5; // To paint all 5 bars red
|
|
}
|
|
//For first battery (upper bar)
|
|
if (firstBattery > 0)
|
|
painter.drawRect(00, 00, 18, 40);
|
|
if (firstBattery > 1)
|
|
painter.drawRect(20, 00, 18, 40);
|
|
if (firstBattery > 2)
|
|
painter.drawRect(40, 00, 18, 40);
|
|
if (firstBattery > 3)
|
|
painter.drawRect(60, 00, 18, 40);
|
|
if (firstBattery > 4)
|
|
painter.drawRect(80, 00, 18, 40);
|
|
}
|
|
|
|
if(secondBattery != 99)
|
|
{
|
|
painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
|
|
if(secondBattery < 3)
|
|
painter.setBrush(QBrush(Qt::yellow, Qt::SolidPattern));
|
|
if(secondBattery < 2)
|
|
painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
|
|
|
|
if(secondBattery == 0)
|
|
{
|
|
painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
|
|
secondBattery = 5; // To paint all 5 bars red
|
|
}
|
|
|
|
//For second battery (lower bar)
|
|
if (secondBattery > 0)
|
|
painter.drawRect(00, 60, 18, 40);
|
|
if (secondBattery > 1)
|
|
painter.drawRect(20, 60, 18, 40);
|
|
if (secondBattery > 2)
|
|
painter.drawRect(40, 60, 18, 40);
|
|
if (secondBattery > 3)
|
|
painter.drawRect(60, 60, 18, 40);
|
|
if (secondBattery > 4)
|
|
painter.drawRect(80, 60, 18, 40);
|
|
}
|
|
|
|
QFont font = painter.font() ;
|
|
font.setPointSize(30);
|
|
painter.setFont(font);
|
|
|
|
painter.setBrush(QBrush(Qt::black, Qt::NoBrush));
|
|
if(firstBattery == 99) //If Unknown BatteryState
|
|
{
|
|
painter.setPen(Qt::black);
|
|
painter.drawText(45,35, QStringLiteral("?"));
|
|
}
|
|
|
|
// Draw Outline for whole Battery
|
|
painter.setPen(Qt::black);
|
|
painter.drawRect(00,00,100,40);
|
|
|
|
painter.setBrush(QBrush(Qt::black, Qt::NoBrush));
|
|
if(secondBattery == 99) //If Unknown BatteryState
|
|
{
|
|
painter.setPen(Qt::black);
|
|
painter.drawText(45,92, QStringLiteral("?"));
|
|
}
|
|
|
|
// Draw Outline for whole Battery
|
|
painter.setPen(Qt::black);
|
|
painter.drawRect(00,60,100,40);
|
|
|
|
|
|
// 'marking':
|
|
// painter.setPen(QPen(Qt::NoPen)); // rect with no outter line
|
|
|
|
painter.end();
|
|
|
|
return image;
|
|
}
|
|
/*!
|
|
* \brief InterfaceImpl::updateBatteryLevel
|
|
* \details Changes the icon of battery state and change Tooltip
|
|
*/
|
|
void InterfaceImpl::updateBatteryLevel()
|
|
{
|
|
if(!m_notiBattery)
|
|
return;
|
|
|
|
if(m_currentBatteryStateForId.isEmpty())
|
|
{
|
|
setToolTip();
|
|
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage()));
|
|
return;
|
|
}
|
|
int firstBatteryState = m_currentBatteryStateForId.value(0).batteryPercent() / 20;
|
|
int secondBatteryState = m_currentBatteryStateForId.value(1).batteryPercent() / 20;
|
|
|
|
if(m_currentBatteryStateForId.values().length() == 2)
|
|
{
|
|
setToolTip(firstBatteryState, secondBatteryState);
|
|
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(firstBatteryState, secondBatteryState)));
|
|
}
|
|
else if(m_currentBatteryStateForId.values().length() == 1)
|
|
{
|
|
if(m_currentBatteryStateForId.first().batteryPort() == 0)
|
|
{
|
|
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(firstBatteryState, 99)));
|
|
setToolTip(firstBatteryState, 99);
|
|
}
|
|
else if(m_currentBatteryStateForId.first().batteryPort() == 1)
|
|
{
|
|
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(99,secondBatteryState)));
|
|
setToolTip(99,secondBatteryState);
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace NmeaManagement
|