/** * @RDE_HEADER@ * HMI Plugin for ParticipantManagement - Participant OrgChart Dialog * $Id$ * $HeadURL$ * $Author$ * Created by Patric Karwat, SLSE, 2017-04-07 */ #include "participant_org_chart.h" #include "ui_participant_org_chart.h" #include #include #include #include #include #include namespace ParticipantManagement { inline bool compareState(const StateInformation &a, const StateInformation &b) { if (a.stateTime() != b.stateTime()) return a.stateTime() < b.stateTime(); return a.vulnerabilityState() < b.vulnerabilityState(); } LtsParticipantsOrgChart::LtsParticipantsOrgChart(QWidget *parent) : QWidget(parent) , m_partyId(-1) , m_useSymData(true) , m_isMenuEnabled(false) , m_isDragEnabled(false) , m_channel(nullptr) , m_notifier(nullptr) , m_dtc(nullptr) , m_asbItc(nullptr) , m_ui(new Ui::LtsParticipantsOrgChart) , m_logger(getLogger("LtsParticipantsOrgChart")) { m_ui->setupUi(this); } LtsParticipantsOrgChart::~LtsParticipantsOrgChart() { delete m_ui; } bool LtsParticipantsOrgChart::init(const std::shared_ptr &dtc , const std::shared_ptr &asbIfc , bool useSymData , bool isMenuEnabled , bool isDragEnabled) { if (!dtc || !asbIfc) return false; m_dtc = dtc; m_asbItc = asbIfc; m_useSymData = useSymData; m_isMenuEnabled = isMenuEnabled; m_isDragEnabled = isDragEnabled; m_channel = new QWebChannel(this); m_notifier = new WebNofitifier(this); connect(m_notifier, &WebNofitifier::edit, this, &LtsParticipantsOrgChart::startEdit); connect(m_notifier, &WebNofitifier::remove, this, &LtsParticipantsOrgChart::startDelete); connect(m_notifier, &WebNofitifier::dbClick, this, &LtsParticipantsOrgChart::startDBClick); connect(m_notifier, &WebNofitifier::movedParticipant, this, &LtsParticipantsOrgChart::movedParticipant); connect(m_notifier, &WebNofitifier::newHierarchy, this, &LtsParticipantsOrgChart::gotNewHierarchy); connect(this, &LtsParticipantsOrgChart::sendUpdateString, m_notifier, &WebNofitifier::onSetUpdateString, Qt::QueuedConnection); m_ui->wevOrgChart->setAcceptDrops(true); m_ui->wevOrgChart->page()->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true); m_ui->wevOrgChart->page()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); m_ui->wevOrgChart->page()->settings()->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard, true); m_ui->wevOrgChart->page()->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, true); m_ui->wevOrgChart->page()->settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); auto readFiles = { QLatin1String(":/jquery-3.1.0.min.js"), QLatin1String(":/qwebchannel.js"), QLatin1String(":/jquery.orgchart.js"), QLatin1String(":/scripts.js") }; QFile readFile; //start with loading files. for (const auto &file : readFiles) { readFile.setFileName(file); if (!readFile.open(QIODevice::ReadOnly)) return false; m_scriptString.append(QString::fromUtf8(readFile.readAll())); readFile.close(); } //Now we read the basic html file readFile.setFileName(QLatin1String(":/start.html")); if (!readFile.open(QIODevice::ReadOnly)) return false; m_html.append(QString::fromUtf8(readFile.readAll())); readFile.close(); //so now load orgFrom Dtc //loadParty(partyId); m_ui->wevOrgChart->page()->setWebChannel(m_channel); connect(m_ui->wevOrgChart, &QWebEngineView::loadFinished, this, [=](bool suc) { QString url = m_ui->wevOrgChart->page()->url().toString(); if (url == QLatin1String("about:blank")) { return; } if (suc) { //if (m_ui->wevOrgChart->page()->findText(QLatin1String() ); // return; if (m_dataSource.size() > 10) m_ui->wevOrgChart->page()->runJavaScript(m_dataSource + m_scriptString); } }); m_channel->registerObject(QLatin1String("webNotifier"), m_notifier); m_notifier->setJsonString(QLatin1String("test")); m_ui->wevOrgChart->page()->setHtml(m_html); return true; } void LtsParticipantsOrgChart::loadParty(int partyId) { TRACE_LOG(m_logger) << "loadParty " << partyId; m_partyId = partyId; const QMap participantMap = m_dtc->participants(); ParticipantManagement::Participant root; QString preDefThing = QLatin1String(" var datascource = "); //first get all participants from Party for (const ParticipantManagement::Participant &part : participantMap) { if (part.isDeleted() || part.partyId() != m_partyId) continue; if (part.superiorId() == 0) { root = part; break; } } if (root.inferiorIds().size() == 0) { m_dataSource = preDefThing; m_ui->wevOrgChart->reload(); return; } // transfer to m_participantOrgChart_MimeDataHelper: delete m_participantOrgChart_MimeDataHelper.data(); m_participantOrgChart_MimeDataHelper.clear(); m_participantOrgChart_MimeDataHelper = new ParticipantOrgChart_MimeDataHelper(this); if (!m_participantOrgChart_MimeDataHelper->init(m_dtc, AdvancedSymbology::SymbolDictionary::defaultSymbologyType(), true)) { ERROR_LOG(m_logger) << LOGFUNCTION << " init failed"; return; } connect(m_participantOrgChart_MimeDataHelper.data(), &ParticipantOrgChart_MimeDataHelper::finished, this, &LtsParticipantsOrgChart::onParticipantOrgChart_MimeDataHelperFinished); m_participantOrgChart_MimeDataHelper->run(root.id(), false, AdvancedSymbology::roleToRole<>(m_dtc->party(m_partyId).role()), QColor::fromRgb(QRgb(m_dtc->party(m_partyId).color())), m_useSymData); } void LtsParticipantsOrgChart::onParticipantOrgChart_MimeDataHelperFinished() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; QString preDefThing = QLatin1String(" var datascource = "); const QJsonObject &json = m_participantOrgChart_MimeDataHelper->getMimeDataResult(); preDefThing.append(QString::fromUtf8(QJsonDocument(json).toJson())); m_dataSource = preDefThing; QString isMenuEnabled = QLatin1String("; var isMenuEnabled = "); QString isDragEnabled = QLatin1String("; var isDragEnabled = "); QString menuDelete = QLatin1String("; var menuDelete = '") + tr("Delete") + QLatin1String("';"); QString menuEdit = QLatin1String("; var menuEdit = '") + tr("Edit") + QLatin1String("';"); QString unitName = QLatin1String("; var unitName = '") + tr("Unit") + QLatin1String("';"); isMenuEnabled.append(m_isMenuEnabled ? QLatin1String("true;") : QLatin1String("false;")); isDragEnabled.append(m_isDragEnabled ? QLatin1String("true;") : QLatin1String("false;")); m_dataSource.append(isMenuEnabled); m_dataSource.append(isDragEnabled); m_dataSource.append(menuEdit); m_dataSource.append(menuDelete); m_dataSource.append(unitName); //only reload when page is ready if (m_ui->wevOrgChart->page()->url().toString() != QLatin1String("about:blank")) { m_ui->wevOrgChart->reload(); } TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } bool LtsParticipantsOrgChart::loadTemplate(int templateRootId) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; ParticipantManagement::TemplateParticipant root = m_dtc->templateParticipant(templateRootId); if (m_ui->wevOrgChart->page()->url().toString() == QLatin1String("about:blank")) { m_ui->wevOrgChart->page()->setHtml(QString()); m_ui->wevOrgChart->page()->setHtml(m_html); } // transfer to m_participantOrgChart_MimeDataHelper: m_participantOrgChart_MimeDataHelper.clear(); m_participantOrgChart_MimeDataHelper = new ParticipantOrgChart_MimeDataHelper(this); if (!m_participantOrgChart_MimeDataHelper->init(m_dtc, AdvancedSymbology::SymbolDictionary::defaultSymbologyType(), false)) { ERROR_LOG(m_logger) << LOGFUNCTION << " init failed"; return false; } connect(m_participantOrgChart_MimeDataHelper.data(), &ParticipantOrgChart_MimeDataHelper::finished, this, &LtsParticipantsOrgChart::onParticipantOrgChart_MimeDataHelperFinished); m_participantOrgChart_MimeDataHelper->run(root.templateId(), false, AdvancedSymbology::roleToRole<>(m_dtc->party(m_partyId).role()), QColor::fromRgb(QRgb(m_dtc->party(m_partyId).color())), false); return true; } void LtsParticipantsOrgChart::updateParticipant(int participantId) { QSharedPointer helper = QSharedPointer(new ParticipantOrgChart_MimeDataHelper()); if (!helper->init(m_dtc, AdvancedSymbology::SymbolDictionary::defaultSymbologyType(), true)) { ERROR_LOG(m_logger) << LOGFUNCTION << " init failed"; return; } m_participantOrgChart_MimeDataHelperMap[participantId] = helper; // update will cancel/destroy the former one.. :-) connect(helper.data(), &ParticipantOrgChart_MimeDataHelper::finished, this, &LtsParticipantsOrgChart::onSingleParticipantOrgChart_MimeDataHelperFinished); helper->run(participantId, true, AdvancedSymbology::roleToRole<>(m_dtc->party(m_partyId).role()), QColor::fromRgb(QRgb(m_dtc->party(m_partyId).color())), m_useSymData); } void LtsParticipantsOrgChart::onSingleParticipantOrgChart_MimeDataHelperFinished() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; ParticipantOrgChart_MimeDataHelper *senderWatcher = qobject_cast(sender()); if (!senderWatcher) { ERROR_LOG(m_logger) << LOGFUNCTION << " sender failed"; return; } const int participantId = senderWatcher->getParticipantId(); const QJsonObject &newJson = senderWatcher->getMimeDataResult(); DEBUG_LOG(m_logger) << LOGFUNCTION << " sendUpdateString:" << " participantId=" << participantId; emit sendUpdateString(participantId, newJson); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void LtsParticipantsOrgChart::sendToOrgChart(int participantId, const QJsonObject &json) { emit sendUpdateString(participantId, json); } void LtsParticipantsOrgChart::getWholeHierarchy() { m_notifier->getWholeHierarchy(); } //Notifier WebNofitifier::WebNofitifier(QObject *parent) : QObject(parent) , m_currentJsonString(QString()) , m_updateString(QString()) , m_updateTimer(new QTimer(this)) { connect(m_updateTimer, &QTimer::timeout, this, &WebNofitifier::onTimerTick); } void WebNofitifier::startEdit(const QString &data) { emit edit(data); } void WebNofitifier::startDelete(const QString &data) { emit remove(data); } void WebNofitifier::doMoveChanged() { emit movedParticipant(); } void WebNofitifier::startDBClick(int id) { emit dbClick(id); } void WebNofitifier::gotHierarchy(const QString &data) { emit newHierarchy(data); } void WebNofitifier::onSetUpdateString(int ddsId, const QJsonObject &updateString) { m_dataToChange.insert(ddsId, QString::fromUtf8(QJsonDocument(updateString).toJson())); if (!m_updateTimer->isActive()) m_updateTimer->start(277); } void WebNofitifier::onTimerTick() { const QString dataToSend = m_dataToChange.take(m_dataToChange.firstKey()); if (m_dataToChange.isEmpty()) m_updateTimer->stop(); emit updateStringChanged(dataToSend); } void WebNofitifier::getWholeHierarchy() { emit getHierarchy(); } void WebNofitifier::setJsonString(const QString &string) { m_currentJsonString = string; emit jsonStringChanged(string); } }