Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+390
@@ -0,0 +1,390 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for NotificationManangement
|
||||
*
|
||||
* Created by Mike Lennart Wille, ESZS, 2025-06-17
|
||||
*/
|
||||
|
||||
#include "nom_edit_gui_plugin.h"
|
||||
#include "nom_dialog.h"
|
||||
|
||||
#include <LtsNotification/lts_notification.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
#include <LtsWidgets/lts_events.h>
|
||||
#include <NotificationManagement/nom_dtc.h>
|
||||
#include <Services/AreaEffectSimulation/aes_operator_rights.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionMatch>
|
||||
|
||||
namespace NotificationManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session) { return std::make_shared<InterfaceImpl>(session); }
|
||||
|
||||
const QString InterfaceImpl::s_nomEditGuiPlugin = QStringLiteral("nomEditGuiPlugin");
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Nom.Edit"))
|
||||
, m_noti(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
{
|
||||
qApp->installEventFilter(this);
|
||||
}
|
||||
|
||||
InterfaceImpl::~InterfaceImpl() {}
|
||||
|
||||
int InterfaceImpl::isDeleted(const NomNotification &data) const
|
||||
{
|
||||
int operatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
for (const auto &addr : data.recipientIds())
|
||||
{
|
||||
if (addr.addressType() == AddressType_def::Operator)
|
||||
{
|
||||
if (addr.addressId() != operatorId)
|
||||
continue;
|
||||
if (addr.isDeleted())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InterfaceImpl::showNotificationList(int notificationId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "showNotificationList notificationId=" << notificationId;
|
||||
initNotificationSystem();
|
||||
}
|
||||
|
||||
bool InterfaceImpl::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
// DEBUG_LOG(m_logger) << "event->type()" << event->type();
|
||||
|
||||
if (watched == qApp && !event->isAccepted() && event->type() == LtsWidgets::LtsLinkEvent::eventTypeId())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "0 event->type()" << event->type();
|
||||
}
|
||||
|
||||
auto ev = static_cast<LtsWidgets::LtsLinkEvent *>(event);
|
||||
|
||||
if (event->type() == LtsWidgets::LtsLinkEvent::eventTypeId())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "event->type() == LtsWidgets::LinkEvent::eventId()";
|
||||
DEBUG_LOG(m_logger) << "ev->url()=" << ev->url().toString();
|
||||
|
||||
const auto ev = static_cast<LtsWidgets::LtsLinkEvent *>(event);
|
||||
const auto identifier = ev->url().path().mid(1);
|
||||
int id = 0;
|
||||
|
||||
QRegularExpression re(QStringLiteral("(\\d+)$"));
|
||||
QRegularExpressionMatch match = re.match(identifier);
|
||||
if (match.hasMatch())
|
||||
{
|
||||
id = match.captured(1).toInt();
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "identifier=" << identifier << ", id=" << id;
|
||||
if(ev->url().host().toLower() == QStringLiteral("notificationack") && id > 0)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ack";
|
||||
ack(m_nomNotifications.value(m_nomNotifications.value(id).id())); //hier eigentlich nicht
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "ev->url().host()=" << ev->url().host();
|
||||
if (ev->url().host().toLower() == s_nomEditGuiPlugin.toLower())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ev->url().host()=" << ev->url().host();
|
||||
|
||||
m_session->addWidget(onShowNotificationManagementDialog(nullptr), menuGroup(), QStringLiteral("NotificationEdit"), LtsWidgets::LayoutArea::eDialogTab);
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void InterfaceImpl::onNotificationChanged(const NotificationManagement::NomNotification ¬i, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onNotificationChanged title=" << noti.title()
|
||||
<< ", content =" << noti.content()
|
||||
<< ", args.size=" << noti.contentArgs().size()
|
||||
<< ", modType=" << modType;
|
||||
if (noti.exerciseId() != m_session->exerciseId())
|
||||
return;
|
||||
|
||||
if (!isMyMessage(noti.recipientIds()))
|
||||
return;
|
||||
const QString notiIdent = QCoreApplication::translate("Notification", noti.title().c_str()) + QString::number(noti.id());
|
||||
|
||||
if (isDeleted(noti))
|
||||
{
|
||||
m_unreadMessages.remove(noti.id());
|
||||
updateUnreadCount();
|
||||
if (m_session->baseLayout()->messageIdentifierExists(notiIdent))
|
||||
{
|
||||
m_session->baseLayout()->removeQueuedMessage(notiIdent);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NomNotification localNoti = noti;
|
||||
|
||||
QString content = QCoreApplication::translate("Notification", localNoti.content().c_str());
|
||||
|
||||
for (const std::string& arg : noti.contentArgs())
|
||||
{
|
||||
// .arg() ersetzt immer den kleinsten freien Platzhalter (z. B. zuerst %1, dann %2)
|
||||
content = content.arg(QString::fromStdString(arg));
|
||||
DEBUG_LOG(m_logger) << ".arg() ersetzt immer den kleinsten freien Platzhalter"
|
||||
<< ", arg=" << arg
|
||||
<< ", content=" << content;
|
||||
}
|
||||
|
||||
localNoti.content(content.toStdString());
|
||||
|
||||
m_nomNotifications.insert(noti.id(), localNoti);
|
||||
|
||||
// When it's low, dont add it to the unread_message
|
||||
if (noti.processed() <= 0 && (modType == DataModification::eAdded || modType == DataModification::eModified))
|
||||
{
|
||||
|
||||
if (m_unreadMessages.contains(noti.id()) && noti.priority() < Priority::Normal)
|
||||
{
|
||||
m_unreadMessages.remove(noti.id());
|
||||
}
|
||||
|
||||
if (!m_unreadMessages.contains(noti.id()))
|
||||
{
|
||||
m_unreadMessages.insert(noti.id());
|
||||
|
||||
QString content = QString::fromStdString(localNoti.content());
|
||||
|
||||
for (const std::string& arg : noti.contentArgs()) {
|
||||
content = content.arg(QString::fromStdString(arg));
|
||||
}
|
||||
|
||||
QMap<QString, QString> linkMap;
|
||||
parseContent(content, linkMap);
|
||||
// now replace the strings
|
||||
QMapIterator<QString, QString> it(linkMap);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
|
||||
content = content.replace(QStringLiteral("[%1](%2)").arg(it.value(), it.key()), QStringLiteral("<a href='%1'>%2</a>").arg(it.key(), it.value()));
|
||||
}
|
||||
const QString openMessageLink(QStringLiteral("OpenMessages"));
|
||||
const LtsWidgets::LtsNotificationBox::MessageType messageType = static_cast<LtsWidgets::LtsNotificationBox::MessageType>(noti.messageType().underlying());
|
||||
// If Priority is High add Notification for every user
|
||||
if (noti.priority() == Priority::High)
|
||||
{
|
||||
m_session->baseLayout()->showMessage(
|
||||
QCoreApplication::translate("Notification", noti.title().c_str()),
|
||||
content,
|
||||
messageType,
|
||||
[this, linkMap, noti](const QString &link)
|
||||
{
|
||||
Q_UNUSED(link)
|
||||
// Nothing to do here for now as links are already taken care of inside the Message see: LtsBaseLayoutWidget::showMessage
|
||||
// do not try to ack already acked notification
|
||||
if (!noti.processed())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ack";
|
||||
ack(noti); //hier nach neustart?
|
||||
}
|
||||
},
|
||||
true,
|
||||
notiIdent);
|
||||
m_session->baseLayout()->installEventFilter(this);
|
||||
}
|
||||
else if (noti.priority() == Priority::Highest)
|
||||
{
|
||||
// if the proirity is highest parse the links and send them directly without user input
|
||||
for (const auto &link : linkMap.keys())
|
||||
{
|
||||
auto *event = new LtsWidgets::LtsLinkEvent(QUrl(link), m_session->baseLayout());
|
||||
event->setAccepted(false);
|
||||
DEBUG_LOG(m_logger) << "Post event" << event << " " << event->url().toString();
|
||||
QApplication::postEvent(qApp, event); // receive link events by overriding eventFilter of your *parented* QObject class
|
||||
}
|
||||
// do not try to ack already acked notification
|
||||
if (!noti.processed())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ack";
|
||||
ack(noti); //oder hier?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((noti.processed() && (modType == DataModification::eModified)) || modType == DataModification::eRemoved)
|
||||
{
|
||||
m_unreadMessages.remove(noti.id()); // deletes nothing if there is no message with that id :)
|
||||
// remove notification from user
|
||||
if (m_session->baseLayout()->messageIdentifierExists(notiIdent))
|
||||
{
|
||||
m_session->baseLayout()->removeQueuedMessage(notiIdent);
|
||||
}
|
||||
}
|
||||
|
||||
updateUnreadCount();
|
||||
// recalc notification icon counter
|
||||
}
|
||||
|
||||
void InterfaceImpl::onReadReceiptReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Got ReadReceiptReply " << replyObject.translated() << " add info: " << replyObject.additionalInfo();
|
||||
}
|
||||
|
||||
void InterfaceImpl::initNotificationSystem()
|
||||
{
|
||||
if (m_noti != nullptr)
|
||||
return;
|
||||
|
||||
m_noti = m_session->createNotification(QStringLiteral("nom.Notifications"));
|
||||
|
||||
m_noti->setIcon(QIcon(QStringLiteral("icon:messages_notif.svg")));
|
||||
m_noti->setToolTip(tr("No unread notifications"));
|
||||
m_noti->setAction(
|
||||
[this]()
|
||||
{ m_session->addWidget(onShowNotificationManagementDialog(nullptr), menuGroup(), QStringLiteral("NotificationEdit"), LtsWidgets::LayoutArea::eDialogTab); });
|
||||
|
||||
connect(m_dtc.get(), &NotificationManagement::Interface::Dtc::nomNotificationChanged, this, &InterfaceImpl::onNotificationChanged, Qt::UniqueConnection);
|
||||
|
||||
m_dtc->enableNomNotification();
|
||||
}
|
||||
|
||||
void InterfaceImpl::updateUnreadCount()
|
||||
{
|
||||
if (m_noti == nullptr)
|
||||
return;
|
||||
|
||||
m_noti->setCount(m_unreadMessages.count());
|
||||
m_noti->setToolTip(tr("%Ln unread message(s)", "", m_unreadMessages.count()));
|
||||
}
|
||||
|
||||
bool InterfaceImpl::parseContent(const QString &contentString, QMap<QString, QString> &retMap)
|
||||
{
|
||||
if (contentString.isEmpty())
|
||||
return false;
|
||||
|
||||
// Mark Down Regex lookig for String between ]( and ) eg: TestLingk "[LinkName](http::blahblah)"
|
||||
QRegularExpression regLink(QStringLiteral("(?<=\\]\\()(.*?)(?=\\))"));
|
||||
QRegularExpressionMatch matchLink = regLink.match(contentString);
|
||||
QRegularExpression regDesc(QStringLiteral("(?<=\\[)(.*?)(?=\\]\\()"));
|
||||
QRegularExpressionMatch matchDesc = regDesc.match(contentString);
|
||||
|
||||
QRegularExpressionMatchIterator itLink = regLink.globalMatch(contentString);
|
||||
QRegularExpressionMatchIterator itDesc = regDesc.globalMatch(contentString);
|
||||
while (itLink.hasNext() && itDesc.hasNext())
|
||||
{
|
||||
QString linkRef = itLink.next().captured();
|
||||
QString linkDesc = itDesc.next().captured();
|
||||
if (!linkRef.isEmpty() && !linkDesc.isEmpty())
|
||||
{
|
||||
retMap.insert(linkRef, linkDesc);
|
||||
}
|
||||
}
|
||||
|
||||
return retMap.size();
|
||||
}
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
{
|
||||
LtsWidgets::PluginData plData;
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Notifications");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:messages_notif.svg"));
|
||||
plData.identifier = QLatin1String("NotificationEdit");
|
||||
plData.operatorRight = OperatorRights::NotificationEdit;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
|
||||
plData.createWidgetFunc = [this](QWidget *parent) { return onShowNotificationManagementDialog(parent); };
|
||||
ret.append(plData);
|
||||
}
|
||||
// Init System without button
|
||||
initNotificationSystem();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getDtc<NotificationManagement::DataInterface>(m_dtc))
|
||||
return false;
|
||||
if (!m_session->getFtc<NotificationManagement::DataInterface>(m_ftc))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InterfaceImpl::clearInterfaces()
|
||||
{
|
||||
m_dtc = nullptr;
|
||||
m_ftc = nullptr;
|
||||
m_dtcOpm = nullptr;
|
||||
}
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowNotificationManagementDialog(QWidget *parent)
|
||||
{
|
||||
auto *dialog = new NotificationManagementDialog(m_session, menuGroup(), parent);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
void InterfaceImpl::ack(const NotificationManagement::NomNotification ¬ification)
|
||||
{
|
||||
|
||||
ReadReceipt request;
|
||||
int operatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
|
||||
int workstationId = LtsSessionData::LtsSessionData::getInstance()->getWorkstationId();
|
||||
for (const auto &addr : notification.recipientIds())
|
||||
{
|
||||
if ((addr.addressType() == AddressType_def::Operator && addr.addressId() == operatorId)
|
||||
|| (addr.addressType() == AddressType_def::Workstation && addr.addressId() == workstationId))
|
||||
{
|
||||
request.addressId(addr.id());
|
||||
break;
|
||||
}
|
||||
}
|
||||
request.operatorId(operatorId);
|
||||
request.workstationId(workstationId);
|
||||
|
||||
request.notificationIds({notification.id()});
|
||||
request.processed(!notification.processed());
|
||||
DEBUG_LOG(m_logger) << "m_ftc->readReceipt ";
|
||||
m_ftc->readReceiptRequest(request, this);
|
||||
}
|
||||
|
||||
bool InterfaceImpl::isMyMessage(const std::vector<Address> &recipents)
|
||||
{
|
||||
|
||||
if (recipents.empty())
|
||||
return false;
|
||||
|
||||
using Iter = std::vector<Address>::const_iterator;
|
||||
Iter it = recipents.begin();
|
||||
while (it != recipents.end())
|
||||
{
|
||||
|
||||
if (it->addressType() == AddressType::Operator && it->addressId() == LtsSessionData::LtsSessionData::getInstance()->getOperatorId())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (it->addressType() == AddressType::Workstation && it->addressId() == LtsSessionData::LtsSessionData::getInstance()->getWorkstationId())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace NotificationManagement
|
||||
Reference in new issue
Block a user