Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+82
View File
@@ -0,0 +1,82 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# Created by Mike Wille, SLSE, 2017-03-31
#
SET(flm_explorer_gui_SRCS
flm_explorer_gui_plugin.cpp
flm_dialog.cpp
flm_dialog_model_folder.cpp
flm_dialog_model_file.cpp
flm_edit_folder.cpp
flm_edit_file_content.cpp
flm_set_properties_dialog.cpp
flm_preview_file_dialog.cpp
flm_preview_playback.cpp
flm_get_content.cpp
flm_get_content_async.cpp
flm_office_integration.cpp
settings.cpp
RatioAwareLabel.cpp
TopicEditor/topic_editor.cpp
HQReports/flm_hq_report_edit.cpp
HQReports/flm_hq_report_model.cpp
HQReports/flm_hq_report_json_parser.cpp
HQReports/flm_hq_report_converter.cpp
HQReports/flm_hq_report_symbol_creator.cpp
HQReports/flm_hq_report_symbol_concrete_creators.cpp
HQReports/flm_hq_report_symbol_factory.cpp
)
NGL_WRAP_UI(flm_explorer_gui_SRCS
flm_dialog.ui
flm_edit_folder.ui
flm_edit_file_content.ui
flm_set_properties_dialog.ui
flm_preview_file_dialog.ui
flm_preview_playback.ui
TopicEditor/topic_editor.ui
HQReports/flm_hq_report_edit.ui
)
INSTALL_SHARED_FILES(flm_explorer_gui_SRCS
FILES office.ica
DESTINATION "IcaScripts"
WS
)
NGL_ADD_LIBRARY(WS FlmExplorerGuiPlugin MODULE ${flm_explorer_gui_SRCS})
NGL_TARGET_LINK_LIBRARIES(FlmExplorerGuiPlugin
NGLLogger
FlmExplorerGuiPluginInterface
FlmDataPluginInterface
OpmDataPluginInterface
ExmDataPluginInterface
PpmDataPluginInterface
Qt5::Widgets
LtsDataView
LtsUtilsGuiDds
LtsUtilsGuiConnectDialog
LtsUtilsCore
LtsUtilsSettings
LtsSession
LtsSessionData
LtsWidgets
LtsPrinting
nglwidgets
ngltools
nglsettings
TopicEditorBase
LtsScriptTimeline # TopicEditor
PreGuiScriptCommon # TopicEditor => Text Topic => TopicDesigner
PpmGuiPartyPluginInterface
situationMapGeometryModel
advancedSymbology
svcAesCommon
)
NGL_INSTALL_TARGET(FlmExplorerGuiPlugin)
@@ -0,0 +1,230 @@
#include "flm_hq_report_converter.h"
#include <FileManagement/flm_ftc.h>
#include <FileManagement/flm_ftc_types.h>
#include <FileManagement/flm_data_plugin_interface.h>
#include <Symbology/sidc_builder_base.h>
#include <Symbology/sidc_codec.h>
#include <Symbology/symbol_dictionary.h>
#include <SymbologyXML/symbol_types.h>
#include <GeometryModel/geometry_model_factory.h>
#include <LtsUtilsCore/dds_vector.h>
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <ParticipantManagement/ppm_data_plugin_interface.h>
#include <AreaEffectSimulation/Utils/polygons.h>
namespace FileManagement
{
FlmHqReportConverter::FlmHqReportConverter() : m_logger(getLogger("HQReportConverter"))
{
connect(this, &FlmHqReportConverter::allRequestsFinished,
this, &FlmHqReportConverter::onRequestsFinished);
}
bool FlmHqReportConverter::init(LtsSession::LtsSession *session, int currentPartyId)
{
if (session == nullptr)
{
ERROR_LOG(m_logger) << "Got invalid session";
return false;
}
m_session = session;
if (!m_session->getDtc<DataInterface>(m_flmDtc))
{
ERROR_LOG(m_logger) << "Could not get FLM Dtc.";
return false;
}
if (!m_session->getFtc<DataInterface>(m_flmFtc))
{
ERROR_LOG(m_logger) << "Could not get FLM Ftc.";
return false;
}
if (!session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
{
ERROR_LOG(m_logger) << "Could not get PPM Dtc.";
return false;
}
if (!m_flmFtc->enableFileContentModify())
{
ERROR_LOG(m_logger) << "Could enable fileContentModify.";
return false;
}
m_flmDtc->enableFileContent();
m_flmDtc->enableFolder();
if (m_geometryModel != nullptr)
{
delete m_geometryModel;
m_geometryModel = nullptr;
}
m_geometryModel = SituationMap::GeometryModelFactory::singleton()->create();
m_partyId = currentPartyId;
return true;
}
void FlmHqReportConverter::addHqToPlanIds(const QMap<int, QList<int>> &hqToPlanIds)
{
for (auto it = hqToPlanIds.constBegin(); it != hqToPlanIds.constEnd(); ++it)
{
m_hqToPlanIds[it.key()].append(it.value());
}
}
void FlmHqReportConverter::processCollectedHqs()
{
for (auto it = m_hqToPlanIds.constBegin(); it != m_hqToPlanIds.constEnd(); ++it)
{
m_pendingRequests += it.value().size();
}
for (auto it = m_hqToPlanIds.constBegin(); it != m_hqToPlanIds.constEnd(); ++it)
{
int planId = it.key();
const QList<int> &reportIds = it.value();
// Request file content for each HqReport
for (int id : reportIds)
{
DEBUG_LOG(m_logger) << "Request File with ID: " << id << " from plan with ID: " << planId;
FileManagement::GetFileContentDataRequest request(id);
m_flmFtc->getFileContentDataRequest(request, this);
}
}
}
void FlmHqReportConverter::createGeometryFromReport(const HqReportData &data)
{
m_symbolFactory.build(data.art, data, m_geometryModel);
}
void FlmHqReportConverter::checkIfAllFinished()
{
if (m_pendingRequests <= 0) emit allRequestsFinished();
}
void FlmHqReportConverter::onGetFileContentDataReply(
const FileManagement::GetFileContentDataReply &reply)
{
m_pendingRequests--;
if (reply.errorString().size() > 0)
{
ERROR_LOG(m_logger) << "Got onGetFileContentDataReply error: " << reply.errorString();
return;
}
int id = static_cast<int>(reply.id());
int planId = -1;
DEBUG_LOG(m_logger) << "Reply File with ID: " << id << " from plan with ID: " << planId;
INFO_LOG(m_logger) << "Got reply with id " << id << " and errorString " << reply.errorString();
QByteArray fileContent = QByteArray(reinterpret_cast<const char*>(reply.content().data()), reply.content().size());
FlmHqReportJsonParser m_parser = FlmHqReportJsonParser();
HqReportData data = m_parser.parse(fileContent);
data.contentFileId = id;
DEBUG_LOG(m_logger) << "Party: " << m_partyId << " has Color: "<< QColor::fromRgb(QRgb(m_ppmDtc->party(m_partyId).color())).value();
data.partyColor = QColor::fromRgb(QRgb(m_ppmDtc->party(m_partyId).color()));
for (auto it = m_hqToPlanIds.constBegin(); it != m_hqToPlanIds.constEnd(); ++it)
{
if (it.value().contains(id))
{
planId = it.key();
break;
}
}
m_convertedHqToPlanIds[planId].append(data);
DEBUG_LOG(m_logger) << "Content size: " << reply.content().size();
checkIfAllFinished();
}
void FlmHqReportConverter::onFileContentModifyReply(const Core::FunctionReplyObject &reply)
{
DEBUG_LOG(m_logger) << "Got FileContentModify Reply: " << reply.translated();
if (reply.error())
{
ERROR_LOG(m_logger) << "Error while insert HX Message: " << reply.translated()
<< ", error: " << reply.error();
}
}
void FlmHqReportConverter::onFileContentRemoveReply(const Core::FunctionReplyObject &reply)
{
DEBUG_LOG(m_logger) << "Got FileContentRemove Reply: " << reply.translated();
if (reply.error())
{
ERROR_LOG(m_logger) << "Error while insert HX Message: " << reply.translated()
<< ", error: " << reply.error();
}
}
void FlmHqReportConverter::onRequestsFinished()
{
DEBUG_LOG(m_logger) << "ALL REQUESTS FINISHED";
for (auto it = m_convertedHqToPlanIds.constBegin(); it != m_convertedHqToPlanIds.constEnd(); ++it)
{
int planId = it.key();
const QList<HqReportData> &reportDatas = it.value();
for (auto &reportData : reportDatas)
{
DEBUG_LOG(m_logger) << "createGeometryFromReport :" << reportData.art;
createGeometryFromReport(reportData);
}
const FileManagement::FileContent &flc = m_flmDtc->fileContent(planId);
FileManagement::FileContentModifyRequest data;
DEBUG_LOG(m_logger) << "FILE CONTENT: " << flc.name() << " " << flc.folderId();
data.id(flc.id());
data.name(flc.name());
data.isTemplate(false);
data.isHidden(false);
data.folderId(flc.folderId());
data.fileStatus(FileManagement::FileStatus::Valid);
data.fileCategory(FileManagement::FileCategory::Exercise);
data.fileType(FileManagement::FileType::TacticalPlan);
data.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
data.lastModified(QDateTime::currentMSecsSinceEpoch());
data.content(LtsUtils::convert<std::vector<uint8_t>>(m_geometryModel->toByteArray()));
data.exerciseId(m_session->exerciseId());
m_flmFtc->fileContentModifyRequest(data, this);
m_geometryModel->clearModel();
}
}
} // namespace FileManagement
@@ -0,0 +1,80 @@
#pragma once
#include <FileManagement/logger.h>
#include <GeometryModel/geometry_model.h>
#include "flm_hq_report_json_parser.h"
#include "flm_hq_report_symbol_factory.h"
namespace LtsSession
{
class LtsSession;
}
namespace FileManagement
{
namespace Interface
{
class Dtc;
class Ftc;
} // namespace Interface
class FlmHqReportConverter : public QObject,
public Interface::Ftc::GetFileContentDataReplyHandler,
public Interface::Ftc::FileContentModifyReplyHandler,
public Interface::Ftc::FileContentRemoveReplyHandler
{
Q_OBJECT
public:
FlmHqReportConverter();
~FlmHqReportConverter() = default;
bool init(LtsSession::LtsSession *session, int currentPartyId);
/**
* @brief add hqToPlanIds to m_hqToPlanIds
* @param const QMap<int, QList<int>> &hqToPlanIds -> <planId, QList<HqIds>>
*/
void addHqToPlanIds(const QMap<int, QList<int>> &hqToPlanIds);
/**
* @brief Iterate and send GetFileContentDataRequest to get File Information HQ
*/
void processCollectedHqs();
/**
* @brief create GeometryModel from HQ Report
* @param {data} HQ Report Data
*/
void createGeometryFromReport(const HqReportData &data);
private:
void checkIfAllFinished();
protected:
void onGetFileContentDataReply(const FileManagement::GetFileContentDataReply &reply) override;
void onFileContentModifyReply(const Core::FunctionReplyObject &reply) override;
void onFileContentRemoveReply(const Core::FunctionReplyObject &reply) override;
public slots:
void onRequestsFinished();
signals:
/**
* @brief checks if all getFileContentDataRequests are finished
*/
void allRequestsFinished();
private:
LOGGER_T m_logger;
LtsSession::LtsSession *m_session{nullptr};
std::shared_ptr<Interface::Dtc> m_flmDtc;
std::shared_ptr<Interface::Ftc> m_flmFtc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
SituationMap::GeometryModel *m_geometryModel{nullptr};
QList<SituationMap::GeometryModel::Node> m_planNodes;
SymbolFactory m_symbolFactory;
int m_partyId;
int m_pendingRequests{0};
QMap<int, QList<int>> m_hqToPlanIds; /// Map<planIds, QList<HQMessageId>>
QMap<int, int> m_hqToPlanIdsLookup; /// Map<planIds, HQMessageId> for Lookup
QMap<int, QList<HqReportData>> m_convertedHqToPlanIds; /// Map<planIds, QList<convertedHqMessage>>
}; // class FlmHqReportConverter
} // namespace FileManagement
@@ -0,0 +1,387 @@
#include "flm_hq_report_edit.h"
#include "flm_hq_report_model.h"
#include "ui_flm_hq_report_edit.h"
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <QDateTime>
#include <QInputDialog>
#include <SituationMap/GeometryModel/geometry_model.h>
#include <SituationMap/GeometryModel/geometry_model_factory.h>
#include <LtsUtils/LtsUtilsCore/dds_vector.h>
namespace FileManagement
{
HQReportEdit::HQReportEdit(const QString &menuGroup, QWidget *parent)
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
, m_ui(new Ui::HQReportEdit)
, m_logger(getLogger("HQReportEdit"))
, m_menuGroup(menuGroup)
{
m_ui->setupUi(this);
m_buttonBox->getButton(LtsWidgets::DialogButton::Add)->setText(tr("New Plan"));
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &HQReportEdit::onCreateNewPlanClicked);
connect(m_ui->pbShift, &QPushButton::clicked, this, &HQReportEdit::onShiftClicked);
setOnlineHelpFilename(QStringLiteral("Situation-HQReport"));
}
HQReportEdit::~HQReportEdit() { delete m_ui; }
bool HQReportEdit::init(LtsSession::LtsSession *session, int partyId)
{
if (session == nullptr)
{
ERROR_LOG(m_logger) << "Got invalid session";
return false;
}
m_session = session;
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> partyCboInterface;
if (!m_session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(partyCboInterface))
{
ERROR_LOG(m_logger) << "Could not get Party Combobox Interface.";
return false;
}
if (!partyCboInterface->fillPartyComboBox(m_ui->cboParties) || m_ui->cboParties->count() == 0)
{
ERROR_LOG(m_logger) << "Could not fill Parties.";
return false;
}
if (!m_session->getDtc<DataInterface>(m_flmDtc))
{
ERROR_LOG(m_logger) << "Could not get FLM Dtc.";
return false;
}
if (!m_session->getFtc<DataInterface>(m_flmFtc))
{
ERROR_LOG(m_logger) << "Could not get FLM Ftc.";
return false;
}
if (!m_flmFtc->enableFileContentModify())
{
ERROR_LOG(m_logger) << "Could enable fileContentModify.";
return false;
}
// init models
qDeleteAll(m_hqModels);
m_hqModels.clear();
qDeleteAll(m_planModels);
m_planModels.clear();
for (int index = 0; index < m_ui->cboParties->count(); ++index)
{
const int partyId = m_ui->cboParties->itemData(index).toInt();
const int partyFolderId = m_flmDtc->getPartyFolderId(m_session->exerciseId(), partyId);
FlmHQReportModel *planModel = new FlmHQReportModel(m_ui->listViewPlan);
if (!planModel->init(m_session, partyFolderId, FileType::inner_enum::TacticalPlan))
{
WARNING_LOG(m_logger) << "Could not init planModel for partyId " << partyId;
delete planModel;
planModel = nullptr;
continue;
}
const int hqReportFolderId = m_flmDtc->findFolder(partyFolderId, QStringLiteral("Messages"));
FlmHQReportModel *hqReportModel = new FlmHQReportModel(m_ui->listViewMessage);
if (!hqReportModel->init(m_session, hqReportFolderId, FileType::inner_enum::AdlerJson))
{
WARNING_LOG(m_logger) << "Could not init hqReportModel for partyId " << partyId;
delete planModel;
planModel = nullptr;
delete hqReportModel;
hqReportModel = nullptr;
continue;
}
connect(planModel, &FlmHQReportModel::dataAddedOrRemoved, this, &HQReportEdit::slotChangesMade);
m_planModels.insert(partyId, planModel);
m_hqModels.insert(partyId, hqReportModel);
}
// configure listViewPlan
m_ui->listViewPlan->setDragDropMode(QAbstractItemView::DropOnly);
m_ui->listViewPlan->setDefaultDropAction(Qt::CopyAction);
m_ui->listViewPlan->setDropIndicatorShown(true);
// configure listViewMessage
m_ui->listViewMessage->setDragDropMode(QAbstractItemView::DragOnly);
m_ui->listViewMessage->setDefaultDropAction(Qt::CopyAction);
m_ui->listViewMessage->setDropIndicatorShown(true);
onPartyChanged();
if (!m_flmFtc->enableFileContentModify())
{
ERROR_LOG(m_logger) << "Could enable fileContentModify.";
return false;
}
// init models
qDeleteAll(m_hqModels);
m_hqModels.clear();
qDeleteAll(m_planModels);
m_planModels.clear();
for (int index = 0; index < m_ui->cboParties->count(); ++index)
{
const int partyId = m_ui->cboParties->itemData(index).toInt();
createModels(partyId);
}
// configure listViewPlan
m_ui->listViewPlan->setDragDropMode(QAbstractItemView::DropOnly);
m_ui->listViewPlan->setDefaultDropAction(Qt::MoveAction);
m_ui->listViewPlan->setDropIndicatorShown(true);
// configure listViewMessage
m_ui->listViewMessage->setDragDropMode(QAbstractItemView::DragOnly);
m_ui->listViewMessage->setDefaultDropAction(Qt::MoveAction);
m_ui->listViewMessage->setDropIndicatorShown(true);
onPartyChanged();
connect(m_ui->cboParties, qOverload<int>(&QComboBox::currentIndexChanged), this, &HQReportEdit::onPartyChanged);
int partyIndex = m_ui->cboParties->findData(partyId); // in case of notification: onPartyChanged() is called when index changes
m_ui->cboParties->setCurrentIndex(partyIndex < 0 ? 0 : partyIndex);
return true;
}
void HQReportEdit::createModels(const int partyId)
{
const int partyFolderId = m_flmDtc->getPartyFolderId(m_session->exerciseId(), partyId);
if (partyFolderId == 0)
{
WARNING_LOG(m_logger) << "No partyFolderId found for partyId " << partyId;
return;
}
const int hqReportFolderId = m_flmDtc->findFolder(partyFolderId, QStringLiteral("Messages"));
auto *planModel = new FlmHQReportModel(m_ui->listViewPlan);
if (!planModel->init(m_session, partyFolderId, FileType::inner_enum::TacticalPlan))
{
WARNING_LOG(m_logger) << "Could not init planModel for partyId " << partyId;
delete planModel;
return;
}
auto *hqReportModel = new FlmHQReportModel(m_ui->listViewMessage);
if (!hqReportModel->init(m_session, hqReportFolderId, FileType::inner_enum::AdlerJson))
{
WARNING_LOG(m_logger) << "Could not init hqReportModel for partyId " << partyId;
delete planModel;
delete hqReportModel;
return;
}
connect(planModel, &FlmHQReportModel::dataAddedOrRemoved, this, &HQReportEdit::slotChangesMade);
m_planModels.insert(partyId, planModel);
m_hqModels.insert(partyId, hqReportModel);
}
bool HQReportEdit::apply()
{
QMap<int, QList<int>> allHqToPlanIds;
for (auto it = m_planModels.begin(); it != m_planModels.end(); ++it)
{
QMap<int, QList<int>> hqToPlanIds = it.value()->getHQToPlan(); // <planId, hq-message ids>
for (auto planId : hqToPlanIds.keys())
{
allHqToPlanIds[planId].append(hqToPlanIds[planId]);
it.value()->clearMovedData();
}
}
const int currentPartyId = m_ui->cboParties->currentData().toInt();
FlmHqReportConverter *hqRepConv = new FlmHqReportConverter();
if (hqRepConv->init(m_session, currentPartyId))
{
DEBUG_LOG(m_logger) << "Add HQ to Converter";
hqRepConv->addHqToPlanIds(allHqToPlanIds);
hqRepConv->processCollectedHqs();
}
return true;
}
void HQReportEdit::retranslate() { translate(m_ui, tr("HQ Report")); }
void HQReportEdit::onPartyChanged(int index)
{
Q_UNUSED(index);
const int currentPartyId = m_ui->cboParties->currentData().toInt();
if (!m_planModels.contains(currentPartyId) || !m_hqModels.contains(currentPartyId))
{
INFO_LOG(m_logger) << "Models for party" << currentPartyId << "not found. Attempting to create...";
createModels(currentPartyId);
}
QAbstractItemModel *hqModel = m_hqModels.value(currentPartyId, nullptr);
QAbstractItemModel *planModel = m_planModels.value(currentPartyId, nullptr);
if (m_ui->listViewMessage->selectionModel())
{
m_ui->listViewMessage->selectionModel()->disconnect(this);
}
if (m_ui->listViewPlan->selectionModel())
{
m_ui->listViewPlan->selectionModel()->disconnect(this);
}
m_ui->listViewMessage->setModel(hqModel);
m_ui->listViewPlan->setModel(planModel);
if (hqModel && planModel)
{
connect(m_ui->listViewMessage->selectionModel(), &QItemSelectionModel::selectionChanged, this, &HQReportEdit::onSelectionChanged);
connect(m_ui->listViewPlan->selectionModel(), &QItemSelectionModel::selectionChanged, this, &HQReportEdit::onSelectionChanged);
}
else
{
ERROR_LOG(m_logger) << "Failed to switch to party" << currentPartyId << ": Models still missing.";
}
}
void HQReportEdit::onCreateNewPlanClicked()
{
bool ok = false;
QString planName = QInputDialog::getText(this, tr("Enter Plan name"), tr("Name:"), QLineEdit::Normal, QString(), &ok);
if (!ok)
{
DEBUG_LOG(m_logger) << "No name for new plan entered.";
return;
}
FlmHQReportModel *planModel = static_cast<FlmHQReportModel *>(m_ui->listViewPlan->model());
if (planModel == nullptr)
{
ERROR_LOG(m_logger) << "Could not create plan --> no plan model present.";
return;
}
SituationMap::GeometryModel *geometryModel = SituationMap::GeometryModelFactory::singleton()->create();
if (geometryModel == nullptr)
{
ERROR_LOG(m_logger) << "Could not create plan --> not possible to create GeometryModel.";
return;
}
if (m_session == nullptr)
{
ERROR_LOG(m_logger) << "Could not create plan --> not possible to create GeometryModel.";
return;
}
FileManagement::FileContentModifyRequest data;
data.name(planName.toStdString());
data.isTemplate(false);
data.isHidden(false);
data.folderId(planModel->folderId());
data.fileStatus(FileManagement::FileStatus::Valid);
data.fileCategory(FileManagement::FileCategory::Exercise);
data.fileType(FileManagement::FileType::TacticalPlan);
data.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
data.lastModified(QDateTime::currentMSecsSinceEpoch());
data.content(LtsUtils::convert<std::vector<uint8_t>>(geometryModel->toByteArray()));
data.exerciseId(m_session->exerciseId());
m_flmFtc->fileContentModifyRequest(data,
[this](const Core::FunctionReplyObject &reply)
{
if (reply.error())
{
const QString errorMessage = tr("Could not save plan: %1").arg(QString::fromStdString(reply.str()));
ERROR_LOG(m_logger) << errorMessage;
new LtsWidgets::LtsMessageDialogNew(this, errorMessage, tr("Save failed"));
}
});
}
void HQReportEdit::onSelectionChanged(const QItemSelection &, const QItemSelection &)
{
m_ui->pbShift->setEnabled(m_ui->listViewMessage->selectionModel()->hasSelection() && m_ui->listViewPlan->selectionModel()->hasSelection());
}
void HQReportEdit::onShiftClicked()
{
const int currentPartyId = m_ui->cboParties->currentData().toInt();
FlmHQReportModel *messageModel = m_hqModels.value(currentPartyId);
FlmHQReportModel *planModel = m_planModels.value(currentPartyId);
if (messageModel == nullptr || planModel == nullptr)
return;
const QModelIndex currentMessageIndex = m_ui->listViewMessage->currentIndex();
if (!currentMessageIndex.isValid())
return;
QMimeData *mimeData = messageModel->mimeData({currentMessageIndex});
if (mimeData == nullptr)
return;
if (!planModel->dropMimeData(mimeData, Qt::CopyAction, -1, 0, m_ui->listViewPlan->currentIndex()))
return;
m_ui->listViewPlan->viewport()->update();
}
} // namespace FileManagement
@@ -0,0 +1,65 @@
/**
* @RDE_HEADER@
* FileManagement - HQ Meldung dialog
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include "flm_hq_report_converter.h"
#include <FileManagement/logger.h>
#include <LtsWidgets/lts_dialog.h>
class QListView;
namespace Ui
{
class HQReportEdit;
}
namespace LtsSession
{
class LtsSession;
}
namespace FileManagement
{
namespace Interface
{
class Dtc;
class Ftc;
} // namespace Interface
class FlmHQReportModel;
class HQReportEdit : public LtsWidgets::LtsDialog
{
Q_OBJECT
public:
explicit HQReportEdit(const QString &menuGroup, QWidget *parent = nullptr);
~HQReportEdit();
bool init(LtsSession::LtsSession *session, int partyId = -1);
void createModels(const int partyId);
bool apply() override;
void retranslate() override;
private Q_SLOTS:
void onPartyChanged(int index = 0);
void onCreateNewPlanClicked();
void onSelectionChanged(const QItemSelection &, const QItemSelection &);
void onShiftClicked();
private:
Ui::HQReportEdit *m_ui;
LOGGER_T m_logger;
QString m_menuGroup;
LtsSession::LtsSession *m_session{nullptr};
QHash<int, FlmHQReportModel *> m_hqModels;
QHash<int, FlmHQReportModel *> m_planModels;
std::shared_ptr<Interface::Dtc> m_flmDtc;
std::shared_ptr<Interface::Ftc> m_flmFtc;
};
} // namespace FileManagement
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>HQReportEdit</class>
<widget class="QWidget" name="HQReportEdit">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>536</width>
<height>332</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="2">
<widget class="QListView" name="listViewPlan"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="lblPlans">
<property name="text">
<string>Plans</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblMessages">
<property name="text">
<string>Messages</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QListView" name="listViewMessage"/>
</item>
<item row="1" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lblParty">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Party:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboParties">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="pbShift">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,85 @@
#include "flm_hq_report_json_parser.h"
namespace FileManagement
{
FlmHqReportJsonParser::FlmHqReportJsonParser() : m_logger(getLogger("HQReportParser")) {}
HqReportData FlmHqReportJsonParser::parse(const QByteArray &data)
{
DEBUG_LOG(m_logger) << "START PARSING";
QJsonDocument doc = QJsonDocument::fromJson(data);
QJsonObject obj = doc.object();
HqReportData report;
report.art = obj[QStringLiteral("art")].toString();
report.name = obj[QStringLiteral("name")].toString();
if ( obj.contains(QStringLiteral("meldungsnummer")))
report.number = obj[QStringLiteral("meldungsnummer")].toInt();
if ((obj.contains(QStringLiteral("bis"))) &&
(obj.contains((QStringLiteral("ab")))))
{
report.bis = parseHqReportTime(obj[QStringLiteral("bis")].toObject());
report.ab = parseHqReportTime(obj[QStringLiteral("ab")].toObject());
}
if ((obj.contains(QStringLiteral("koordinaten"))) &&
(obj[QStringLiteral("koordinaten")].isArray()))
{
QJsonArray coordsArray = obj[QStringLiteral("koordinaten")].toArray();
for (const QJsonValue &value : coordsArray)
{
QPointF coord;
QJsonObject coordsObj = value.toObject();
coord.setX(coordsObj[QStringLiteral("longitude")].toDouble() * LtsCoordTrans::deg2rad());
coord.setY(coordsObj[QStringLiteral("latitude")].toDouble() * LtsCoordTrans::deg2rad());
report.koordinaten.push_back(coord);
}
}
if ((obj.contains(QStringLiteral("mittelpunkt"))) &&
(obj[QStringLiteral("mittelpunkt")].isObject()))
{
QPointF center;
QJsonObject coordsObj = obj[QStringLiteral("mittelpunkt")].toObject();
center.setX(coordsObj[QStringLiteral("longitude")].toDouble() * LtsCoordTrans::deg2rad());
center.setY(coordsObj[QStringLiteral("latitude")].toDouble() * LtsCoordTrans::deg2rad());
report.mittelpunkt = center;
}
if (obj.contains(QStringLiteral("radius"))) report.radius = obj[QStringLiteral("radius")].toInt();
if (obj.contains(QStringLiteral("linkerNachbar")))
report.linkerNachbar = obj[QStringLiteral("linkerNachbar")].toString();
if (obj.contains(QStringLiteral("rechterNachbar")))
report.rechterNachbar = obj[QStringLiteral("rechterNachbar")].toString();
return report;
}
QString FlmHqReportJsonParser::parseHqReportTime(const QJsonObject &obj)
{
const int year = obj[QStringLiteral("jahr")].toInt();
const int minutes = obj[QStringLiteral("minuten")].toInt();
const int month = obj[QStringLiteral("monat")].toInt();
const int seconds = obj[QStringLiteral("sekunden")].toInt();
const int day = obj[QStringLiteral("tag")].toInt();
const int hour = obj[QStringLiteral("stunden")].toInt();
const QDate date(year, month, day);
const QTime time(hour, minutes, seconds);
const QDateTime dt(date, time);
return dt.toString(QStringLiteral("dd.MM.yyyy HH:mm:ss"));
}
} // namespace FileManagement
@@ -0,0 +1,64 @@
#pragma once
#include <FileManagement/flm_ftc.h>
#include <FileManagement/flm_ftc_types.h>
#include <FileManagement/logger.h>
#include <GeometryModel/geometry_model.h>
#include <GeometryModel/geometry_model_factory.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <QHash>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QPointF>
#include <QString>
#include <optional>
#include <string>
#include <vector>
namespace FileManagement
{
using namespace SituationMap;
struct HqCoordinates
{
double latitude;
double longitude;
};
struct HqReportData
{
int contentFileId;
QColor partyColor;
int maxGipfel{-1};
int radius{-1};
QString ab;
QString art;
QString bis;
QString name;
int number;
QString truppenteil;
QString linkerNachbar;
QString rechterNachbar;
QVector<QPointF> koordinaten;
QPointF mittelpunkt;
};
class FlmHqReportJsonParser
{
public:
FlmHqReportJsonParser();
/**
* @brief parses HQ Report to JSON
* @param {data} HQ Report Data as QByteArray
*/
HqReportData parse(const QByteArray &data);
/**
* @brief create GeometryModel from HQ Report
* @param {obj} Time Data as JSON from HQ Report
*/
QString parseHqReportTime(const QJsonObject &obj);
private:
LOGGER_T m_logger;
}; // class FlmHqReportJsonParser
} // namespace FileManagement
@@ -0,0 +1,294 @@
#include "flm_hq_report_model.h"
#include <LtsSession/lts_session.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
namespace FileManagement
{
FlmHQReportModel::FlmHQReportModel(QObject *parent)
: QAbstractListModel(parent)
, m_logger(getLogger("HQReportModel"))
{
}
bool FlmHQReportModel::init(LtsSession::LtsSession *session, int contentFolderId, const FileType &fileType)
{
if (!session)
{
ERROR_LOG(m_logger) << "Got invalid Session";
return false;
}
if (!session->getDtc<FileManagement::DataInterface>(m_flmDtc))
{
ERROR_LOG(m_logger) << "Could not get FLM Dtc";
return false;
}
m_contentFolderId = contentFolderId;
m_fileType = fileType;
m_flmDtc->enableFileContent();
m_flmDtc->waitForHistoricalDataFileContent(3000);
m_flmDtc->fileContents([this](const FileContent &content){onFileContentChanged(content, DataModification::eAdded);});
connect(m_flmDtc.get(), &Interface::Dtc::fileContentChanged, this, &FlmHQReportModel::onFileContentChanged);
return true;
}
int FlmHQReportModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return m_data.count();
}
QVariant FlmHQReportModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role == Qt::DisplayRole)
return createText(index.row());
return QVariant();
}
Qt::ItemFlags FlmHQReportModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
if (!index.isValid())
return defaultFlags;
return defaultFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}
Qt::DropActions FlmHQReportModel::supportedDropActions() const
{
return Qt::CopyAction;
}
Qt::DropActions FlmHQReportModel::supportedDragActions() const
{
return Qt::CopyAction;
}
QStringList FlmHQReportModel::mimeTypes() const
{
QStringList types;
types << mimeType;
return types;
}
bool FlmHQReportModel::removeRows(int row, int count, const QModelIndex &parent)
{
if (parent.isValid() || row < 0 || row >= m_data.size() || (row + count) > m_data.size())
return false;
beginRemoveRows(QModelIndex(), row, row + count - 1);
for (int i = 0; i < count; ++i)
m_data.removeAt(row);
endRemoveRows();
return true;
}
QMimeData *FlmHQReportModel::mimeData(const QList<QModelIndex> &indexes) const
{
QMimeData *mimeData = new QMimeData();
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
for (const QModelIndex &index : indexes)
{
if (index.isValid())
{
HQData md = m_data.at(index.row());
stream << md.id << md.name;// Serialize your custom metadata to QByteArray
}
}
mimeData->setData(mimeType, encodedData);
return mimeData;
}
bool FlmHQReportModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
Q_UNUSED(row)
Q_UNUSED(column)
if (!parent.isValid() || !data->hasFormat(mimeType) || action != Qt::CopyAction)
return false;
QByteArray encodedData = data->data(mimeType);
QDataStream stream(&encodedData, QIODevice::ReadOnly);
while (!stream.atEnd())
{
HQData md;
stream >> md.id >> md.name;
addMovedData(parent.row(), md);
}
emit dataAddedOrRemoved();
return true;
}
bool FlmHQReportModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(row)
Q_UNUSED(column)
if (!parent.isValid() ||
!data->hasFormat(mimeType) ||
action != Qt::CopyAction ||
parent.row() < 0 ||
parent.row() >= m_data.size())
return false;
QByteArray encodedData = data->data(mimeType);
QDataStream stream(&encodedData, QIODevice::ReadOnly);
const HQData &currentData = m_data.at(parent.row());
if (!m_movedData.contains(currentData.id))
return true;
const QList<HQData> &movedDataListForCurrentData = m_movedData.value(currentData.id);
while (!stream.atEnd())
{
HQData movedData;
stream >> movedData.id >> movedData.name;
if (movedDataListForCurrentData.contains(movedData)) // we do not allow double entries
return false;
}
return true;
}
void FlmHQReportModel::addHQReportData(const HQData &data)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_data.append(data);
endInsertRows();
}
void FlmHQReportModel::deleteHQReportData(const HQData &data)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
endInsertRows();
const int zeile = m_data.indexOf(data);
if (zeile == -1) {
return;
}
beginRemoveRows(QModelIndex(), zeile, zeile);
m_data.removeAt(zeile);
endRemoveRows();
return;
}
void FlmHQReportModel::onFileContentChanged(const FileContent &content, DataModification modType)
{
HQData data;
data.id = content.id();
data.name = QString::fromStdString(content.name());
if (content.folderId() != m_contentFolderId || content.fileType() != m_fileType)
return;
if (content.fileStatus() == FileStatus::Deleted) {
if (modType == DataModification::eModified || modType == DataModification::eAdded) {
deleteHQReportData(data);
}
} else if (modType == DataModification::eAdded) {
addHQReportData(data);
}
}
int FlmHQReportModel::folderId() const
{
return m_contentFolderId;
}
QMap<int, QList<int>> FlmHQReportModel::getHQToPlan() const
{
QMap<int, QList<int>> hqToPlan;
for (auto it = m_movedData.constBegin(); it != m_movedData.constEnd(); ++it)
{
const QList<HQData> &movedData = it.value();
QList<int> hqIds;
hqIds.reserve(movedData.size());
for (const HQData &currentData : movedData)
hqIds.append(currentData.id);
hqToPlan.insert(it.key(), hqIds);
}
return hqToPlan;
}
void FlmHQReportModel::clearMovedData()
{
m_movedData.clear();
emit dataAddedOrRemoved();
emit dataChanged(index(0, 0), index(rowCount() - 1, 0));
}
QString FlmHQReportModel::createText(int dataIndex) const
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " dataIndex: " << dataIndex;
if (dataIndex < 0 || dataIndex >= m_data.size())
return QString();
const HQData &data = m_data.at(dataIndex);
if (!m_movedData.contains(data.id))
{
DEBUG_LOG(m_logger) << "No moved data for " << data.name;
return data.name;
}
const QList<HQData> &movedData = m_movedData.value(data.id);
QStringList movedDataNames;
movedDataNames.reserve(movedData.size());
for (const HQData &currentMovedData : movedData)
movedDataNames.append(currentMovedData.name);
return QString(QStringLiteral("%1 (%2)")).arg(data.name).arg(movedDataNames.join(QLatin1Char(',')));
}
void FlmHQReportModel::addMovedData(int dataIndex, const HQData &movedData)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " dataIndex: " << dataIndex << ", movedData.id: " << movedData.id << ", movedData.name: " << movedData.name;
if (dataIndex < 0 || dataIndex >= m_data.size())
return;
const HQData &data = m_data.at(dataIndex);
if (!m_movedData.contains(data.id))
m_movedData.insert(data.id, QList<HQData>());
m_movedData[data.id].append(movedData);
}
}
@@ -0,0 +1,97 @@
#pragma once
#include <QObject>
#include <QAbstractListModel>
#include <QStandardItemModel>
#include <QList>
#include <QMimeData>
#include <QByteArray>
#include <QDataStream>
#include <FileManagement/flm_enums.hpp>
#include <FileManagement/logger.h>
#include <LtsUtilsCore/data_modification_enum.h>
namespace FileManagement
{
class FileContent;
namespace Interface
{
class Dtc;
}
}
namespace LtsSession
{
class LtsSession;
}
namespace FileManagement
{
struct HQData
{
int id;
QString name;
bool operator==(const HQData &other) const
{
return id == other.id &&
name == other.name;
}
};
class FlmHQReportModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit FlmHQReportModel(QObject *parent = nullptr);
bool init(LtsSession::LtsSession *session, int contentFolderId, const FileManagement::FileType &fileType);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
Qt::DropActions supportedDropActions() const override;
Qt::DropActions supportedDragActions() const override;
QStringList mimeTypes() const override;
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;
QMimeData *mimeData(const QList<QModelIndex> &indexes) const override;
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
void addHQReportData(const HQData &data);
void deleteHQReportData(const HQData &data);
int folderId() const;
QMap<int, QList<int>> getHQToPlan() const;
void clearMovedData();
private:
QString createText(int dataIndex) const;
void addMovedData(int dataIndex, const HQData &movedData);
private Q_SLOTS:
void onFileContentChanged(const FileContent &content, DataModification modType);
Q_SIGNALS:
void dataAddedOrRemoved();
private:
QList<HQData> m_data;
QMap<int, QList<HQData>> m_movedData;
const QString mimeType = QStringLiteral("application/x-custom-hqdata");
int m_contentFolderId {-1};
FileManagement::FileType m_fileType;
std::shared_ptr<FileManagement::Interface::Dtc> m_flmDtc;
LOGGER_T m_logger;
};
}//namespace FileManagement
Q_DECLARE_METATYPE(FileManagement::HQData)
@@ -0,0 +1,97 @@
#include "flm_hq_report_symbol_concrete_creators.h"
#include <ParticipantManagement/ppm_dtc.h>
#include <ParticipantManagement/ppm_ftc.h>
#include <ParticipantManagement/ppm_ftc_types.h>
namespace FileManagement {
void LineCreator::create(const HqReportData &data, SituationMap::GeometryModel *model) const
{
QList<QPair<GeometryModel::Attribute, QVariant>> symbolAttributes;
const int userData = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
symbolAttributes.reserve(2);
symbolAttributes.append(QPair<GeometryModel::Attribute, QVariant>(GeometryModel::Attribute::SIDC, QVariant(SymbolCreator::convertBaseSymbolToSidic(m_baseSymbol))));
symbolAttributes.append(QPair<GeometryModel::Attribute, QVariant>(GeometryModel::Attribute::SIDC_Color, QVariant(data.partyColor)));
const SituationMap::GeometryModel::Node &node = model->addPrimitive(GeometryModel::PrimitiveType::DictionarySymbol,
data.koordinaten.toList(),
symbolAttributes,
userData);
QString text = QStringLiteral("Name: %1 Gültig ab: %2 Gültig bis: %3 ").arg(data.name)
.arg(data.ab)
.arg(data.bis);
model->setNodeDisplayName(node, text);
symbolAttributes.clear();
}
void AreaCreator::create(const HqReportData &data, SituationMap::GeometryModel *model) const
{
QList<QPair<GeometryModel::Attribute, QVariant>> symbolAttributes;
const int userData = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
symbolAttributes.reserve(2);
symbolAttributes.append(QPair<GeometryModel::Attribute, QVariant>(GeometryModel::Attribute::SIDC, QVariant(SymbolCreator::convertBaseSymbolToSidic(m_baseSymbol))));
symbolAttributes.append(QPair<GeometryModel::Attribute, QVariant>(GeometryModel::Attribute::SIDC_Color, QVariant(data.partyColor)));
const SituationMap::GeometryModel::Node &node = model->addPrimitive(GeometryModel::PrimitiveType::DictionarySymbol,
data.koordinaten.toList(),
symbolAttributes,
userData);
QString text = QStringLiteral("Name: %1 Gültig ab: %2 Gültig bis: %3 ").arg(data.art + QStringLiteral(" ") + data.name)
.arg(data.ab)
.arg(data.bis);
model->setNodeDisplayName(node, text);
symbolAttributes.clear();
}
void PointCreator::create(const HqReportData &data, SituationMap::GeometryModel *model) const
{
QList<QPair<GeometryModel::Attribute, QVariant>> symbolAttributes;
const int userData = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
symbolAttributes.reserve(2);
symbolAttributes.append(QPair<GeometryModel::Attribute, QVariant>(GeometryModel::Attribute::SIDC, QVariant(SymbolCreator::convertBaseSymbolToSidic(m_baseSymbol))));
symbolAttributes.append(QPair<GeometryModel::Attribute, QVariant>(GeometryModel::Attribute::SIDC_Color, QVariant(data.partyColor)));
const SituationMap::GeometryModel::Node &node = model->addPrimitive(GeometryModel::PrimitiveType::DictionarySymbol,
data.koordinaten.toList(),
symbolAttributes,
userData);
QString text = QStringLiteral("Name: %1 Gültig ab: %2 Gültig bis: %3").arg(data.name)
.arg(data.ab)
.arg(data.bis);
model->setNodeDisplayName(node, text);
symbolAttributes.clear();
}
void AreaCircularCreator::create(const HqReportData &data, SituationMap::GeometryModel *model) const
{
QList<QPair<GeometryModel::Attribute, QVariant>> symbolAttributes;
const int userData = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
symbolAttributes.reserve(2);
symbolAttributes.append(QPair<GeometryModel::Attribute, QVariant>(GeometryModel::Attribute::SIDC, QVariant(SymbolCreator::convertBaseSymbolToSidic(m_baseSymbol))));
symbolAttributes.append(QPair<GeometryModel::Attribute, QVariant>(GeometryModel::Attribute::SIDC_Color, QVariant(data.partyColor)));
const SituationMap::GeometryModel::Node &node = model->addPrimitive(GeometryModel::PrimitiveType::DictionarySymbol,
{data.mittelpunkt},
symbolAttributes,
userData);
QString text = QStringLiteral("Name: %1 Gültig ab: %2 Gültig bis: %3 Radius: %4").arg(data.name)
.arg(data.ab)
.arg(data.bis)
.arg(data.radius);
model->setNodeDisplayName(node, text);
}
} // namespace FileManagement
@@ -0,0 +1,55 @@
#pragma once
#include <QString>
#include <LtsSession/lts_session_data.h>
#include <Utils/polygons.h>
#include <Symbology/sidc_codec.h>
#include <Symbology/sidc_builder_base.h>
#include "flm_hq_report_symbol_creator.h"
namespace FileManagement
{
class LineCreator : public SymbolCreator
{
public:
LineCreator(const QString &baseSymbol) : m_baseSymbol(baseSymbol) {}
void create(const HqReportData &data, SituationMap::GeometryModel *model) const override;
private:
QString m_baseSymbol;
}; // class LineCreator
class AreaCreator : public SymbolCreator
{
public:
AreaCreator(const QString &baseSymbol) : m_baseSymbol(baseSymbol) {}
void create(const HqReportData &data, SituationMap::GeometryModel *model) const override;
private:
QString m_baseSymbol;
}; // class AreaCreator
class AreaCircularCreator : public SymbolCreator
{
public:
AreaCircularCreator(const QString &baseSymbol) : m_baseSymbol(baseSymbol) {}
void create(const HqReportData &data, SituationMap::GeometryModel *model) const override;
private:
QString m_baseSymbol;
}; // class AreaCircular
class PointCreator : public SymbolCreator
{
public:
PointCreator(const QString &baseSymbol) : m_baseSymbol(baseSymbol) {}
void create(const HqReportData &data, SituationMap::GeometryModel *model) const override;
private:
QString m_baseSymbol;
}; // class PointCreator
} // namespace FileManagement
@@ -0,0 +1,13 @@
#include "flm_hq_report_symbol_creator.h"
namespace FileManagement
{
QString SymbolCreator::convertBaseSymbolToSidic(const QString &baseSymbolCode)
{
QString encodedBaseCode = AdvancedSymbology::SidcCodec::encodeBaseSymbolCode(AdvancedSymbology::SymbologyType::APP6D, baseSymbolCode);
const QString sidic = AdvancedSymbology::SidcBuilderBase::baseSymbolCodeToSidc(encodedBaseCode);
return sidic;
}
}
@@ -0,0 +1,20 @@
#pragma once
#include "flm_hq_report_json_parser.h"
#include <Symbology/sidc_codec.h>
#include <Symbology/sidc_builder_base.h>
#include <Utils/polygons.h>
namespace FileManagement
{
class SymbolCreator
{
public:
virtual ~SymbolCreator() = default;
virtual void create(const HqReportData &data, SituationMap::GeometryModel *model) const = 0;
static QString convertBaseSymbolToSidic(const QString &baseSymbolCode);
}; // class SymbolCreator
} // namespace FileManagement
@@ -0,0 +1,84 @@
#include "flm_hq_report_symbol_factory.h"
namespace FileManagement
{
SymbolFactory::SymbolFactory()
{
// Lines
m_normalRegistry.insert(QStringLiteral("AL"), std::make_shared<LineCreator>(QStringLiteral("25141000")));
m_normalRegistry.insert(QStringLiteral("ANL"), std::make_shared<LineCreator>(QStringLiteral("25141100")));
m_normalRegistry.insert(QStringLiteral("CFL"), std::make_shared<LineCreator>(QStringLiteral("25260200")));
m_normalRegistry.insert(QStringLiteral("NFL"), std::make_shared<LineCreator>(QStringLiteral("25240301")));
m_normalRegistry.insert(QStringLiteral("FSSL"), std::make_shared<LineCreator>(QStringLiteral("25260200")));
m_normalRegistry.insert(QStringLiteral("FSCL"), std::make_shared<LineCreator>(QStringLiteral("25260100")));
m_normalRegistry.insert(QStringLiteral("RFL"), std::make_shared<LineCreator>(QStringLiteral("25260500")));
m_normalRegistry.insert(QStringLiteral("VZL"), std::make_shared<LineCreator>(QStringLiteral("25140300")));
m_normalRegistry.insert(QStringLiteral("PL"), std::make_shared<LineCreator>(QStringLiteral("25140300")));
// Points
m_normalRegistry.insert(QStringLiteral("RP"), std::make_shared<PointCreator>(QStringLiteral("25131500")));
m_normalRegistry.insert(QStringLiteral("SP"), std::make_shared<PointCreator>(QStringLiteral("25131600")));
m_normalRegistry.insert(QStringLiteral("PP"), std::make_shared<PointCreator>(QStringLiteral("25131200")));
m_normalRegistry.insert(QStringLiteral("CP"), std::make_shared<PointCreator>(QStringLiteral("25130300")));
// Area
m_normalRegistry.insert(QStringLiteral("AO"), std::make_shared<AreaCreator>(QStringLiteral("25120100")));
m_normalRegistry.insert(QStringLiteral("ATRZ"), std::make_shared<AreaCreator>(QStringLiteral("25150103")));
m_normalRegistry.insert(QStringLiteral("AMA"), std::make_shared<AreaCreator>(QStringLiteral("25150103")));
m_normalRegistry.insert(QStringLiteral("ARA"), std::make_shared<AreaCreator>(QStringLiteral("25120100")));
m_normalRegistry.insert(QStringLiteral("BAA"), std::make_shared<AreaCreator>(QStringLiteral("25271700")));
m_normalRegistry.insert(QStringLiteral("BCA"), std::make_shared<AreaCreator>(QStringLiteral("25271700")));
m_normalRegistry.insert(QStringLiteral("BDRY"), std::make_shared<AreaCreator>(QStringLiteral("25110100")));
m_normalRegistry.insert(QStringLiteral("BHA"), std::make_shared<AreaCreator>(QStringLiteral("25271700")));
m_normalRegistry.insert(QStringLiteral("CAA"), std::make_shared<AreaCreator>(QStringLiteral("25271800")));
m_normalRegistry.insert(QStringLiteral("CFZ"), std::make_shared<AreaCreator>(QStringLiteral("25241401")));
m_normalRegistry.insert(QStringLiteral("CHA"), std::make_shared<AreaCreator>(QStringLiteral("25271800")));
m_normalRegistry.insert(QStringLiteral("CZ"), std::make_shared<AreaCreator>(QStringLiteral("25241301")));
m_normalRegistry.insert(QStringLiteral("EA"), std::make_shared<AreaCreator>(QStringLiteral("25151300")));
m_normalRegistry.insert(QStringLiteral("EZ"), std::make_shared<AreaCreator>(QStringLiteral("25150103"))); // E01562-388
m_normalRegistry.insert(QStringLiteral("FLET"), std::make_shared<AreaCreator>(QStringLiteral("25 140103"))); // E01562-388
m_normalRegistry.insert(QStringLiteral("FLOT"), std::make_shared<AreaCreator>(QStringLiteral("25140103"))); // E01562-388
m_normalRegistry.insert(QStringLiteral("FOAZI"), std::make_shared<AreaCreator>(QStringLiteral("25271900")));
m_normalRegistry.insert(QStringLiteral("FOAZII"), std::make_shared<AreaCreator>(QStringLiteral("25271900")));
m_normalRegistry.insert(QStringLiteral("IZ"), std::make_shared<AreaCreator>(QStringLiteral("25150103"))); // E01562-388
m_normalRegistry.insert(QStringLiteral("LZ"), std::make_shared<AreaCreator>(QStringLiteral("25150103"))); // E01562-388
m_normalRegistry.insert(QStringLiteral("MA"), std::make_shared<AreaCreator>(QStringLiteral("25270800")));
m_normalRegistry.insert(QStringLiteral("NAI"), std::make_shared<AreaCreator>(QStringLiteral("25120200")));
m_normalRegistry.insert(QStringLiteral("OA"), std::make_shared<AreaCreator>(QStringLiteral("25151700")));
m_normalRegistry.insert(QStringLiteral("ROTACA"), std::make_shared<AreaCreator>(QStringLiteral("25150103"))); // E01562-388
m_normalRegistry.insert(QStringLiteral("ROTAHA"), std::make_shared<AreaCreator>(QStringLiteral("25150103"))); // E01562-388
m_normalRegistry.insert(QStringLiteral("ROTARA"), std::make_shared<AreaCreator>(QStringLiteral("25150103"))); // E01562-388
m_normalRegistry.insert(QStringLiteral("ROUTE"), std::make_shared<AreaCreator>(QStringLiteral("25151700")));
m_normalRegistry.insert(QStringLiteral("TAI"), std::make_shared<AreaCreator>(QStringLiteral("25120300")));
m_normalRegistry.insert(QStringLiteral("FEBA"), std::make_shared<AreaCreator>(QStringLiteral("25140400")));
m_normalRegistry.insert(QStringLiteral("MFLD"), std::make_shared<AreaCreator>(QStringLiteral("25270701")));
m_normalRegistry.insert(QStringLiteral("ZOF"), std::make_shared<AreaCreator>(QStringLiteral("25120300")));
m_normalRegistry.insert(QStringLiteral("TAREA"), std::make_shared<AreaCreator>(QStringLiteral("25120300")));
m_normalRegistry.insert(QStringLiteral("FAA"), std::make_shared<AreaCreator>(QStringLiteral("25240201")));
m_normalRegistry.insert(QStringLiteral("NFA"), std::make_shared<AreaCreator>(QStringLiteral("25240301")));
m_normalRegistry.insert(QStringLiteral("RFA"), std::make_shared<AreaCreator>(QStringLiteral("25240401")));
// Areas with radius
m_circularRegistry.insert(QStringLiteral("CFZ"), std::make_shared<AreaCircularCreator>(QStringLiteral("25241403")));
m_circularRegistry.insert(QStringLiteral("CZ"), std::make_shared<AreaCircularCreator>(QStringLiteral("25241303")));
m_circularRegistry.insert(QStringLiteral("FFA"), std::make_shared<AreaCircularCreator>(QStringLiteral("25240303")));
m_circularRegistry.insert(QStringLiteral("NFA"), std::make_shared<AreaCircularCreator>(QStringLiteral("25240303")));
m_circularRegistry.insert(QStringLiteral("RFA"), std::make_shared<AreaCircularCreator>(QStringLiteral("25240403")));
m_circularRegistry.insert(QStringLiteral("FSCL"), std::make_shared<AreaCircularCreator>(QStringLiteral("25240403")));
m_circularRegistry.insert(QStringLiteral("RFL"), std::make_shared<AreaCircularCreator>(QStringLiteral("25240403")));
m_circularRegistry.insert(QStringLiteral("FSSL"), std::make_shared<AreaCircularCreator>(QStringLiteral("25240403")));
m_circularRegistry.insert(QStringLiteral("NFL"), std::make_shared<AreaCircularCreator>(QStringLiteral("25240403")));
}
void SymbolFactory::build(const QString &art, const HqReportData &data, SituationMap::GeometryModel *model)
{
if(m_normalRegistry.contains(art))
{
if(data.radius < 0)
m_normalRegistry[art]->create(data, model);
else
{
if ( m_circularRegistry.contains(art))
m_circularRegistry[art]->create(data, model);
}
}
}
}
@@ -0,0 +1,22 @@
#pragma once
#include <QHash>
#include <QString>
#include <memory>
#include "flm_hq_report_symbol_creator.h"
#include "flm_hq_report_symbol_concrete_creators.h"
namespace FileManagement
{
class SymbolFactory
{
public:
SymbolFactory();
void build(const QString &art, const HqReportData &data, SituationMap::GeometryModel *model);
private:
QHash<QString, std::shared_ptr<SymbolCreator>> m_normalRegistry; /// Map HQ message type(art) to BaseSymbolCode
QHash<QString, std::shared_ptr<SymbolCreator>> m_circularRegistry;
};
}
@@ -0,0 +1,55 @@
/**
* @RDE_HEADER@
* A QLabel that rescales the set pixmap with respect of the current aspect ratio
* $Id: flm_preview_file_dialog.cpp 52224 2020-09-30 12:31:15Z ojog_i $
* $HeadURL: svn://192.168.133.21/TDS/branches/product/iterations/21_01_chaos/Lts/Plugins/FileManagement/Gui/Explorer/flm_preview_file_dialog.cpp $
* $Author: ojog_i $
*
* Created by Mike Wille, SLTE, 2020-03-03
*/
#include "RatioAwareLabel.h"
RatioAwareLabel::RatioAwareLabel(QWidget *parent)
: QLabel(parent)
{
setScaledContents(false);
}
void RatioAwareLabel::setPixmap(const QPixmap &pixmap)
{
m_pixmap = pixmap;
scale();
}
int RatioAwareLabel::heightRatio(int width) const
{
if (m_pixmap.isNull())
return height();
return (m_pixmap.height() * width / m_pixmap.width());
}
QSize RatioAwareLabel::sizeHint() const
{
int w = width();
return QSize(w, heightRatio(w));
}
void RatioAwareLabel::scale()
{
if (m_pixmap.isNull())
return;
QLabel::setPixmap(m_pixmap.scaled(size(), Qt::KeepAspectRatio, Qt::FastTransformation));
}
void RatioAwareLabel::resizeEvent(QResizeEvent *event)
{
QLabel::resizeEvent(event);
scale();
}
+36
View File
@@ -0,0 +1,36 @@
/**
* @RDE_HEADER@
* A QLabel that rescales the set pixmap with respect of the current aspect ratio
* $Id: flm_preview_file_dialog.cpp 52224 2020-09-30 12:31:15Z ojog_i $
* $HeadURL: svn://192.168.133.21/TDS/branches/product/iterations/21_01_chaos/Lts/Plugins/FileManagement/Gui/Explorer/flm_preview_file_dialog.cpp $
* $Author: ojog_i $
*
* Created by Mike Wille, SLTE, 2020-03-03
*/
#pragma once
#include <QLabel>
#include <QObject>
#include <QPixmap>
class RatioAwareLabel : public QLabel
{
public:
RatioAwareLabel(QWidget *parent);
protected:
void resizeEvent(QResizeEvent *event) override;
QSize sizeHint() const override;
public slots:
void setPixmap(const QPixmap &pixmap);
private:
int heightRatio(int width) const;
void scale();
QPixmap m_pixmap;
};
@@ -0,0 +1,525 @@
/**
* @RDE_HEADER@
* Topic Editor for the Situation Topic in the Script Editor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2017-04-04
*/
#include "topic_editor.h"
#include "ui_topic_editor.h"
#include <LtsWidgets/lts_text_edit_dialog.h>
#include <LtsUtilsCore/dds_vector.h>
#include <LtsUtilsCore/dds_vector_to_pixmap.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <Plugins/PresentationManagement/Gui/Script/Common/topic_designer.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <TopicEditorBase/topic_previewer.h>
#include <QInputDialog>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
namespace FileManagement
{
FileTopicEditor::FileTopicEditor(
LtsSession::LtsSession *session, FileContentPreviewPlaybackWidget *previewWidget, const std::shared_ptr<Interface::Ftc> &ftc,
QWidget *parent
)
: TopicEditorBase::TopicEditor(parent)
, m_session(session)
, m_getContent(new FileManagement::GetFileContent(ftc, this))
, m_previewPlaybackWidget(previewWidget)
, m_ui(new Ui::FileTopicEditor)
, m_logger(getLogger("FileManagementTopicEditor"))
{
// init UI
m_ui->setupUi(this);
init(m_ui->widget);
m_ftc = ftc;
m_ui->scrollArea->setWidget(m_previewPlaybackWidget);
connect(m_previewPlaybackWidget, &FileContentPreviewPlaybackWidget::currentPageChanged,
this, &FileTopicEditor::onPageNoChanged);
connect(m_previewPlaybackWidget, &FileContentPreviewPlaybackWidget::rotationChanged,
this, &FileTopicEditor::onRotationChanged);
if (m_ui->pbSetTopicPosition->isEnabled())
m_ui->pbSetTopicPosition->setToolTip(tr("Starts a replay at the time that the topic was positioned.%1").arg(QString())); // same tr as below to save HJL some hassle with the linguist
else
m_ui->pbSetTopicPosition->setToolTip(tr("Starts a replay at the time that the topic was positioned.%1").arg(QStringLiteral(" <b>%1</b>").arg(tr("You need to position the topic on a screen track first to start a preview.", "Sie müssen das Topic auf eine Screen-Spur ziehen, bevor Sie eine Vorschau starten können."))));
connect(m_ui->pbBrowse, &QPushButton::clicked,
this, &FileTopicEditor::onSelectFile);
connect(m_ui->pbEnterText, &QPushButton::clicked,
this, &FileTopicEditor::onEnterText);
connect(m_ui->zoomSlider, &QSlider::valueChanged,
this, &FileTopicEditor::onZoomSliderChanged);
connect(m_ui->sbPageNo, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &FileTopicEditor::onPageNoChanged);
connect(m_ui->sbRotation, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &FileTopicEditor::onRotationChanged);
// connect(m_ui->scrollArea, &QObject::destroyed,
// this, [this]()
// {
// WARNING_LOG(m_logger)<<"==> FileTopicEditor: !!! deleted !!! ScrollArea: "<<m_ui->scrollArea;
// });
// connect(m_previewPlaybackWidget, &QObject::destroyed,
// this, [this]()
// {
// WARNING_LOG(m_logger)<<"==> FileTopicEditor: !!! deleted !!! PreviewPlaybackWidget: "<<m_previewPlaybackWidget;
// });
m_ui->pbSetTopicPosition->setEnabled(false);
#if 0
connect(m_ui->pbSetTopicPosition, &QPushButton::clicked, this, [this]()
{
m_ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
emit signalSetTopicPosition(m_ui->scrollArea, m_topicData.id);
});
#else
{
connect(m_ui->pbSetTopicPosition, &QPushButton::clicked, this, &FileTopicEditor::onPreview);
}
#endif
}
FileTopicEditor::~FileTopicEditor()
{
delete m_ui;
}
///////////////////////////////////////////////////////////////////////////////
// PUBLIC
void FileTopicEditor::updatePreview()
{
setUnchangeable(true);
if (m_userText.isEmpty()) // no user text specified (either not a text topic or a file was selected for text) - use file
{
DEBUG_LOG(m_logger) << "file id = " << m_fileId;
m_fileContent = m_dtc->fileContent(m_fileId);
m_fileName = QString::fromStdString(m_fileContent.name());
m_ui->leFileName->setText(m_fileName);
DEBUG_LOG(m_logger) << "file name = " << m_fileName;
if (m_topicData.topicType == TopicEditorBase::TopicType::Pdf)
{
DEBUG_LOG(m_logger) << "zoom level = " << m_zoomLevel;
m_ui->zoomSlider->setValue(m_zoomLevel);
DEBUG_LOG(m_logger) << "rotation = " << m_rotation;
m_ui->sbRotation->setValue(m_rotation);
const int pageNo = m_pageNo; // QSlider::setRange() emits sliderChanged
m_ui->sbPageNo->setRange(1, m_previewPlaybackWidget->getNumPages());
m_pageNo = pageNo;
DEBUG_LOG(m_logger) << "page no = " << m_pageNo;
m_ui->sbPageNo->setValue(m_pageNo);
m_ui->sbPageNo->setEnabled(true);
m_ui->zoomSlider->setEnabled(true);
m_ui->sbRotation->setEnabled(true);
}
}
else // user text specified
{
m_fileId = 0;
m_ui->leFileName->setText(tr("Custom text"));
}
m_previewPlaybackWidget->setVisible(true);
m_previewPlaybackWidget->init(m_fileContent, m_pageNo, m_zoomLevel / 100., m_rotation, 0, m_userText);
setUnchangeable(false);
}
bool FileTopicEditor::fetchInterfaces()
{
if (!m_session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_guiIfc))
{
ERROR_LOG(m_logger) << "Failed to retrieve Flm ForeignGuiInterface";
return false;
}
if (!m_session->getDtc<FileManagement::DataInterface>(m_dtc))
{
ERROR_LOG(m_logger) << "Failed to retrieve Flm Dtc";
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
// PRIVATE
void FileTopicEditor::updateInternalData()
{
enaDisa();
if (m_topicData.topicType != TopicEditorBase::TopicType::Text)
m_ui->pbEnterText->hide();
if (m_topicData.topicType == TopicEditorBase::TopicType::TacticalPlan)
{
m_ui->pbSetTopicPosition->hide();
m_ui->scrollArea->hide();
}
if (m_topicData.topicType == TopicEditorBase::TopicType::Text ||
m_topicData.topicType == TopicEditorBase::TopicType::Image ||
m_topicData.topicType == TopicEditorBase::TopicType::Pdf)
{
// prepare topic with full size (+ margin) if all are zero
if (m_topicData.x <= 0 && m_topicData.y <= 0 && m_topicData.w <= 0 && m_topicData.h <= 0)
{
m_topicData.x = 0;
m_topicData.y = 0;
m_topicData.h = 0.8;
m_topicData.w = 0.8;
}
}
// init file dialog filter
m_fileTypes.clear();
switch (m_topicData.topicType)
{
case TopicEditorBase::TopicType::Image:
m_fileTypes << FileManagement::FileType_def::Jpg << FileManagement::FileType_def::Png;
break;
case TopicEditorBase::TopicType::Pdf:
m_fileTypes << FileManagement::FileType_def::Pdf;
break;
case TopicEditorBase::TopicType::Text:
m_fileTypes << FileManagement::FileType_def::Text << FileManagement::FileType_def::EvaluationSchema;
break;
case TopicEditorBase::TopicType::Xml:
m_fileTypes << FileManagement::FileType_def::Xml;
break;
case TopicEditorBase::TopicType::TacticalPlan:
m_fileTypes << FileManagement::FileType_def::TacticalPlan;
break;
case TopicEditorBase::TopicType::MSOffice:
m_fileTypes << FileManagement::FileType_def::MSOfficeDocument
<< FileManagement::FileType_def::MSOfficeDocument97
<< FileManagement::FileType_def::MSOfficePresentation
<< FileManagement::FileType_def::MSOfficePresentation97
<< FileManagement::FileType_def::MSOfficeSpreadsheet
<< FileManagement::FileType_def::MSOfficeSpreadsheet97;
break;
case TopicEditorBase::TopicType::OpenOffice:
m_fileTypes << FileManagement::FileType_def::OpenOfficeDocument
<< FileManagement::FileType_def::OpenOfficePresentation
<< FileManagement::FileType_def::OpenOfficeSpreadsheet;
break;
default:
break;
}
switch (m_topicData.topicType)
{
case TopicEditorBase::TopicType::Image:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_Image_Topic"));
break;
case TopicEditorBase::TopicType::Pdf:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_PDF_Topic"));
break;
case TopicEditorBase::TopicType::Text:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_Text_Topic"));
break;
case TopicEditorBase::TopicType::Xml:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_XML_Topic"));
break;
case TopicEditorBase::TopicType::TacticalPlan:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_Tactical_Plan_Topic"));
break;
case TopicEditorBase::TopicType::MSOffice:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_MS_Office_Topic"));
break;
case TopicEditorBase::TopicType::OpenOffice:
setOnlineHelpFilename(QStringLiteral("Script_Editor-Add_Open_Office_Topic"));
break;
default:
translate(m_ui, tr("Unknown File Topic Editor"));
break;
}
m_ui->pbSetTopicPosition->setEnabled(!m_topicData.channel.isEmpty() || !m_topicData.parentChannel.isEmpty()); // preview only available if topic is at a screen
// only get ONCE (initially) from SAVED topic data !
m_userText = getTopicDataValue(QStringLiteral("UserText")).toString();
m_fileId = getTopicDataValue(QStringLiteral("FileId")).toInt();
m_pageNo = getTopicDataValue(QStringLiteral("PageNo")).toInt();
m_zoomLevel = getTopicDataValue(QStringLiteral("ZoomLevel")).toInt();
m_rotation = getTopicDataValue(QStringLiteral("Rotation")).toInt();
if (hasTopicDataProperties())
updatePreview();
}
void FileTopicEditor::retranslate()
{
switch (m_topicData.topicType)
{
case TopicEditorBase::TopicType::Image:
translate(m_ui, tr("Image Topic Editor"));
break;
case TopicEditorBase::TopicType::Pdf:
translate(m_ui, tr("Pdf Topic Editor"));
break;
case TopicEditorBase::TopicType::Text:
translate(m_ui, tr("Text Topic Editor"));
break;
case TopicEditorBase::TopicType::Xml:
translate(m_ui, tr("Xml Topic Editor"));
break;
case TopicEditorBase::TopicType::TacticalPlan:
translate(m_ui, tr("Tactical Plan Topic Editor"));
break;
case TopicEditorBase::TopicType::MSOffice:
translate(m_ui, tr("MS Office Topic Editor"));
break;
case TopicEditorBase::TopicType::OpenOffice:
translate(m_ui, tr("Open Office Topic Editor"));
break;
default:
translate(m_ui, tr("Unknown File Topic Editor"));
break;
}
if (hasTopicDataProperties())
updatePreview();
}
void FileTopicEditor::enaDisa()
{
if (m_previewPlaybackWidget)
m_previewPlaybackWidget->setVisible(false);
m_ui->lblPageNo->setVisible(false);
m_ui->sbPageNo->setVisible(false);
m_ui->lblZoom->setVisible(false);
m_ui->zoomSlider->setVisible(false);
m_ui->lblZoomValue->setVisible(false);
m_ui->sbRotation->setVisible(false);
m_ui->lblRotation->setVisible(false);
if (m_topicData.topicType == TopicEditorBase::TopicType::Pdf)
{
m_ui->lblPageNo->setVisible(true);
m_ui->sbPageNo->setVisible(true);
m_ui->lblZoom->setVisible(true);
m_ui->zoomSlider->setVisible(true);
m_ui->lblZoomValue->setVisible(true);
m_ui->sbRotation->setVisible(true);
m_ui->lblRotation->setVisible(true);
m_ui->sbPageNo->setEnabled(false);
m_ui->zoomSlider->setEnabled(false);
m_ui->sbRotation->setEnabled(false);
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->hide();
}
}
///////////////////////////////////////////////////////////////////////////////
// PRIVATE SLOTS
bool FileTopicEditor::apply2()
{
setTopicDataProperty(QStringLiteral("FileId"), m_fileId);
if (m_topicData.topicType == TopicEditorBase::TopicType::Pdf)
{
setTopicDataProperty(QStringLiteral("PageNo"), m_pageNo);
setTopicDataProperty(QStringLiteral("ZoomLevel"), m_zoomLevel);
setTopicDataProperty(QStringLiteral("Rotation"), m_rotation);
}
setTopicDataProperty(QStringLiteral("UserText"), m_userText);
setDescription(m_ui->widget->description());
m_ui->widget->previewer()->setTopicData(m_topicData);
if (m_fileId == 0)
{
if (m_topicData.topicType == TopicEditorBase::TopicType::Text && !m_userText.isEmpty())
{
emit changesSaved(m_topicData);
return true;
}
new LtsWidgets::LtsMessageDialogNew(this, tr("No content was selected for this topic."), tr("Applying changes failed"));
return false;
}
emit changesSaved(m_topicData); // used to reset flag if on Preview widget was modified.
return true;
}
void FileTopicEditor::onSelectFile()
{
QByteArray content;
int folderId = 0;
if (m_topicData.topicType == TopicEditorBase::TopicType::TacticalPlan)
folderId = m_dtc->findFolder(0, QStringLiteral("Tactical Plans"));
int fileId = m_guiIfc->loadFileContent(this, content, m_fileTypes, 0, QString(), folderId);
if (fileId > 0)
{
m_fileId = fileId;
m_userText.clear(); // if we selected a valid file, user text has no use
updatePreview();
slotChangesMade();
}
else
{
ERROR_LOG(m_logger) << "Cannot load file from library";
}
}
void FileTopicEditor::onZoomSliderChanged()
{
DEBUG_LOG(m_logger) << LOGFUNCTION;
m_zoomLevel = m_ui->zoomSlider->value();
m_ui->zoomSlider->setToolTip(tr("Zoom %1 %").arg(m_zoomLevel));
m_ui->lblZoomValue->setText(QString::number(m_zoomLevel) + QStringLiteral(" %"));
m_previewPlaybackWidget->setZoomFactor(m_zoomLevel / 100.);
}
void FileTopicEditor::onPageNoChanged(int pageNo)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << "page no = " << pageNo;
m_pageNo = pageNo;
m_ui->sbPageNo->setValue(m_pageNo);
m_previewPlaybackWidget->setPage(m_pageNo);
}
void FileTopicEditor::onEnterText()
{
if (m_textEditDialog)
{
focusDialog(menuGroup(), QStringLiteral("FileTopicTextEditDialog"), LtsWidgets::LayoutArea::eDialogTab);
return;
}
m_textEditDialog = new LtsWidgets::LtsTextEditDialog(this); // QPointer
m_textEditDialog->enableBackgroundColor(true);
QString html;
if (m_userText.isEmpty() && m_fileContent.id() != 0)
{
std::vector<uint8_t> content;
m_getContent->getContent(m_fileContent.id(), content);
html = QString::fromUtf8(LtsUtils::toQByteArray(content));
}
else
html = m_userText;
// we have to remove the background color from the html but to add it to the exteditors color picker
const int backGroundColorIndex = html.indexOf(QLatin1String("background-color"));
if (backGroundColorIndex != -1)
{
const int rgbIndex = html.indexOf(QLatin1Char('#'), backGroundColorIndex);
const QColor backGroundColor(html.mid(rgbIndex, 7));
const int backGroundColorIndexEnd = html.indexOf(QLatin1Char(';'), backGroundColorIndex);
m_textEditDialog->setInitialBackgroundColor(backGroundColor);
html.remove(backGroundColorIndex, backGroundColorIndexEnd - backGroundColorIndex + 2);
}
m_textEditDialog->setHtml(html);
connect(m_textEditDialog.data(), &LtsWidgets::LtsTextEditDialog::signalTextAppliedWithBackGroundColor,
this, &FileTopicEditor::onCustomTextChanged);
addDialog(m_textEditDialog, menuGroup(), QStringLiteral("FileTopicTextEditDialog"), LtsWidgets::LayoutArea::eDialogTab);
}
void FileTopicEditor::onRotationChanged(int rotation)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " rotation = " << rotation;
m_rotation = rotation;
m_ui->sbRotation->setValue(m_rotation);
m_previewPlaybackWidget->setRotation(m_rotation);
}
void FileTopicEditor::onCustomTextChanged(const QString &htmlText)
{
m_userText = htmlText;
m_ui->leFileName->setText(tr("Custom text"));
m_fileId = 0;
m_fileContent = FileContent();
updatePreview();
slotChangesMade();
}
/*!
* \brief FileTopicEditor::onPreview
* in this Method the scroll area and the widget will be used as parent
* A new Object will be created and used instead of the parent. to avoid sofware crashed on preview
* setWidget in topic designer: ownership of created scrollArea will be changed there => on delete will be
* automatically deleted.
*/
void FileTopicEditor::onPreview()
{
if(m_ui->scrollArea == nullptr || m_ftc == nullptr)
return;
updatePreview();
QScrollArea *scrollArea = new QScrollArea(m_ui->scrollArea);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setWidgetResizable(true);
FileContentPreviewPlaybackWidget *prevWidget = new FileContentPreviewPlaybackWidget(m_ftc, m_previewPlaybackWidget);
prevWidget->setGeometry(QRect(0, 0, 566, 69));
QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
sizePolicy1.setHorizontalStretch(0);
sizePolicy1.setVerticalStretch(0);
sizePolicy1.setHeightForWidth(prevWidget->sizePolicy().hasHeightForWidth());
prevWidget->setSizePolicy(sizePolicy1);
prevWidget->setVisible(true);
prevWidget->init(m_fileContent, m_pageNo, m_zoomLevel / 100., m_rotation, 0, m_userText);
scrollArea->setWidget(prevWidget);
connect(prevWidget, &FileContentPreviewPlaybackWidget::currentPageChanged,
this, &FileTopicEditor::onPageNoChanged);
connect(prevWidget, &FileContentPreviewPlaybackWidget::rotationChanged,
this, [this, prevWidget](int rotation)
{
if(m_ui->sbRotation == nullptr)
return;
m_rotation = rotation;
m_ui->sbRotation->setValue(m_rotation);
prevWidget->setRotation(m_rotation);
});
emit signalSetTopicPosition(scrollArea, m_topicData.id);
}
} // namespace FileManagement
@@ -0,0 +1,87 @@
/**
* @RDE_HEADER@
* Topic Editor for the Situation Topic in the Script Editor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2017-04-04
*/
#pragma once
#include <FileManagement/logger.h>
#include <LtsSession/lts_session.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/FileManagement/Gui/Explorer/flm_preview_playback.h>
#include <TopicEditorBase/topic_editor_base.h>
#include <QPointer>
namespace Ui { class FileTopicEditor; }
namespace PresentationManagement { class TopicDesigner; }
namespace LtsWidgets { class LtsTextEditDialog; }
namespace FileManagement
{
class FileTopicEditor : public TopicEditorBase::TopicEditor
{
Q_OBJECT
public:
explicit FileTopicEditor(
LtsSession::LtsSession *session, FileContentPreviewPlaybackWidget *previewWidget,
const std::shared_ptr<FileManagement::Interface::Ftc> &ftc, QWidget *parent = nullptr
);
~FileTopicEditor();
void updatePreview();
bool fetchInterfaces();
private:
void updateInternalData() override final;
void retranslate() override final;
void enaDisa();
private slots:
bool apply2() override final;
void onSelectFile();
void onZoomSliderChanged();
void onPageNoChanged(int pageNo);
void onRotationChanged(int rotation);
void onEnterText();
void onCustomTextChanged(const QString &htmlText);
void onPreview();
private:
LtsSession::LtsSession *m_session{nullptr};
std::shared_ptr<FileManagement::Interface::Dtc> m_dtc{nullptr};
std::shared_ptr<FileManagement::ForeignGuiInterface> m_guiIfc{nullptr};
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc{nullptr};
QVector<FileManagement::FileType> m_fileTypes;
FileManagement::GetFileContent *m_getContent{nullptr};
FileContentPreviewPlaybackWidget *m_previewPlaybackWidget{nullptr};
FileContent m_fileContent;
QString m_fileName;
int m_fileId{0};
int m_pageNo{1};
int m_zoomLevel{100};
int m_rotation{0};
QString m_userText;
//bool m_firstTimeSelected;
QPointer<LtsWidgets::LtsTextEditDialog> m_textEditDialog;
Ui::FileTopicEditor *m_ui{nullptr};
NGL::INGLLogger &m_logger;
};
} // namespace FileManagement
@@ -0,0 +1,226 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FileTopicEditor</class>
<widget class="QWidget" name="FileTopicEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>589</width>
<height>179</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">File Topic Editor</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblSelectedFile">
<property name="text">
<string>Selected File:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="leFileName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbBrowse">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbEnterText">
<property name="text">
<string>... or enter Text</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbSetTopicPosition">
<property name="text">
<string>Preview Positioning</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblPageNo">
<property name="text">
<string>Scroll to Page No:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="sbPageNo"/>
</item>
<item>
<widget class="QLabel" name="lblRotation">
<property name="text">
<string>Rotation:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="sbRotation">
<property name="maximum">
<number>270</number>
</property>
<property name="singleStep">
<number>90</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblZoom">
<property name="text">
<string>Zoom Level:</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="zoomSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string notr="true"/>
</property>
<property name="minimum">
<number>50</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblZoomValue">
<property name="text">
<string notr="true">100</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="TopicEditorBase::TopicPreviewWidget" name="widget" native="true"/>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>100</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>563</width>
<height>64</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TopicEditorBase::TopicPreviewWidget</class>
<extends>QWidget</extends>
<header>TopicEditorBase/topic_preview_widget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>leFileName</tabstop>
<tabstop>sbPageNo</tabstop>
<tabstop>sbRotation</tabstop>
<tabstop>zoomSlider</tabstop>
<tabstop>scrollArea</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
File diff suppressed because it is too large. Load diff
+273
View File
@@ -0,0 +1,273 @@
/**
* @RDE_HEADER@
* FileManagement - FileExplorer dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-11
*/
#pragma once
#include <FileManagement/flm_dtc.h>
#include <FileManagement/flm_ftc.h>
#include <FileManagement/logger.h>
#include <OperatorManagement/opm_dtc.h>
#include <ExerciseManagement/exm_dtc.h>
#include <ParticipantManagement/ppm_dtc.h>
#include <LtsWidgets/lts_dialog.h>
#include <LtsWidgets/lts_frameless_dialog.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <LtsSession/lts_session.h>
#include <Plugins/FileManagement/flm_combobox_gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include "flm_get_content.h"
namespace Ui
{
class FileManagementDialogWidget;
}
//----------------------------------------------------------------------------------------------------
// FileManagementDialogWidget
//----------------------------------------------------------------------------------------------------
namespace FileManagement
{
class DialogModelFolder;
class DialogModelProxyFolder;
class DialogModelFile;
class DialogFileProxyModel;
class ForeignGuiComboboxInterface;
enum class FileDialogMode
{
OpenFile = 0, // used as modal select file to open
SaveFile = 1, // used as modal select folder to save file
User = 2, // used by normal RW user to organize library
Admin = 3 // used as admin, can export, remove files
};
//----------------------------------------------------------------------------------------------------
class FileManagementDialogWidget final : public QWidget
, protected FileManagement::Interface::Ftc::FolderRemoveReplyHandler
, protected FileManagement::Interface::Ftc::FileContentRemoveReplyHandler
, protected FileManagement::Interface::Ftc::FileContentModifyReplyHandler
, protected FileManagement::Interface::Ftc::FileContentChangeStatusReplyHandler
{
Q_OBJECT
friend class FileManagementDialogTab;
friend class FileManagementDialog;
public:
explicit FileManagementDialogWidget(QWidget *parent = nullptr);
~FileManagementDialogWidget();
bool init(LtsSession::LtsSession *session,
FileDialogMode dlgMode = FileDialogMode::OpenFile,
const QVector<FileType> &fileTypes = QVector<FileType>(),
int folderId = 0,
const QString &xmlType = QString());
Q_SIGNALS:
void enableButtons();
void accepted();
void rejected();
private:
void enaDisa();
void saveFileName(const QString &name);
QModelIndex selectedIndexViewFolder() const;
bool isFolderRemovable(const QModelIndex &idx) const;
void removeCurrentRowFolder();
static QString getTemplateFile(const QString &fileName);
FileManagement::FileType getFileType(const QString &fileExt);
void onFolderRemoveReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
void onFileContentRemoveReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
void onFileContentModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
void onFileContentChangeStatusReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
void createNewOfficeFile(const QString &fileName);
static QString getFileTypeStr(FileManagement::FileType fileType);
protected slots:
void onReject();
// folders
void onAddFolder();
void onEditFolder();
void onRemoveFolder();
void onFolderSelectionChanged();
void folderContextMenuRequested(const QPoint &position);
void onFolderChanged(const FileManagement::Folder &data, DataModification modType);
void onRefreshFolders();
void onCopyFolder();
void onCutFolder();
void onPasteFolder();
void selectFolder();
// files
void onExportFile();
void onImportFile();
void onNewOfficeWord();
void onNewOfficeExcel();
void onNewOfficePowerPoint();
void onNewLibreOfficeWrite();
void onNewLibreOfficeCalc();
void onNewLibreOfficePresent();
void onNewFileFromTemplate();
void onRemoveFile();
void onDeleteFile();
void onRestoreFile();
void onEditFile();
void onPreviewFile();
void fileContextMenuRequested(const QPoint &position);
void onCopyFile();
void onCutFile();
void onPasteFile();
void onSelectFile();
void onChooseFileName();
void onFileChanged(const FileManagement::FileContent &data, DataModification modType);
bool showFile(const FileManagement::FileContent &fc, const QString &xmlType);
void reInitModelFile(bool restoreSelected = false);
private:
DialogModelFolder *m_modelFolder{nullptr};
DialogModelProxyFolder *m_proxyModelFolder{nullptr};
DialogModelFile *m_modelFile{nullptr};
DialogFileProxyModel *m_proxyModelFile{nullptr};
std::shared_ptr<FileManagement::Interface::Dtc> m_dtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc;
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<FileManagement::ForeignGuiComboboxInterface> m_flmGuiCbxIfc;
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGuiIfc;
Ui::FileManagementDialogWidget *m_ui{nullptr};
LtsSession::LtsSession *m_session{nullptr};
QString m_menuGroup;
LtsUtils::RequestHelper *m_requestHelper{nullptr};
GetFileContent *m_getContent{nullptr};
// folder actions
QAction *m_actionAddFolder{nullptr};
QAction *m_actionRenameFolder{nullptr};
QAction *m_actionRemoveFolder{nullptr};
QAction *m_actionRefreshFolders{nullptr};
QAction *m_actionCutFolder{nullptr};
QAction *m_actionCopyFolder{nullptr};
QAction *m_actionPasteFolder{nullptr};
FileManagement::Folder m_copyFolder;
int m_selectedFolderId{-1};
// file actions
QAction *m_actionImportFile{nullptr};
QAction *m_actionNewOfficeExcel{nullptr};
QAction *m_actionNewOfficeWord{nullptr};
QAction *m_actionNewOfficePowerPoint{nullptr};
QAction *m_actionNewLibreOfficeWrite{nullptr};
QAction *m_actionNewLibreOfficeCalc{nullptr};
QAction *m_actionNewLibreOfficePresent{nullptr};
QAction *m_actionNewFromTemplate{nullptr};
QAction *m_actionEditFile{nullptr};
QAction *m_actionDeleteFile{nullptr};
QAction *m_actionPreviewFile{nullptr};
QAction *m_actionCutFile{nullptr};
QAction *m_actionCopyFile{nullptr};
QAction *m_actionPasteFile{nullptr};
// admin actions
QAction *m_actionRemoveFile{nullptr};
QAction *m_actionRestoreFile{nullptr};
QAction *m_actionExportFile{nullptr};
FileManagement::FileContent m_copyFile;
FileManagement::FileContent m_selectedFileContent;
std::vector<uint8_t> m_content;
QString m_fileName;
QVector<FileManagement::FileType> m_fileTypes;
QString m_xmlType;
FileDialogMode m_dialogMode;
bool m_isAdminMode;
LOGGER_T m_logger;
};
//----------------------------------------------------------------------------------------------------
class FileManagementDialog : public LtsWidgets::LtsFramelessDialog
{
Q_OBJECT
friend class FileManagementDialogWidget;
public:
explicit FileManagementDialog(QWidget *parent = nullptr);
~FileManagementDialog();
bool init(LtsSession::LtsSession *session,
FileDialogMode dlgMode = FileDialogMode::OpenFile,
const QVector<FileType> &fileTypes = QVector<FileType>(),
int folderId = 0,
const QString &xmlType = QString());
FileManagement::FileContent getSelectedFile() const { return m_editItemWidget->m_selectedFileContent; }
int getSelectedFileId() const { return m_editItemWidget->m_selectedFileContent.id(); }
int getSelectedFolderId() const { return m_editItemWidget->m_selectedFolderId; }
QString getFileName() const { return m_editItemWidget->m_fileName; }
Q_SIGNALS:
void fileSelected(int folderId, int fileId, const QString &fileName);
protected:
void accept() override;
private:
void enaDisa();
private:
FileManagementDialogWidget *m_editItemWidget{nullptr};
LtsWidgets::LtsDialogButtonBox *m_buttonBox{nullptr};
FileDialogMode m_dialogMode;
LOGGER_T m_logger;
};
//-------------------------------------------------------------------------------------------------
class FileManagementDialogTab : public LtsWidgets::LtsDialog
{
Q_OBJECT
friend class FileManagementDialogWidget;
public:
explicit FileManagementDialogTab(const QString &menuGroup, QWidget *parent = nullptr);
~FileManagementDialogTab();
bool init(LtsSession::LtsSession *session,
FileDialogMode dlgMode = FileDialogMode::OpenFile,
const QVector<FileType> &fileTypes = QVector<FileType>(),
const int &folderId = 0,
const QString &buttonName = QString());
int getSelectedFileId() const { return m_editItemWidget->m_selectedFileContent.id(); }
int getSelectedFolder() const { return m_editItemWidget->m_selectedFolderId; }
QString getFileName() const { return m_editItemWidget->m_fileName; }
FileContent getSelectedFile() const { return m_editItemWidget->m_selectedFileContent; }
signals:
void accepted();
private:
void retranslate() override;
void enaDisa();
private:
FileManagementDialogWidget *m_editItemWidget{nullptr};
FileDialogMode m_dialogMode;
LOGGER_T m_logger;
};
} // namespace
+143
View File
@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FileManagementDialogWidget</class>
<widget class="QWidget" name="FileManagementDialogWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>925</width>
<height>559</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">File Management</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lblFolder">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Selected Folder:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblSelectedFolder">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">None</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="tvFolder">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::CurrentChanged|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="LtsDataView::LtsDataView" name="widgetFiles">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>500</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="lblFilter">
<property name="text">
<string>Filtering:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="lblFile">
<property name="text">
<string>Selected File:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leFile">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsDataView::LtsDataView</class>
<extends>QWidget</extends>
<header>LtsDataView/lts_data_view.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,195 @@
/**
* @RDE_HEADER@
* FileManagement - FileContent model
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-11
*/
#include "flm_dialog_model_file.h"
#include <ngltools/ngltools_dtg.h>
#include <QGuiApplication>
#include <QPalette>
#include <QDateTime>
#include <FileManagement/flm_translation.h>
#include <LtsSession/lts_session_data.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
namespace FileManagement
{
//-------------------------------------------------------------------------------------
// DialogModelFile
//-------------------------------------------------------------------------------------
DialogModelFile::DialogModelFile(QObject *parent)
: LtsWidgets::LtsAbstractTableModel<FileManagement::FileContent>(
{
tr("Name"),
tr("Type"),
tr("Category"),
tr("Status"),
tr("Template"),
tr("Exercise"),
tr("Phase"),
tr("Operator"),
tr("Used"),
tr("Uses"),
tr("Last modified"),
tr("Properties"),
tr("Folder Id"),
tr("File Id")
},
parent)
, m_logger(getLogger("DialogModelFile"))
{}
//-------------------------------------------------------------------------------------
bool DialogModelFile::initModel(LtsSession::LtsSession *session,
const QString &xmlType,
const std::function<bool(const FileManagement::FileContent &, const QString &)> &predicate)
{
if (!session->getDtc<FileManagement::DataInterface>(m_flmDtc))
return false;
if (!session->getDtc<OperatorManagement::DataInterface>(m_opmDtc))
return false;
if (!session->getDtc<ExerciseManagement::DataInterface>(m_exmDtc))
return false;
clear();
// insert Model
auto files = [this, xmlType, predicate](const FileManagement::FileContent & fc)
{
if (!predicate(fc, xmlType))
return;
insertRow(fc);
};
m_flmDtc->fileContents(files);
DEBUG_LOG(m_logger) << "initModel - #Files: " << m_vecData.size();
return true;
}
//-------------------------------------------------------------------------------------
QVariant DialogModelFile::data(const QModelIndex &index, int role) const
{
if (!indexIsValid(index))
return {};
const FileManagement::FileContent &fl = m_vecData.at(index.row());
switch(role)
{
case Qt::BackgroundRole:
{
if (fl.fileStatus() == FileManagement::FileStatus::Deleted)
return QGuiApplication::palette().color(QPalette::Disabled, QPalette::AlternateBase);
return QGuiApplication::palette().color(QPalette::Active, QPalette::Base);
}
case Qt::DisplayRole:
{
switch (index.column())
{
case NAME:
return QString::fromStdString(fl.name());
case ISTEMPLATE:
return fl.isTemplate() ? tr("Yes") : tr("No");
case FOLDER:
return fl.folderId();
case FILEID:
return fl.id();
case FILETYPE:
return FileManagement::toString(fl.fileType());
case FILECATEGORY:
return FileManagement::toString(fl.fileCategory());
case FILESTATUS:
return FileManagement::toString(fl.fileStatus());
case OPERATOR:
return QString::fromStdString(m_opmDtc->user(fl.operatorId()).name());
case EXERCISE:
return fl.exerciseId().is_set() ? QString::fromStdString(m_exmDtc->exercise(fl.exerciseId().get()).name()) : QVariant();
case PHASE:
return fl.phaseId().is_set() ? QString::fromStdString(m_exmDtc->exercisePhase(fl.phaseId().get()).name()) : QVariant();
case USEDBY:
return fl.isUsedBy() ? tr("Yes") : tr("No");
case USES:
return fl.usedBy();
case LASTMODIFIED:
return QDateTime::fromMSecsSinceEpoch(fl.lastModified());
case PROPERTIES:
return QString::fromStdString(fl.properties());
}
}
case Qt::DecorationRole:
{
if (index.column() == NAME && fl.isHidden())
return QIcon(QLatin1String(":/style/lock.svg"));
break;
}
default:
break;
}
return {};
}
//-------------------------------------------------------------------------------------
FileManagement::FileContent DialogModelFile::findFileFromName(const QString &fileName) const
{
for (int row = 0; row < rowCount(); ++row)
{
const FileManagement::FileContent &fl = m_vecData.at(row);
if (QString::fromStdString(fl.name()) == fileName)
return fl;
}
return FileManagement::FileContent();
} // int DialogModelFile::findFileIdFromName(const QString & fileName) const
void DialogFileProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
m_sourceModel = qobject_cast<DialogModelFile*>(sourceModel);
LtsWidgets::LtsColumnFilterProxyModel::setSourceModel(sourceModel);
}
bool DialogFileProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (!m_sourceModel ||
source_left.column() != source_right.column() ||
!source_left.isValid() ||
!source_right.isValid())
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
const auto &dataLeft = m_sourceModel->m_vecData.at(source_left.row());
const auto dataRight = m_sourceModel->m_vecData.at(source_right.row());
switch (source_left.column())
{
case LASTMODIFIED:
return dataLeft.lastModified() < dataRight.lastModified();
case NAME:
case FILETYPE:
case FILECATEGORY:
case FILESTATUS:
case ISTEMPLATE:
case EXERCISE:
case PHASE:
case OPERATOR:
case USEDBY:
case USES:
case PROPERTIES:
case FOLDER:
case FILEID:
case COUNT:
break;
}
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
}
} // namespace FileManagement
@@ -0,0 +1,84 @@
/**
* @RDE_HEADER@
* FileManagement - FileContent model
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-11
*/
#pragma once
#include <FileManagement/logger.h>
#include <Services/FileManagement/flm_dtc.h>
#include <Services/FileManagement/flm_ftc.h>
#include <Services/OperatorManagement/opm_dtc.h>
#include <Services/ExerciseManagement/exm_dtc.h>
#include <LtsWidgets/lts_abstract_table_model.h>
#include <LtsWidgets/lts_column_filter_proxy_model.h>
#include <LtsSession/lts_session.h>
// --------------------------------------------------------
// FileManagementModelFile
// --------------------------------------------------------
namespace FileManagement
{
// --------------------------------------------------------
enum Columns
{
NAME = 0,
FILETYPE,
FILECATEGORY,
FILESTATUS,
ISTEMPLATE,
EXERCISE,
PHASE,
OPERATOR,
USEDBY,
USES,
LASTMODIFIED,
PROPERTIES,
FOLDER,
FILEID,
COUNT,
};
// --------------------------------------------------------
class DialogModelFile : public LtsWidgets::LtsAbstractTableModel<FileManagement::FileContent>
{
Q_OBJECT
public:
explicit DialogModelFile(QObject *parent = nullptr);
bool initModel(LtsSession::LtsSession *session,
const QString &xmlType,
const std::function<bool(const FileContent &, const QString &)> &predicate);
QVariant data(const QModelIndex &, int) const override final;
FileManagement::FileContent findFileFromName(const QString &fileName) const;
private:
std::shared_ptr<FileManagement::Interface::Dtc> m_flmDtc;
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
friend class DialogFileProxyModel;
LOGGER_T m_logger;
};
class DialogFileProxyModel final : public LtsWidgets::LtsColumnFilterProxyModel
{
Q_OBJECT
public:
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
void setSourceModel(QAbstractItemModel *sourceModel) override;
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
private:
DialogModelFile *m_sourceModel{nullptr};
};
}
@@ -0,0 +1,404 @@
/**
* @RDE_HEADER@
* FileManangement - Folder model
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-11
*/
#include "flm_dialog_model_folder.h"
#include "ParticipantManagement/ppm_dtc.h"
#include <LtsUtilsCore/pgarray.h>
#include <ngltools/ngltools_dtg.h>
#include <nglwidgets/ngltreeitem.h>
#include <FileManagement/flm_translation.h>
#include <ParticipantManagement/ppm_translation.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/FileManagement/flm_combobox_gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <QDateTime>
namespace FileManagement
{
//-----------------------------------------------------------------------------------------------------------
// DialogModelFolder
//-----------------------------------------------------------------------------------------------------------
DialogModelFolder::DialogModelFolder(QObject *parent,
NGLTreeItem *rootItem,
const QStringList &header)
: NGLTreeModel(parent, rootItem, header)
, m_flmDtc(nullptr)
, m_flmFtc(nullptr)
, m_exmDtc(nullptr)
, m_opmDtc(nullptr)
, m_ppmDtc(nullptr)
, m_logger(getLogger("DialogModelFolder"))
{
}
//-----------------------------------------------------------------------------------------------------------
QVariant DialogModelFolder::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
switch (section)
{
case ID:
return tr("Id");
case NAME:
return tr("Folder");
case PATH:
return tr("Path");
case EDITABLE:
return tr("Editable");
case PARENT:
return tr("Parent");
case OPERATOR:
return tr("Operator");
case MODIFIED:
return tr("Last modified");
default:
break;
}
}
return NGLTreeModel::headerData(section, orientation, role);
}
//-----------------------------------------------------------------------------------------------------------
QVariant DialogModelFolder::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return {};
NGLTreeItem *item = privateData(index);
if (item->data().canConvert<FileManagement::Folder>())
{
FileManagement::Folder folderData = item->data().value<FileManagement::Folder>();
switch(role)
{
case Qt::DisplayRole:
{
switch (index.column())
{
case NAME:
return getFolderName(folderData);
case ID:
return folderData.id();
case PATH:
return LtsUtils::IntArray(folderData.path()).toPgString();
case EDITABLE:
return folderData.isEditable() ? tr("Yes") : tr("No");
case PARENT:
return folderData.parentId();
case OPERATOR:
return QString::fromStdString(m_opmDtc->user(folderData.operatorId()).name());
case MODIFIED:
return QDateTime::fromMSecsSinceEpoch(folderData.lastModified());
default:
break;
}
}
case Qt::UserRole:
return folderData.id();
case Qt::DecorationRole:
{
if (folderData.isHidden())
return item->icon();
break;
}
default:
break;
}
}
return {};
}
//-----------------------------------------------------------------------------------------------------------
FileManagement::Folder DialogModelFolder::getFolder(const QModelIndex &idx) const
{
return privateData(idx)->data().value<FileManagement::Folder>();
}
//-----------------------------------------------------------------------------------------------------------
QString DialogModelFolder::getFolderName(const FileManagement::Folder &folderData) const
{
QString folderName = QString::fromStdString(folderData.name());
if (folderName.startsWith(QStringLiteral("$")))
{
folderName.remove(0, 1);
if (folderName.startsWith(QStringLiteral("EX_")))
{
int exId = folderName.remove(0, 3).toInt();
return QString::fromStdString(m_exmDtc->exercise(exId).name());
}
if (folderName.startsWith(QStringLiteral("PH_")))
{
int phId = folderName.remove(0, 3).toInt();
return QString::fromStdString(m_exmDtc->exercisePhase(phId).name());
}
if (folderName.startsWith(QStringLiteral("PY_")))
{
int partyId = folderName.remove(0, 3).toInt();
return ParticipantManagement::trPartyName(m_ppmDtc->party(partyId).name());
}
return FileManagement::trFolderName(folderName.toStdString());
}
return FileManagement::trFolderName(folderName.toStdString());
}
//-----------------------------------------------------------------------------------------------------------
bool DialogModelFolder::init(LtsSession::LtsSession *session, bool isAdminMode)
{
if (!session->getDtc<FileManagement::DataInterface>(m_flmDtc))
return false;
if (!session->getFtc<FileManagement::DataInterface>(m_flmFtc))
return false;
if (!session->getDtc<OperatorManagement::DataInterface>(m_opmDtc))
return false;
if (!session->getDtc<ExerciseManagement::DataInterface>(m_exmDtc))
return false;
if (!session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc))
return false;
return initModel(session->exerciseId(), isAdminMode);
}
//-----------------------------------------------------------------------------------------------------------
bool DialogModelFolder::isRowRemovable(const NGLTreeItem *parentItem) const
{
if (!parentItem)
return false;
FileManagement::Folder folderData = parentItem->data().value<FileManagement::Folder>();
return folderData.isEditable();
}
//-----------------------------------------------------------------------------------------------------------
bool DialogModelFolder::initModel(int exerciseId, bool isAdminMode)
{
DEBUG_LOG(m_logger) << "initModel Folder";
NGLTreeModel::resetModel();
QMap<qint32, FileManagement::Folder> tmap;
QHash<int, QModelIndex> parentItemIndexCache;
QVector<int> idsToExclude;
auto cbFolders = [this, exerciseId, &tmap, &idsToExclude, isAdminMode] (const FileManagement::Folder &data)
{
if (data.isDeleted() ||
(!isAdminMode && data.isHidden()))
return;
QString folderName = QString::fromStdString(data.name());
if (folderName.startsWith(QStringLiteral("$EX_")))
{
int exId = folderName.remove(0, 4).toInt();
if ((exerciseId > 0 && exId != exerciseId) || exId != m_exmDtc->exercise(exId).id())
{
DEBUG_LOG(m_logger) << "Excluded exercise id " << exId << ", folder id " << data.id();
idsToExclude.append(data.id());
}
}
tmap.insert(data.id(), data);
};
m_flmDtc->folders(cbFolders);
parentItemIndexCache.insert(0, QModelIndex()); //root
for (QMap<qint32, FileManagement::Folder>::const_iterator iter = tmap.constBegin();
iter != tmap.constEnd(); ++iter)
{
int folderId = iter.key();
int parentId = 0;
FileManagement::Folder fld = iter.value();
if (fld.path().size() > 1)
{
parentId = fld.path().at(fld.path().size() - 2);
int idPos2 = fld.path().at(1);
if (idsToExclude.contains(idPos2))
continue;
}
QVariant data;
data.setValue(fld);
if (!parentItemIndexCache.contains(parentId))
{
WARNING_LOG(m_logger) << "Invalid folder structure, parent may be hidden: " << parentId;
WARNING_LOG(m_logger) << "Folder " << fld.name() << ", hidden: " << fld.isHidden();
}
else
{
QModelIndex pIndex = parentItemIndexCache.value(parentId);
int rowPos = -1;
onInsertRow(rowPos, pIndex, fld);
parentItemIndexCache.insert(folderId, index(rowPos, 0, pIndex));
DEBUG_LOG(m_logger) << "Added to tree (folder id, parent id) : (" << folderId << ", " << parentId << ")";
}
}
return true;
}
//----------------------------------------------------------------------------
bool DialogModelFolder::onInsertRow(int &row, const QModelIndex &parent, const FileManagement::Folder &folderData)
{
DEBUG_LOG(m_logger) << "onInsertRow";
row = rowCount(parent);
QVariant data;
data.setValue(folderData);
QIcon icon;
if (folderData.isHidden())
icon = QIcon(QLatin1String(":/style/lock.svg"));
NGLTreeItem *item = new NGLTreeItem(data, icon);
item->setModified(true);
emit internalDataChanged();
return NGLTreeModel::insertRow(row, parent, item);
}
//----------------------------------------------------------------------------
bool DialogModelFolder::onUpdateRow(const QModelIndex &index, const FileManagement::Folder &folderData)
{
DEBUG_LOG(m_logger) << "onUpdateRow";
QVariant data;
data.setValue(folderData);
emit internalDataChanged();
QIcon icon;
if (folderData.isHidden())
icon = QIcon(QLatin1String(":/style/lock.svg"));
return setItemData(index, data, icon);
}
//----------------------------------------------------------------------------
bool DialogModelFolder::onDeleteRow(const QModelIndex &idx, bool isFirstItem)
{
DEBUG_LOG(m_logger) << "onDeleteRow";
while (rowCount(idx) > 0)
onDeleteRow(NGLTreeModel::index(0, 0, idx), false);
if (isFirstItem) //edit mode
{
NGLTreeItem *item = privateData(idx);
FileManagement::Folder data = item->data().value<FileManagement::Folder>();
data.isDeleted(true);
}
removeRow(idx.row(), idx.parent());
emit internalDataChanged();
return true;
}
//----------------------------------------------------------------------------
QModelIndex DialogModelFolder::getIndex(int folderId) const
{
QModelIndexList list = match(index(0, 0), Qt::UserRole, QVariant::fromValue(folderId), 1, Qt::MatchRecursive);
if (!list.isEmpty())
return list.first();
return {};
}
//----------------------------------------------------------------------------
void DialogModelProxyFolder::setOperatorId(int operatorId)
{
if (m_operatorId == operatorId)
return;
m_operatorId = operatorId;
invalidateFilter();
}
//----------------------------------------------------------------------------
void DialogModelProxyFolder::setSourceModel(QAbstractItemModel *model)
{
m_sourceModel = qobject_cast<DialogModelFolder*>(model);
QSortFilterProxyModel::setSourceModel(model);
}
//----------------------------------------------------------------------------
bool DialogModelProxyFolder::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (!m_sourceModel || source_left.column() != source_right.column())
return QSortFilterProxyModel::lessThan(source_left, source_right);
const NGLTreeItem *itemLeft = m_sourceModel->privateData(source_left);
const NGLTreeItem *itemRight = m_sourceModel->privateData(source_right);
if (!itemLeft || !itemRight)
return QSortFilterProxyModel::lessThan(source_left, source_right);
const FileManagement::Folder left = itemLeft->data().value<FileManagement::Folder>();
const FileManagement::Folder right = itemRight->data().value<FileManagement::Folder>();
if (left.id() == FileManagement::MainFolder::GlobalDocuments || right.id() == FileManagement::MainFolder::GlobalDocuments ||
left.id() == FileManagement::MainFolder::UserDocuments || right.id() == FileManagement::MainFolder::UserDocuments ||
left.id() == FileManagement::MainFolder::ExerciseDocuments || right.id() == FileManagement::MainFolder::ExerciseDocuments)
{
return left.id() < right.id();
}
// no sorting on name for folders!
// if (QString::fromStdString(left.name()) != QString::fromStdString(right.name()))
// {
// return (QString::fromStdString(left.name()) < QString::fromStdString(right.name()));
// }
return left.id() < right.id();
}
//----------------------------------------------------------------------------
void DialogModelProxyFolder::sort(int column, Qt::SortOrder order)
{
Qt::SortOrder myOrder = order;
if (column == 0)
myOrder = Qt::AscendingOrder;
QSortFilterProxyModel::sort(column, myOrder);
}
//----------------------------------------------------------------------------
bool DialogModelProxyFolder::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if (!m_sourceModel || !source_parent.isValid())
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
if (m_operatorId == 0) // no filter for admin
return true;
NGLTreeItem *parent = m_sourceModel->privateData(source_parent);
if (!parent)
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
NGLTreeItem *child = parent->child(source_row);
if (!child)
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
const Folder data = child->data().value<Folder>();
if (data.operatorId() != m_operatorId)
{
// it's user folder -> check if it's in user documents and hide if it's not for the current operator
for (int p : data.path())
{
if (p == FileManagement::MainFolder::UserDocuments)
return false;
}
}
return true;
}
} // namespace FileManagement
@@ -0,0 +1,104 @@
/**
* @RDE_HEADER@
* FileManangement - Folder Model
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-11
*/
#pragma once
#include <FileManagement/logger.h>
#include <Services/FileManagement/flm_dtc.h>
#include <Services/FileManagement/flm_ftc.h>
#include <Services/ExerciseManagement/exm_dtc.h>
#include <Services/OperatorManagement/opm_dtc.h>
#include <Services/ParticipantManagement/ppm_dtc.h>
#include <LtsSession/lts_session.h>
#include <QSortFilterProxyModel>
#include <nglwidgets/ngltreemodel.h>
class QTableWidget;
// -------------------------------------------------------------------------------------
// FileManagementModelFolder
// -------------------------------------------------------------------------------------
namespace FileManagement
{
class DialogModelFolder final : public NGLTreeModel
{
Q_OBJECT
public:
enum Columns
{
NAME = 0,
OPERATOR = 1,
ID = 2,
PATH = 3,
EDITABLE = 4,
PARENT = 5,
MODIFIED = 6,
COUNT = 7,
};
explicit DialogModelFolder(QObject *parent,
NGLTreeItem *rootItem,
const QStringList &header);
~DialogModelFolder() = default;
bool init(LtsSession::LtsSession *session, bool isAdminMode);
bool initModel(int exerciseId, bool isAdminMode);
bool isRowRemovable(const NGLTreeItem *parentItem) const;
FileManagement::Folder getFolder(const QModelIndex &idx) const;
QModelIndex getIndex(int folderId) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override final;
QVariant data(const QModelIndex &, int) const override final;
QString getFolderName(const FileManagement::Folder &folderData) const;
public Q_SLOTS :
bool onInsertRow(int &row, const QModelIndex &parent, const FileManagement::Folder &folderData);
bool onUpdateRow(const QModelIndex &index, const FileManagement::Folder &folderData);
bool onDeleteRow(const QModelIndex &idx, bool isFirstItem = true);
Q_SIGNALS:
void internalDataChanged();
private:
std::shared_ptr<FileManagement::Interface::Dtc> m_flmDtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_flmFtc;
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
LOGGER_T m_logger;
};
// -------------------------------------------------------------------------------------
class DialogModelProxyFolder final : public QSortFilterProxyModel
{
Q_OBJECT
public:
using QSortFilterProxyModel::QSortFilterProxyModel;
void setOperatorId(int operatorId);
void setSourceModel(QAbstractItemModel *model) override;
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override;
protected:
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
DialogModelFolder *m_sourceModel{nullptr};
int m_operatorId = 0;
};
} // namespace FileManagement
// -------------------------------------------------------------------------------------
Q_DECLARE_METATYPE(FileManagement::Folder)
@@ -0,0 +1,443 @@
/**
* @RDE_HEADER@
* FileManagement - Edit FileContent metadata dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-30
*/
#include "flm_edit_file_content.h"
#include "flm_preview_file_dialog.h"
#include "ui_flm_edit_file_content.h"
#include "flm_set_properties_dialog.h"
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/FileManagement/flm_combobox_gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
#include <ngltools/ngltools_dtg.h>
#include <LtsSession/lts_session_data.h>
#include <FileManagement/flm_translation.h>
#include <QDateTime>
namespace FileManagement
{
//--------------------------------------------------------------------------------------------------------------------
FileContentEditDialog::FileContentEditDialog(QWidget *parent)
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_ui(new Ui::FileContentEditDialog)
, m_logger(getLogger("FileContentEditDialog"))
{
m_ui->setupUi(this);
//HACK as close is not allowed directly
connect(m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &FileContentEditDialog::close);
connect(m_ui->leName, &QLineEdit::textChanged, this, &FileContentEditDialog::validate);
connect(m_ui->leName, &QLineEdit::returnPressed, this, &FileContentEditDialog::onReturnPressed);
m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Apply)->hide();
m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Ok)->hide();
}
//--------------------------------------------------------------------------------------------------------------------
FileContentEditDialog::~FileContentEditDialog()
{
delete m_ui;
}
//------------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::validate(const QString &fileName)
{
m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Add)->setDisabled(fileName.isEmpty());
}
//------------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onReturnPressed()
{
if (m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Add)->isEnabled())
m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Add)->setFocus();
}
//--------------------------------------------------------------------------------------------------------------------
bool FileContentEditDialog::init(LtsSession::LtsSession *session,
const QModelIndex &workingIndex,
bool isAdminMode,
const QString &folderName,
const FileManagement::FileContent &data,
const std::vector<uint8_t> &content
)
{
if (!session)
{
ERROR_LOG(m_logger) << "Failed to init FileContentEditDialog";
return false;
}
if (!session->getDtc<FileManagement::DataInterface>(m_dtc))
return false;
if (!session->getFtc<FileManagement::DataInterface>(m_ftc))
return false;
if (!session->getDtc<OperatorManagement::DataInterface>(m_opmDtc))
return false;
if (!session->getDtc<ExerciseManagement::DataInterface>(m_exmDtc))
return false;
if (!session->getForeignGuiInterface<FileManagement::ForeignGuiComboboxInterface>(m_flmGuiCbxIfc))
return false;
m_workingIndex = workingIndex;
m_editData = data;
m_content = content;
m_folderName = folderName;
// combo boxes
m_ui->cbFileType->clear();
m_flmGuiCbxIfc->fillFileTypeComboBox(m_ui->cbFileType);
m_ui->cbFileCategory->clear();
m_flmGuiCbxIfc->fillFileCategoryComboBox(m_ui->cbFileCategory);
m_ui->cbFileStatus->clear();
m_flmGuiCbxIfc->fillFileStatusComboBox(m_ui->cbFileStatus);
fillExercisesComboBox();
fillPhasesComboBox();
getMetaData();
connect(m_ui->cbFileType, static_cast<void (LtsWidgets::LtsComboBox::*)(int)>(&LtsWidgets::LtsComboBox::currentIndexChanged),
this, &FileContentEditDialog::onComboFileTypeChanged);
connect(m_ui->cbFileCategory, static_cast<void (LtsWidgets::LtsComboBox::*)(int)>(&LtsWidgets::LtsComboBox::currentIndexChanged),
this, &FileContentEditDialog::onComboFileCategoryChanged);
connect(m_ui->cbFileStatus, static_cast<void (LtsWidgets::LtsComboBox::*)(int)>(&LtsWidgets::LtsComboBox::currentIndexChanged),
this, &FileContentEditDialog::onComboFileStatusChanged);
connect(m_ui->cbExercises, static_cast<void (LtsWidgets::LtsComboBox::*)(int)>(&LtsWidgets::LtsComboBox::currentIndexChanged),
this, &FileContentEditDialog::onComboExerciseChanged);
connect(m_ui->cbPhases, static_cast<void (LtsWidgets::LtsComboBox::*)(int)>(&LtsWidgets::LtsComboBox::currentIndexChanged),
this, &FileContentEditDialog::onComboPhaseChanged);
connect(m_ui->pbProperties, &QPushButton::clicked,
this, &FileContentEditDialog::onPropertiesClicked);
connect(m_ui->checkUsed, &QCheckBox::stateChanged, this, &FileContentEditDialog::onCheckUsedStateChanged);
if (m_editData.id() > 0) //EditMode
{
m_ui->ltsDialogButtonBox->setText(LtsWidgets::DialogButton::Add, tr("Ok"));
m_ui->ltsDialogButtonBox->connectButton(LtsWidgets::DialogButton::Add, this, &FileContentEditDialog::onEditItem);
setWindowTitle(tr("Edit File Content"));
}
else
{
m_ui->ltsDialogButtonBox->connectButton(LtsWidgets::DialogButton::Add, this, &FileContentEditDialog::onAddItem);
setWindowTitle(tr("Create File Content"));
}
// only show hidden checkbox in Admin mode
m_ui->lblHidden->setVisible(isAdminMode);
m_ui->checkHidden->setVisible(isAdminMode);
#ifdef TABLET_MODE
m_ui->leName->setFocusPolicy(Qt::ClickFocus);
m_ui->leName->clearFocus();
#endif
return true;
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::getMetaData()
{
DEBUG_LOG(m_logger) << "getMetaData";
m_ui->cbExercises->setCurrentIndex(0);
m_ui->cbExercises->setEnabled(false);
m_ui->cbPhases->setCurrentIndex(0);
m_ui->cbPhases->setEnabled(false);
m_ui->leName->setText(QString::fromStdString(m_editData.name()));
m_ui->cbFileType->setCurrentIndex(m_ui->cbFileType->findData(QVariant(m_editData.fileType().underlying())));
m_ui->cbFileCategory->setCurrentIndex(m_ui->cbFileCategory->findData(m_editData.fileCategory().underlying()));
m_ui->cbFileStatus->setCurrentIndex(m_ui->cbFileStatus->findData(QVariant(m_editData.fileStatus().underlying())));
m_ui->leFolder->setText(m_folderName);
m_ui->checkTemplate->setChecked(m_editData.isTemplate());
m_ui->checkHidden->setChecked(m_editData.isHidden());
m_ui->checkUsed->setChecked(m_editData.isUsedBy());
m_ui->lblUses->setText(QStringLiteral("[") + QString::number(m_editData.usedBy()) + QStringLiteral("]"));
m_ui->leOperator->setText(QString::fromStdString(m_opmDtc->user(m_editData.operatorId()).name()));
m_ui->leProperties->setText(QString::fromStdString(m_editData.properties()));
if (m_editData.fileCategory() == FileManagement::FileCategory::Exercise ||
m_editData.fileCategory() == FileManagement::FileCategory::User)
{
if (m_editData.exerciseId().is_set())
{
m_ui->cbExercises->setCurrentIndex(m_ui->cbExercises->findData(m_editData.exerciseId().get()));
if (m_editData.phaseId().is_set())
m_ui->cbPhases->setCurrentIndex(m_ui->cbPhases->findData(m_editData.phaseId().get()));
else
m_ui->cbPhases->setEnabled(true);
}
else
m_ui->cbExercises->setEnabled(true);
}
m_ui->leLastModified->setText(DTG::toStringMSec(m_editData.lastModified()));
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::setMetaData()
{
DEBUG_LOG(m_logger) << "setMetaData";
m_editData.name(m_ui->leName->text().toStdString());
m_editData.fileType(static_cast<FileManagement::FileType::type>(m_ui->cbFileType->currentData().toInt()));
m_editData.fileCategory(static_cast<FileManagement::FileCategory::type>(m_ui->cbFileCategory->currentData().toInt()));
m_editData.fileStatus(static_cast<FileManagement::FileStatus::type>(m_ui->cbFileStatus->currentData().toInt()));
m_editData.isTemplate(m_ui->checkTemplate->isChecked());
m_editData.isHidden(m_ui->checkHidden->isChecked());
m_editData.isUsedBy(m_ui->checkUsed->isChecked());
if (m_editData.fileCategory() == FileManagement::FileCategory::Exercise)
{
if (m_ui->cbExercises->currentData().toInt() > 0)
{
m_editData.exerciseId(m_ui->cbExercises->currentData().toInt());
if (m_ui->cbPhases->currentData().toInt() > 0)
m_editData.phaseId(m_ui->cbPhases->currentData().toInt());
}
}
else
{
m_editData.exerciseId();
m_editData.phaseId();
}
m_editData.properties(m_ui->leProperties->text().toStdString());
m_editData.lastModified(QDateTime::currentMSecsSinceEpoch());
// logged in operator
m_editData.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
// folderId is already set as selected folder
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onAddItem()
{
DEBUG_LOG(m_logger) << "onAddItem";
setMetaData();
FileContentModifyRequest data;
data.name(m_editData.name());
data.fileType(m_editData.fileType());
data.fileCategory(m_editData.fileCategory());
data.fileStatus(m_editData.fileStatus());
data.properties(m_editData.properties());
data.isTemplate(m_editData.isTemplate());
data.isHidden(m_editData.isHidden());
data.isUsedBy(m_editData.isUsedBy());
data.usedBy(m_editData.usedBy());
data.folderId(m_editData.folderId());
if (m_editData.fileCategory() == FileManagement::FileCategory::Exercise ||
m_editData.fileCategory() == FileManagement::FileCategory::User)
{
if (m_editData.exerciseId().is_set())
{
data.exerciseId(m_editData.exerciseId().get());
if (m_editData.phaseId().is_set())
data.phaseId(m_editData.phaseId().get());
}
}
else
{
m_editData.exerciseId();
m_editData.phaseId();
}
DEBUG_LOG(m_logger) << "onAddItem: Content size = " << m_content.size();
data.content(m_content);
data.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
data.lastModified(QDateTime::currentMSecsSinceEpoch());
if (!m_requestHelper->startSingleRequest([data, this]() {return m_ftc->fileContentModifyRequest(data, this);}))
return;
int newRow = -1;
emit addItem(newRow, m_workingIndex, m_editData);
close();
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onEditItem()
{
DEBUG_LOG(m_logger) << "onEditItem";
setMetaData();
FileContentModifyRequest data;
data.id(m_editData.id());
data.name(m_editData.name());
data.fileType(m_editData.fileType());
data.fileCategory(m_editData.fileCategory());
data.fileStatus(m_editData.fileStatus());
data.properties(m_editData.properties());
data.isTemplate(m_editData.isTemplate());
data.isHidden(m_editData.isHidden());
data.isUsedBy(m_editData.isUsedBy());
data.usedBy(m_editData.usedBy());
data.folderId(m_editData.folderId());
if (m_editData.fileCategory() == FileManagement::FileCategory::Exercise ||
m_editData.fileCategory() == FileManagement::FileCategory::User)
{
if (m_editData.exerciseId().is_set())
{
data.exerciseId(m_editData.exerciseId().get());
if (m_editData.phaseId().is_set())
data.phaseId(m_editData.phaseId().get());
}
}
else
{
m_editData.exerciseId();
m_editData.phaseId();
}
data.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
data.lastModified(QDateTime::currentMSecsSinceEpoch());
DEBUG_LOG(m_logger) << "onEditItem: Content size = " << m_content.size();
data.content(m_content);
DEBUG_LOG(m_logger) << "Modify FileContent id = " << data.id();
if (!m_requestHelper->startSingleRequest([ = ]()
{
return m_ftc->fileContentModifyRequest(FileContentModifyRequest(data), this);
}))
return;
emit updateItem(m_workingIndex, m_editData);
close();
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onComboFileTypeChanged(int crt)
{
DEBUG_LOG(m_logger) << "onComboFileTypeChanged crt = " << crt;
m_ui->cbFileType->setCurrentIndex(crt);
m_editData.fileType(static_cast<FileManagement::FileType::type>(m_ui->cbFileType->currentData().toInt()));
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onComboFileStatusChanged(int crt)
{
DEBUG_LOG(m_logger) << "onComboFileStatusChanged crt = " << crt;
m_ui->cbFileStatus->setCurrentIndex(crt);
m_editData.fileStatus(static_cast<FileManagement::FileStatus::type>(m_ui->cbFileStatus->currentData().toInt()));
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onComboFileCategoryChanged(int crt)
{
DEBUG_LOG(m_logger) << "onComboFileCategoryChanged crt = " << crt;
m_ui->cbFileCategory->setCurrentIndex(crt);
m_editData.fileCategory(static_cast<FileManagement::FileCategory::type>(m_ui->cbFileCategory->currentData().toInt()));
// if (m_editData.fileCategory() == FileManagement::FileCategory::Exercise)
// m_ui->cbExercises->setEnabled(true);
// else
// m_ui->cbExercises->setEnabled(false);
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onComboExerciseChanged(int crt)
{
DEBUG_LOG(m_logger) << "onComboExerciseChanged crt = " << crt;
m_ui->cbExercises->setCurrentIndex(crt);
if (m_ui->cbExercises->currentData().toInt() > 0)
{
m_editData.exerciseId(m_ui->cbExercises->currentData().toInt());
m_ui->cbPhases->setEnabled(true);
}
else
{
m_editData.exerciseId().reset();
m_editData.phaseId().reset();
m_ui->cbPhases->setEnabled(false);
}
fillPhasesComboBox();
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onComboPhaseChanged(int crt)
{
DEBUG_LOG(m_logger) << "onComboPhaseChanged crt = " << crt;
m_ui->cbPhases->setCurrentIndex(crt);
if (m_ui->cbPhases->currentData().toInt() > 0)
m_editData.phaseId(m_ui->cbPhases->currentData().toInt());
else
m_editData.phaseId().reset();
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::fillExercisesComboBox()
{
DEBUG_LOG(m_logger) << "fillExercisesComboBox";
QSignalBlocker blocker(m_ui->cbExercises);
m_ui->cbExercises->clear();
m_ui->cbExercises->addItem(tr("<not set>"), 0);
auto cbEx = [this] (const ExerciseManagement::Exercise &ex)
{
m_ui->cbExercises->addItem(QString::fromStdString(ex.name()), ex.id());
};
m_exmDtc->exercises(cbEx);
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::fillPhasesComboBox()
{
DEBUG_LOG(m_logger) << "fillPhasesComboBox";
QSignalBlocker blocker(m_ui->cbPhases);
m_ui->cbPhases->clear();
m_ui->cbPhases->addItem(tr("<not set>"), 0);
if (m_editData.exerciseId().is_set())
{
const int exId = m_editData.exerciseId().get();
DEBUG_LOG(m_logger) << "ExId = " << exId;
if (exId > 0)
{
auto cbPhases = [this, exId] (const ExerciseManagement::ExercisePhase &ph)
{
if (ph.exerciseId() == exId)
m_ui->cbPhases->addItem(QString::fromStdString(ph.name()), ph.id());
};
m_exmDtc->exercisePhases(cbPhases);
}
if (m_editData.phaseId().is_set())
m_ui->cbPhases->setCurrentIndex(m_ui->cbPhases->findData(m_editData.phaseId().get()));
}
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onPropertiesClicked()
{
DEBUG_LOG(m_logger) << "onPropertiesClicked";
SetPropertiesDialog *dialog = new SetPropertiesDialog(m_ui->leProperties, this);
dialog->init();
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
}
//--------------------------------------------------------------------------------------------------------------------
void FileContentEditDialog::onCheckUsedStateChanged(int newState)
{
DEBUG_LOG(m_logger) << "onCheckUsedClicked: newState = " << newState;
if (newState == Qt::Checked) // it was unused
m_editData.usedBy(1);
else
m_editData.usedBy(0);
m_ui->lblUses->setText(QLatin1Char('[') + QString::number(m_editData.usedBy()) + QLatin1Char(']'));
}
} // namespace FileManagement
@@ -0,0 +1,93 @@
/**
* @RDE_HEADER@
* FileManagement - Edit FileContent metadata dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-30
*/
#pragma once
#include <FileManagement/logger.h>
#include <Services/FileManagement/flm_dtc.h>
#include <Services/FileManagement/flm_ftc.h>
#include <Services/OperatorManagement/opm_dtc.h>
#include <Services/ExerciseManagement/exm_dtc.h>
#include <Plugins/FileManagement/flm_combobox_gui_plugin_interface.h>
#include <LtsSession/lts_session.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <QModelIndex>
#include <LtsWidgets/lts_frameless_dialog.h>
namespace Ui
{
class FileContentEditDialog;
}
namespace FileManagement
{
class FileContentEditDialog : public LtsWidgets::LtsFramelessDialog
, protected FileManagement::Interface::Ftc::FileContentModifyReplyHandler
{
Q_OBJECT
public:
explicit FileContentEditDialog(QWidget *parent = nullptr);
~FileContentEditDialog();
bool init(LtsSession::LtsSession *session,
const QModelIndex &workingIndex,
bool isAdminMode,
const QString &folderName,
const FileContent &data = FileContent(),
const std::vector<uint8_t> &content = {});
protected:
void onFileContentModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
private:
void getMetaData();
void setMetaData();
void fillExercisesComboBox();
void fillPhasesComboBox();
private Q_SLOTS:
void onAddItem();
void onEditItem();
void onComboFileTypeChanged(int crt);
void onComboFileStatusChanged(int crt);
void onComboFileCategoryChanged(int crt);
void onComboExerciseChanged(int crt);
void onComboPhaseChanged(int crt);
void onPropertiesClicked();
void validate(const QString &fileName);
void onReturnPressed();
void onCheckUsedStateChanged(int newState);
Q_SIGNALS:
void addItem(int &row, const QModelIndex &parent, const FileContent &newData);
void updateItem(const QModelIndex &parent, const FileContent &editData);
private:
QModelIndex m_workingIndex;
FileContent m_editData;
std::vector<uint8_t> m_content;
QString m_exportFileName;
std::shared_ptr<FileManagement::Interface::Dtc> m_dtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc;
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
std::shared_ptr<FileManagement::ForeignGuiComboboxInterface> m_flmGuiCbxIfc;
QString m_folderName;
LtsUtils::RequestHelper *m_requestHelper{nullptr};
Ui::FileContentEditDialog *m_ui{nullptr};
LOGGER_T m_logger;
};
} // namespace FileManagement
@@ -0,0 +1,462 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FileContentEditDialog</class>
<widget class="QWidget" name="FileContentEditDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>941</width>
<height>374</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Edit File Content</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="6">
<spacer name="spacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="8">
<widget class="LtsWidgets::LtsComboBox" name="cbExercises"/>
</item>
<item row="0" column="1" colspan="4">
<widget class="QLineEdit" name="leName">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>File Name</string>
</property>
</widget>
</item>
<item row="2" column="8">
<widget class="LtsWidgets::LtsComboBox" name="cbFileStatus">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="lblTemplate">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Template:</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="lblUsed">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Used:</string>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="LtsWidgets::LtsComboBox" name="cbFileType"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="lblProperties">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Properties:</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="lblUses">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string notr="true">[999]</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="lblLastModified">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Last modified:</string>
</property>
</widget>
</item>
<item row="2" column="7">
<widget class="QLabel" name="lblFileStatus">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>File Status:</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="4">
<widget class="QLineEdit" name="leFolder">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="5" column="1" colspan="4">
<widget class="QLineEdit" name="leProperties">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="6">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="7">
<widget class="QLabel" name="lblPhase">
<property name="text">
<string>Phase:</string>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QLabel" name="lblFileCategory">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>File Category:</string>
</property>
</widget>
</item>
<item row="3" column="7">
<widget class="QLabel" name="lblExercise">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Exercise:</string>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QLabel" name="lblFileType">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>File Type:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkTemplate">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="6" column="1" colspan="4">
<widget class="QLineEdit" name="leLastModified">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="6">
<spacer name="spacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="6">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblOperator">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Operator:</string>
</property>
</widget>
</item>
<item row="1" column="6">
<spacer name="spacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblFileName">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>File Name:</string>
</property>
</widget>
</item>
<item row="5" column="5">
<widget class="QPushButton" name="pbProperties">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Edit</string>
</property>
</widget>
</item>
<item row="5" column="8">
<widget class="LtsWidgets::LtsComboBox" name="cbPhases"/>
</item>
<item row="3" column="4">
<widget class="QCheckBox" name="checkUsed">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="LtsWidgets::LtsComboBox" name="cbFileCategory">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1" colspan="4">
<widget class="QLineEdit" name="leOperator">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblFolder">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Folder:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="lblHidden">
<property name="text">
<string>Is Hidden:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkHidden">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>46</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="LtsWidgets::LtsDialogButtonBox" name="ltsDialogButtonBox" native="true">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsDialogButtonBox</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_dialog_button_box.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LtsWidgets::LtsComboBox</class>
<extends>QComboBox</extends>
<header>LtsWidgets/lts_combo_box.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>leName</tabstop>
<tabstop>leFolder</tabstop>
<tabstop>leOperator</tabstop>
<tabstop>cbFileType</tabstop>
<tabstop>cbFileCategory</tabstop>
<tabstop>cbFileStatus</tabstop>
<tabstop>checkTemplate</tabstop>
<tabstop>checkUsed</tabstop>
<tabstop>cbExercises</tabstop>
<tabstop>leProperties</tabstop>
<tabstop>pbProperties</tabstop>
<tabstop>leLastModified</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
+158
View File
@@ -0,0 +1,158 @@
/**
* @RDE_HEADER@
* FileManagement - Rename Folder Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-22
*/
#include "flm_edit_folder.h"
#include "ui_flm_edit_folder.h"
#include <LtsSession/lts_session_data.h>
namespace FileManagement
{
//------------------------------------------------------------------------------------------------------------------------
FolderEditDialog::FolderEditDialog(QWidget *parent)
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_ui(new Ui::FolderEditDialog)
, m_workingIndex(QModelIndex())
, m_logger(getLogger("FolderEditDialog"))
{
m_ui->setupUi(this);
connect(m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &FolderEditDialog::close);
connect(m_ui->leName, &QLineEdit::textChanged, this, &FolderEditDialog::validate);
connect(m_ui->leName, &QLineEdit::returnPressed, this, &FolderEditDialog::onReturnPressed);
m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Apply)->hide();
m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Ok)->hide();
m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Add)->setDisabled(m_ui->leName->text().isEmpty());
}
//------------------------------------------------------------------------------------------------------------------------
FolderEditDialog::~FolderEditDialog()
{
delete m_ui;
delete m_requestHelper;
}
//------------------------------------------------------------------------------------------------------------------------
void FolderEditDialog::validate(const QString &folderName)
{
m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Add)->setDisabled(folderName.isEmpty());
}
//------------------------------------------------------------------------------------------------------------------------
void FolderEditDialog::onReturnPressed()
{
if (m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Add)->isEnabled())
m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Add)->setFocus();
}
//------------------------------------------------------------------------------------------------------------------------
bool FolderEditDialog::init(const QModelIndex &workingIndex, const int &folderId, const int &parentFolderId,
const std::shared_ptr<FileManagement::Interface::Dtc> &dtc,
const std::shared_ptr<FileManagement::Interface::Ftc> &ftc,
bool isAdminMode,
const FileManagement::Folder &data)
{
if (!dtc || !ftc)
return false;
m_workingIndex = workingIndex;
m_folderId = folderId;
m_parentFolderId = parentFolderId;
m_editData = data;
m_dtc = dtc;
m_ftc = ftc;
setWindowTitle(tr("Create New Folder"));
if (m_folderId > 0) //EditMode
{
m_ui->leName->setText(QString::fromStdString(m_editData.name()));
m_ui->ltsDialogButtonBox->setText(LtsWidgets::DialogButton::Add, tr("Rename"));
setWindowTitle(tr("Edit Folder"));
}
else if (data.id() > 0) // add folder from copy/paste
m_ui->leName->setText(QString::fromStdString(m_editData.name()));
m_ui->ltsDialogButtonBox->connectButton(LtsWidgets::DialogButton::Add, this, &FolderEditDialog::onAddEditFolder);
m_ui->cbHidden->setVisible(isAdminMode);
m_ui->cbHidden->setChecked(m_editData.isHidden());
#ifdef TABLET_MODE
m_ui->leName->setFocusPolicy(Qt::ClickFocus);
m_ui->leName->clearFocus();
#else
m_ui->leName->setFocus();
#endif
return true;
}
//------------------------------------------------------------------------------------------------------------------------
void FolderEditDialog::onAddEditFolder()
{
if (apply())
{
close();
DEBUG_LOG(m_logger) << "Added / Edited folder " << m_editData.name();
}
}
//------------------------------------------------------------------------------------------------------------------------
bool FolderEditDialog::apply()
{
if (m_folderId > 0)
// already exists (rename folder)
{
DEBUG_LOG(m_logger) << "Rename folder id = " << m_folderId;
m_requestHelper->addRequest([this]()
{
FolderModifyRequest req;
req.id(m_folderId);
req.name(m_ui->leName->text().toStdString());
req.path(m_dtc->folder(m_folderId).path());
req.isEditable(true);
req.isHidden(m_ui->cbHidden->isChecked());
req.parentId(m_dtc->folder(m_folderId).parentId());
req.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
return m_ftc->folderModifyRequest(req, this);
});
}
else
// create new folder
{
DEBUG_LOG(m_logger) << "Create new folder";
FolderModifyRequest req;
req.name(m_ui->leName->text().toStdString());
req.isEditable(true);
req.isHidden(m_ui->cbHidden->isChecked());
req.parentId(m_parentFolderId);
std::vector<int> parentPath;
if (m_parentFolderId > 0)
{
FileManagement::Folder fld = m_dtc->folder(m_parentFolderId);
parentPath = fld.path();
}
req.path(parentPath);
req.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
m_requestHelper->addRequest([req, this]()
{
return m_ftc->folderModifyRequest(req, this);
});
}
// do nothing on failure - rh's message is enough
return m_requestHelper->startRequests(); // return success or failure
}
} // namespace FileManagement;
+67
View File
@@ -0,0 +1,67 @@
/**
* @RDE_HEADER@
* FileManagement - Rename Folder Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-22
*/
#pragma once
#include <LtsWidgets/lts_frameless_dialog.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include <Services/FileManagement/flm_dtc.h>
#include <Services/FileManagement/flm_ftc.h>
#include <Services/FileManagement/logger.h>
#include <QModelIndex>
namespace Ui
{
class FolderEditDialog;
}
namespace FileManagement
{
class FolderEditDialog : public LtsWidgets::LtsFramelessDialog
, protected FileManagement::Interface::Ftc::FolderModifyReplyHandler
{
Q_OBJECT
public:
explicit FolderEditDialog(QWidget *parent = nullptr);
~FolderEditDialog();
bool init(const QModelIndex &workingIndex, const int &folderId, const int &parentFolderId,
const std::shared_ptr<FileManagement::Interface::Dtc> &dtc,
const std::shared_ptr<FileManagement::Interface::Ftc> &ftc,
bool isAdminMode,
const Folder &data = Folder());
bool apply();
protected:
void onFolderModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
private Q_SLOTS:
void onAddEditFolder();
void validate(const QString &folderName);
void onReturnPressed();
private:
std::shared_ptr<FileManagement::Interface::Dtc> m_dtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc;
LtsUtils::RequestHelper *m_requestHelper{nullptr};
Ui::FolderEditDialog *m_ui{nullptr};
QModelIndex m_workingIndex;
Folder m_editData;
int m_folderId{-1};
int m_parentFolderId{-1};
LOGGER_T m_logger;
};
}
+64
View File
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FolderEditDialog</class>
<widget class="QWidget" name="FolderEditDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>296</width>
<height>108</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Edit Folder</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="LtsWidgets::LtsDialogButtonBox" name="ltsDialogButtonBox" native="true">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<widget class="QCheckBox" name="cbHidden">
<property name="text">
<string>Is Hidden</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblName">
<property name="toolTip">
<string>Folder Name</string>
</property>
<property name="text">
<string>Folder Name:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="leName">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsDialogButtonBox</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_dialog_button_box.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,988 @@
/**
* @RDE_HEADER@
* Gui Plugin for FileManagement Explorer
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, SLSE, 2017-03-31
*/
#include "flm_explorer_gui_plugin.h"
#include "flm_dialog.h"
#include "flm_preview_playback.h"
#include "flm_get_content_async.h"
#include "HQReports/flm_hq_report_edit.h"
#include <ngltools/ngltools_dtg.h>
#include <LtsWidgets/lts_events.h>
#include <LtsWidgets/lts_base_layout_widget.h>
#include <LtsUtilsCore/dds_vector.h>
#include <LtsUtilsCore/dds_vector_to_pixmap.h>
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <Services/FileManagement/flm_dtc.h>
#include <Services/FileManagement/flm_ftc.h>
#include <Services/OperatorManagement/opm_dtc.h>
#include <Services/ExerciseManagement/exm_dtc.h>
#include <Services/FileManagement/flm_operator_rights.h>
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
#include <Plugins/ExerciseManagement/exm_data_plugin_interface.h>
#include <TopicEditor/topic_editor.h>
#include <QBuffer>
#include <QCoreApplication>
#include <QPointer>
#include <QFileInfo>
#include <QTextStream>
#include <QJsonDocument>
#include <QVector>
#include <QUrlQuery>
//----------------------------------------------------------------------------------------------------
namespace FileManagement
{
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
{
return std::make_shared<InterfaceImpl>(session);
}
const QString InterfaceImpl::s_flmExplorerScheme = QStringLiteral("FileManagement");
const QString InterfaceImpl::s_flmHQReportScheme = QStringLiteral("flmHQReport");
//----------------------------------------------------------------------------------------------------
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Flm.Explorer"))
, m_requestHelper(new LtsUtils::RequestHelper(this))
{
qApp->installEventFilter(this);
}
//----------------------------------------------------------------------------------------------------
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
if (m_session->isReplayPartition())
return QVector<LtsWidgets::PluginData>();
if (appId() == LtsAppDescriptor::App::OC && strcmp(PROJECTBUILD, "guez") == 0)
return QVector<LtsWidgets::PluginData>();
QVector<LtsWidgets::PluginData> ret;
if (m_session->exerciseId() != 0)
{
{
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.menuText = tr("Organize Library");
plData.tooltip = tr("Organize Library");
plData.identifier = QLatin1String("flmFileExplorer");
plData.menuIcon = QIcon(QLatin1String("icon:organize_library.svg"));
plData.operatorRight = OperatorRights::FileManagementFilesEdit;
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowFileManagementDialog(parent);
};
ret.append(plData);
}
{
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.menuText = tr("HQ Report");
plData.tooltip = tr("HQ Report");
plData.identifier = s_flmHQReportScheme;
plData.menuIcon = QIcon(QLatin1String("icon:organize_library.svg"));
plData.operatorRight = OperatorRights::FileManagementFilesEdit;
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowHQReportDialog(parent);
};
ret.append(plData);
}
}
else // ex0
{
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.menuText = tr("Manage Library");
plData.tooltip = tr("Manage Library");
plData.identifier = QLatin1String("flmFileAdmin");
plData.menuIcon = QIcon(QLatin1String("icon:organize_library_admin.svg"));
plData.operatorRight = OperatorRights::FileManagementFileAdmin;
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
plData.createWidgetFunc = [this](QWidget * parent)
{
return onShowFileManagementAdminDialog(parent);
};
ret.append(plData);
}
return ret;
}
//----------------------------------------------------------------------------------------------------
bool InterfaceImpl::fetchInterfaces()
{
// Own
DEBUG_LOG(m_logger) << "Fetching FLM interfaces for " << m_session->domainId() << ", " << m_session->exerciseId() << ", " << m_session->partitionId();
if (!m_session->getDtc<FileManagement::DataInterface>(m_dtc))
{
DEBUG_LOG(m_logger) << "getDtc for FileManagement::DataInterface failed.";
return false;
}
if (!m_session->getFtc<FileManagement::DataInterface>(m_ftc))
{
DEBUG_LOG(m_logger) << "getFtc for FileManagement::DataInterface failed.";
return false;
}
// Own namespace, but foreign
if (!m_session->getForeignGuiInterface<FileManagement::ForeignGuiComboboxInterface>(m_flmGuiCbxIfc))
{
DEBUG_LOG(m_logger) << "getForeignGuiInterface for FileManagement::ForeignGuiComboboxInterface failed.";
return false;
}
// Foreign
if (!m_session->getDtc<OperatorManagement::DataInterface>(m_opmDtc))
{
DEBUG_LOG(m_logger) << "getDtc for OperatorManagement::DataInterface failed.";
return false;
}
if (!m_session->getDtc<ExerciseManagement::DataInterface>(m_exmDtc))
{
DEBUG_LOG(m_logger) << "getDtc for ExerciseManagement::DataInterface failed.";
return false;
}
return true;
}
//----------------------------------------------------------------------------------------------------
void InterfaceImpl::clearInterfaces()
{
m_dtc = nullptr;
m_ftc = nullptr;
m_flmGuiCbxIfc = nullptr;
m_opmDtc = nullptr;
m_exmDtc = nullptr;
}
//----------------------------------------------------------------------------------------------------
QString InterfaceImpl::menuGroup() const
{
return m_session->exerciseId() == 0 ? tr("Document Library") : tr("Exercise Documents");
}
//----------------------------------------------------------------------------------------------------
LtsWidgets::LtsDialog *InterfaceImpl::onShowFileManagementDialog(QWidget *parent)
{
DEBUG_LOG(m_logger) << "onShowFileManagementDialog";
FileManagementDialogTab *dialog = new FileManagementDialogTab(menuGroup(), parent);
if (!dialog->init(m_session, FileDialogMode::User))
{
ERROR_LOG(m_logger) << "Failed to init dialog";
dialog->deleteLater();
}
dialog->show();
return dialog;
}
//----------------------------------------------------------------------------------------------------
LtsWidgets::LtsDialog *InterfaceImpl::onShowFileManagementAdminDialog(QWidget *parent)
{
DEBUG_LOG(m_logger) << "onShowFileManagementDialog";
FileManagementDialogTab *dialog = new FileManagementDialogTab(menuGroup(), parent);
if (!dialog->init(m_session, FileDialogMode::Admin))
{
ERROR_LOG(m_logger) << "Failed to init dialog";
dialog->deleteLater();
}
dialog->show();
return dialog;
}
LtsWidgets::LtsDialog *InterfaceImpl::onShowHQReportDialog(QWidget *parent)
{
DEBUG_LOG(m_logger) << "onShowHQReportDialog";
HQReportEdit *dialog = new HQReportEdit(menuGroup(), parent);
if (!dialog->init(m_session))
{
ERROR_LOG(m_logger) << "Failed to init dialog";
dialog->deleteLater();
}
dialog->show();
return dialog;
}
void InterfaceImpl::onShowHQReportDialog(int partyId)
{
HQReportEdit *dialog = new HQReportEdit(menuGroup());
if (!dialog->init(m_session, partyId))
{
delete dialog;
return;
}
m_session->addWidget(dialog, menuGroup(), s_flmHQReportScheme, LtsWidgets::LayoutArea::eDialogTab);
}
// only for testing, FileSave mode with jpg filter, not used
//----------------------------------------------------------------------------------------------------
LtsWidgets::LtsFramelessDialog *InterfaceImpl::onSelectFileDialog(QWidget *parent)
{
DEBUG_LOG(m_logger) << "onSelectFileDialog";
FileManagementDialog *dialog = new FileManagementDialog(parent);
if (!dialog->init(m_session, FileDialogMode::SaveFile, {FileType::Jpg, FileType::Png}, 6, tr("Save File")))
{
ERROR_LOG(m_logger) << "Failed to init dialog";
dialog->deleteLater();
}
dialog->show();
return dialog;
}
//----------------------------------------------------------------------------------------------------
int InterfaceImpl::saveFileContent(QWidget *parent,
FileType targetFileType,
int exerciseId,
const QByteArray &content,
int initialFolderId,
const QString &properties)
{
QPointer<FileManagement::FileManagementDialog> dialog = new FileManagement::FileManagementDialog(parent);
if (initialFolderId == 0 && exerciseId > 0)
initialFolderId = m_dtc->getExerciseFolderId(exerciseId);
DEBUG_LOG(m_logger) << "Initial folder Id = " << initialFolderId;
if (!dialog->init(m_session, FileManagement::FileDialogMode::SaveFile, QVector<FileType>() << targetFileType, initialFolderId)) //, fileTypes, folderId, buttonName))
{
ERROR_LOG(m_logger) << "Failed to init save dialog";
delete dialog;
return 0;
}
const int res = dialog->exec(); // block events explicitly
if (res != QDialog::Accepted)
{
delete dialog;
DEBUG_LOG(m_logger) << "Save dialog closed by user";
return 0;
}
const int folderId = dialog->getSelectedFolderId();
const QString fileName = dialog->getFileName();
const FileManagement::FileContent fileToModify = dialog->getSelectedFile();
delete dialog;
INFO_LOG(m_logger) << "FileToSave: Folder id = " << folderId
<< ", File id = " << fileToModify.id()
<< ", File name = " << fileName;
if (folderId < 1 || fileName.isEmpty())
{
DEBUG_LOG(m_logger) << "Save dialog closed by user";
return 0;
}
if (fileToModify.id() > 0) // existing file
{
bool doNotOverwrite = (LtsWidgets::Button::No == LtsWidgets::LtsMessageDialog::showMessage( m_session->baseLayout()
, tr("Do you want to overwrite the existing file?")
, tr("Overwrite")
, LtsWidgets::Behaviour::Modal
, LtsWidgets::Button::Yes | LtsWidgets::Button::No));
if (doNotOverwrite)
{
DEBUG_LOG(m_logger) << "File not overwritten as chosen by user";
return 0;
}
}
FileManagement::FileContentModifyRequest request;
request.id(fileToModify.id());
request.name(fileName.toStdString());
request.isTemplate(fileToModify.isTemplate());
request.folderId(folderId);
const QVector<int> fldPath = LtsUtils::convert<QVector<int>>(m_dtc->folder(folderId).path());
if (fileToModify.id() > 0)
request.fileCategory(fileToModify.fileCategory());
else
{
if (fldPath.contains(FileManagement::MainFolder::UserDocuments))
request.fileCategory(FileManagement::FileCategory::User);
else if (fldPath.contains(FileManagement::MainFolder::ExerciseDocuments))
request.fileCategory(FileManagement::FileCategory::Exercise);
else
request.fileCategory(FileManagement::FileCategory::Global);
}
request.fileType(targetFileType);
request.fileStatus(FileManagement::FileStatus::Valid);
request.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
request.content(LtsUtils::convert<std::vector<uint8_t>>(content));
request.isUsedBy(false);
request.usedBy(0);
request.lastModified(QDateTime::currentMSecsSinceEpoch());
// save exercise and phase for only for exercise documents ?!
if (exerciseId > 0 && request.fileCategory() == FileManagement::FileCategory::Exercise)
{
request.exerciseId(exerciseId);
if (fileToModify.phaseId().is_set())
request.phaseId(fileToModify.phaseId().get());
else
{
// get phase id from selected folder, if that is a phase folder
int phId = (fldPath.size() > 3) ? m_dtc->getExerciseId(fldPath.at(3)) : 0;
if (phId > 0)
request.phaseId(phId);
}
}
else
{
request.exerciseId();
request.phaseId();
}
if (!properties.isEmpty())
request.properties(properties.toStdString());
else
request.properties(fileToModify.properties());
// for xml files that contain XmlType key, write this (key, value) in properties
if (targetFileType == FileManagement::FileType::Xml && !content.isEmpty())
{
QString xmlTypeValue = hasXmlType(content);
if (!xmlTypeValue.isEmpty())
{
QJsonObject obj;
if (fileToModify.properties().size() != 0)
{
const QByteArray &attributesJson = QByteArray::fromRawData(fileToModify.properties().c_str(),
fileToModify.properties().size());
QJsonParseError parseError;
QJsonDocument jDoc(QJsonDocument::fromJson(attributesJson, &parseError));
if (parseError.error == QJsonParseError::NoError)
obj = jDoc.object();
}
obj[QStringLiteral("XmlType")] = xmlTypeValue;
request.properties(QJsonDocument(obj).toJson(QJsonDocument::Compact).toStdString());
}
}
if (!m_requestHelper->startSingleRequest([this, request]()
{
return m_ftc->fileContentModifyRequest(request, this);
}))
return 0;
int fileId = m_requestHelper->getRepliedId();
DEBUG_LOG(m_logger) << "saveFileContent: File Id = " << fileId;
return fileId;
}
//----------------------------------------------------------------------------------------------------
int InterfaceImpl::getFileId(FileManagement::FileType fileType, const QString &fileName, int exId, int phId) const
{
return m_dtc->getFileId(fileType, fileName, exId, phId);
}
//----------------------------------------------------------------------------------------------------
QString InterfaceImpl::getFileName(int fileId) const
{
return QString::fromStdString(m_dtc->fileContent(fileId).name());
}
//----------------------------------------------------------------------------------------------------
bool InterfaceImpl::saveContent(int fileId, const QByteArray &content, const QString &properties)
{
FileManagement::FileContent fileToModify = m_dtc->fileContent(fileId);
if (fileToModify.id() <= 0)
return false;
FileManagement::FileContentModifyRequest request;
request.id(fileId);
request.name(fileToModify.name());
request.isTemplate(fileToModify.isTemplate());
request.folderId(fileToModify.folderId());
request.fileCategory(fileToModify.fileCategory());
request.fileType(fileToModify.fileType());
request.fileStatus(fileToModify.fileStatus());
request.isUsedBy(fileToModify.isUsedBy());
request.usedBy(fileToModify.usedBy());
request.exerciseId(fileToModify.exerciseId());
request.phaseId(fileToModify.phaseId());
request.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
request.lastModified(QDateTime::currentMSecsSinceEpoch());
request.content(LtsUtils::convert<std::vector<uint8_t>>(content));
if (!properties.isEmpty())
request.properties(properties.toStdString());
else
request.properties(fileToModify.properties());
if (!m_requestHelper->startSingleRequest([this, request]()
{
return m_ftc->fileContentModifyRequest(request, this);
}))
return false;
return true;
}
//----------------------------------------------------------------------------------------------------
int InterfaceImpl::newFileContent(FileContent fc, const QByteArray &content)
{
FileManagement::FileContentModifyRequest request;
request.name(fc.name());
request.isTemplate(fc.isTemplate());
request.folderId(fc.folderId());
request.fileCategory(fc.fileCategory());
request.fileType(fc.fileType());
request.fileStatus(fc.fileStatus());
request.isUsedBy(fc.isUsedBy());
request.usedBy(fc.usedBy());
request.exerciseId(fc.exerciseId());
request.phaseId(fc.phaseId());
request.properties(fc.properties());
request.operatorId(fc.operatorId());
request.lastModified(QDateTime::currentMSecsSinceEpoch());
request.content(LtsUtils::convert<std::vector<uint8_t>>(content));
if (!m_requestHelper->startSingleRequest([this, request]()
{
return m_ftc->fileContentModifyRequest(request, this);
}))
return 0;
return m_requestHelper->getRepliedId();
}
//----------------------------------------------------------------------------------------------------
bool InterfaceImpl::deleteFileContent(int fileId)
{
FileManagement::FileContent fc = m_dtc->fileContent(fileId);
if (fc.id() <= 0)
return false;
if (fc.fileStatus() == FileManagement::FileStatus::Deleted)
{
WARNING_LOG(m_logger) << "File content already deleted for id = " << fileId;
return true; // file is deleted, nothing more to do
}
FileManagement::FileContentChangeStatusRequest request;
request.id(fileId);
request.fileStatus(FileManagement::FileStatus::Deleted);
request.lastModified(QDateTime::currentMSecsSinceEpoch());
request.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
if (!m_requestHelper->startSingleRequest([this, request]()
{
return m_ftc->fileContentChangeStatusRequest(request, this);
}))
return false;
return true;
}
//----------------------------------------------------------------------------------------------------
int InterfaceImpl::loadFileContent(QWidget *parent,
QByteArray &content,
const QVector<FileType> &fileTypes,
int exerciseId,
const QString &xmlType,
int initialFolderId)
{
if (initialFolderId == 0)
{
if (exerciseId > 0)
initialFolderId = m_dtc->getExerciseFolderId(exerciseId);
else
initialFolderId = 1;
}
DEBUG_LOG(m_logger) << "Initial folder Id = " << initialFolderId;
QPointer<FileManagement::FileManagementDialog> dialog = new FileManagement::FileManagementDialog(parent);
if (!dialog->init(m_session, FileManagement::FileDialogMode::OpenFile, fileTypes, initialFolderId, xmlType))
{
ERROR_LOG(m_logger) << "Failed to init open dialog";
delete dialog;
return 0;
}
const int res = dialog->exec(); // block events explicitly
if (res != QDialog::Accepted)
{
delete dialog;
return 0;
}
const int fileId = dialog->getSelectedFileId();
delete dialog;
INFO_LOG(m_logger) << "FileToLoad: File id = " << fileId;
if (fileId < 1)
return 0;
auto cbRet = [&content](const Core::FunctionReply & baseReply)
{
const auto &replyObject = static_cast<const FileManagement::GetFileContentDataReply &>(baseReply);
content = LtsUtils::toQByteArray(replyObject.content());
};
FileManagement::GetFileContentDataRequest req;
req.fileContentId(fileId);
auto cb = [req, this]()
{
return m_ftc->getFileContentDataRequest(req, this);
};
if (!m_requestHelper->startSingleRequest(cb, cbRet))
return 0;
return fileId;
}
//----------------------------------------------------------------------------------------------------
int InterfaceImpl::selectFileContent(QWidget *parent,
const QVector<FileType> &fileTypes,
int exerciseId,
int initialFolderId)
{
if (initialFolderId == 0)
{
if (exerciseId > 0)
initialFolderId = m_dtc->getExerciseFolderId(exerciseId);
else
initialFolderId = 1;
}
DEBUG_LOG(m_logger) << "Initial folder Id = " << initialFolderId;
QPointer<FileManagement::FileManagementDialog> dialog = new FileManagement::FileManagementDialog(parent);
if (!dialog->init(m_session, FileManagement::FileDialogMode::OpenFile, fileTypes, initialFolderId))
{
ERROR_LOG(m_logger) << "Failed to init open dialog";
delete dialog;
return 0;
}
const int res = dialog->exec(); // block events explicitly
if (res != QDialog::Accepted)
{
delete dialog;
return 0;
}
const int fileId = dialog->getSelectedFileId();
delete dialog;
return fileId;
}
//----------------------------------------------------------------------------------------------------
bool InterfaceImpl::loadContent(int fileId, QByteArray &content, bool bQuiet)
{
DEBUG_LOG(m_logger) << "loadContent: File id = " << fileId;
if (fileId < 1)
return false;
auto cbRet = [&content](const Core::FunctionReply &baseReply)
{
const auto &replyObject = static_cast<const FileManagement::GetFileContentDataReply &>(baseReply);
content = LtsUtils::toQByteArray(replyObject.content());
};
FileManagement::GetFileContentDataRequest req;
req.fileContentId(fileId);
auto cb = [req, this]()
{
return m_ftc->getFileContentDataRequest(req, this);
};
const bool bOldQuiet = m_requestHelper->quiet();
m_requestHelper->setQuiet(bQuiet);
auto ret = m_requestHelper->startSingleRequest(cb, cbRet);
m_requestHelper->setQuiet(bOldQuiet);
return ret;
}
// check if content is not empty, it is parseable and it contains a specified XmlType key
//----------------------------------------------------------------------------------------------------
bool InterfaceImpl::isXmlType(const QByteArray &content, const QString &searchedType) const
{
return hasXmlType(content) == searchedType;
}
// return value of XmlType key, if exists
//----------------------------------------------------------------------------------------------------
QString InterfaceImpl::hasXmlType(const QByteArray &content) const
{
if (content.isEmpty())
{
WARNING_LOG(m_logger) << "Empty xml file content!";
return QString();
}
QJsonParseError parserError;
const QJsonDocument doc(QJsonDocument::fromJson(content, &parserError));
if (parserError.error != QJsonParseError::NoError)
{
WARNING_LOG(m_logger) << "Error parsing json document: " << parserError.errorString();
return QString();
}
DEBUG_LOG(m_logger) << "json to parse: " << doc.toJson();
const QJsonObject obj(doc.object());
QString type = obj[QStringLiteral("XmlType")].toString();
return type;
}
bool InterfaceImpl::eventFilter(QObject *obj, QEvent *event)
{
if (obj == qApp &&
!event->isAccepted() &&
event->type() == LtsWidgets::SaveImageEvent::saveImageEventId())
{
auto ev = static_cast<LtsWidgets::SaveImageEvent*>(event);
const auto isChildOfSession = [this](QWidget *w)
{
if (!w)
return true;
auto baseLayout = m_session->baseLayout();
return baseLayout->isAncestorOf(w);
};
if (isChildOfSession(ev->widget()))
{
QBuffer buf;
ev->pixmap().save(&buf, "PNG");
saveFileContent(ev->widget(), FileManagement::FileType::Png, m_session->exerciseId(), buf.data());
event->accept();
return true;
}
}
if (obj == qApp &&
!event->isAccepted() &&
event->type() == LtsWidgets::LtsLinkEvent::eventTypeId())
{
auto ev = static_cast<LtsWidgets::LtsLinkEvent*>(event);
const auto isChildOfSession = [this](QWidget *w)
{
if (!w)
return true;
auto baseLayout = m_session->baseLayout();
return baseLayout->isAncestorOf(w);
};
if (isChildOfSession(ev->sourceBaseLayoutWidget()) && ev->url().host() == s_flmHQReportScheme.toLower())
{
QUrlQuery query(ev->url()); // url: //flmHQReport/?party=%2&folder=%3&file=%4
const int partyId = query.queryItemValue(QStringLiteral("party")).toInt();
DEBUG_LOG(m_logger) << "[flm_explorer] partyId: " << partyId;
onShowHQReportDialog(partyId);
event->accept();
return true;
}
}
return QObject::eventFilter(obj, event);
}
//------------------------------------------------------------------------------
TopicEditorBase::TopicEditor *InterfaceImpl::createTopicEditor(const TopicEditorBase::TopicData &data)
{
FileContentPreviewPlaybackWidget *previewWidget = new FileContentPreviewPlaybackWidget(m_ftc, nullptr);
FileTopicEditor *editor = new FileTopicEditor(m_session, previewWidget, m_ftc);
if (!editor->fetchInterfaces())
{
// pDialog is already reparented at this point
delete editor;
return nullptr;
}
editor->setTopicData(data);
return editor;
}
//------------------------------------------------------------------------------
InterfaceImpl::TopicReplayInterface::TopicReplayInterface(const std::shared_ptr<FileManagement::Interface::Dtc> &dtc,
const std::shared_ptr<FileManagement::Interface::Ftc> &ftc)
: m_dtc(dtc)
, m_ftc(ftc)
, m_logger(getLogger(pluginName()))
{
}
//------------------------------------------------------------------------------
InterfaceImpl::TopicReplayInterface::~TopicReplayInterface()
{
if (m_previewWidget != nullptr)
m_previewWidget->deleteLater();
m_previewWidget = nullptr;
}
//------------------------------------------------------------------------------
QWidget *InterfaceImpl::TopicReplayInterface::createWidget()
{
if (!m_previewWidget)
m_previewWidget = new FileManagement::FileContentPreviewPlaybackWidget(m_ftc, nullptr);
return m_previewWidget;
}
//------------------------------------------------------------------------------
bool InterfaceImpl::TopicReplayInterface::playbackInit(const QJsonObject &attributes)
{
FileManagement::FileContent fc;
int fileId = attributes.value(QStringLiteral("FileId")).toInt();
int pageNo = attributes.value(QStringLiteral("PageNo")).toInt();
int zoomLevel = attributes.value(QStringLiteral("ZoomLevel")).toInt();
int rotation = attributes.value(QStringLiteral("Rotation")).toInt();
QString userText = attributes.value(QStringLiteral("UserText")).toString();
if (fileId > 0)
fc = m_dtc->fileContent(fileId);
else
fc.fileType(FileManagement::FileType_def::Text); // TODO: is this really the only possibility?
if (!m_previewWidget)
{
ERROR_LOG(m_logger) << "Preview widget not available for fileId = " << fileId;
return false;
}
if (!m_previewWidget->init(fc, pageNo, zoomLevel / 100., rotation, 0 /* TODO: duration ? */, userText))
{
ERROR_LOG(m_logger) << "Preview widget cannot be initialized for fileId = " << fileId;
return false;
}
return true;
}
//------------------------------------------------------------------------------
bool InterfaceImpl::TopicReplayInterface::exportTopic(const QJsonObject &attributes,
const QString &folderPath,
TopicEditorBase::ExportNotifier *pExportNotifier)
{
const QString &strPathToFile = folderPath;
int fileId = attributes.value(QStringLiteral("FileId")).toInt();
if (fileId <= 0)
{
QString userText = attributes.value(QStringLiteral("UserText")).toString();
if (!userText.size())
{
pExportNotifier->setExportFailed();
return false;
}
QString strFileName(QDateTime::currentDateTime().toString(QStringLiteral("mmzzz")) + QStringLiteral(".html"));
strFileName.remove(QLatin1Char('\n')); // New line breaks html export
saveFile(strPathToFile + strFileName, LtsUtils::convert<std::vector<uint8_t>>(userText.toUtf8()), false);
pExportNotifier->setExportSuccessful(strFileName);
return true;
}
// is a file
DEBUG_LOG(m_logger) << "Trying to export file with id " << fileId << " to " << strPathToFile;
FileManagement::FileContent fc = m_dtc->fileContent(fileId);
GetFileContentAsync *getFileContent = new GetFileContentAsync(fc.id(), m_ftc);
connect(getFileContent, &GetFileContentAsync::signalDone,
getFileContent, [pExportNotifier, getFileContent, fc, strPathToFile]()
{
qWarning() << Q_FUNC_INFO << "file content arrived!";
const std::vector<uint8_t> &content = getFileContent->content();
QString strFileName(QString::number(fc.id()));
switch (fc.fileType().underlying())
{
case FileManagement::FileType::Png:
{
strFileName += QStringLiteral(".png");
QFile file(strPathToFile + strFileName);
if (file.open(QIODevice::WriteOnly))
file.write(LtsUtils::toQByteArray(content));
break;
}
case FileManagement::FileType::Jpg:
{
strFileName += QStringLiteral(".jpg");
QFile file(strPathToFile + strFileName);
if (file.open(QIODevice::WriteOnly))
file.write(LtsUtils::toQByteArray(content));
break;
}
case FileManagement::FileType::Text:
strFileName += QStringLiteral(".txt");
saveFile(strPathToFile + strFileName, content, false);
break;
case FileManagement::FileType::EvaluationSchema:
case FileManagement::FileType::Xml:
strFileName += QStringLiteral(".xml");
saveFile(strPathToFile + strFileName, content, false);
break;
case FileManagement::FileType::TacticalPlan:
strFileName += QStringLiteral(".TacticalPlan");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::OperatorFavourite:
strFileName += QStringLiteral(".OperatorFavourite");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::Pdf:
strFileName += QStringLiteral(".pdf");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::OperatorDefinedSymbol:
strFileName += QStringLiteral(".OperatorDefinedSymbol");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::MSOfficeDocument:
strFileName += QStringLiteral(".docx");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::MSOfficeDocument97:
strFileName += QStringLiteral(".doc");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::MSOfficePresentation:
strFileName += QStringLiteral(".pptx");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::MSOfficePresentation97:
strFileName += QStringLiteral(".ppt");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::MSOfficeSpreadsheet:
strFileName += QStringLiteral(".xlsx");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::MSOfficeSpreadsheet97:
strFileName += QStringLiteral(".xls");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::OpenOfficeDocument:
strFileName += QStringLiteral(".odt");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::OpenOfficePresentation:
strFileName += QStringLiteral(".odp");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::OpenOfficeSpreadsheet:
strFileName += QStringLiteral(".ods");
saveFile(strPathToFile + strFileName, content);
break;
case FileManagement::FileType::Unknown:
strFileName += QStringLiteral(".Unknown");
saveFile(strPathToFile + strFileName, content);
break;
}
pExportNotifier->setExportSuccessful(strFileName);
});
connect(getFileContent, &GetFileContentAsync::signalFailed,
pExportNotifier, &TopicEditorBase::ExportNotifier::exportFailed);
connect(getFileContent, &GetFileContentAsync::signalDone,
getFileContent, &QObject::deleteLater);
connect(getFileContent, &GetFileContentAsync::signalFailed,
getFileContent, &QObject::deleteLater);
qWarning() << Q_FUNC_INFO << "now waiting for the file content to arrive ...";
return true;
}
//------------------------------------------------------------------------------
void InterfaceImpl::TopicReplayInterface::saveFile(const QString &strPathToFile, const std::vector<uint8_t> &content, bool binary)
{
QFile file(strPathToFile);
if (!file.open(QIODevice::WriteOnly))
return;
if (binary)
{
file.write(LtsUtils::toQByteArray(content));
}
else
{
QTextStream stream(&file);
stream << LtsUtils::toQByteArray(content);
}
}
} // namespace FileManagement
@@ -0,0 +1,164 @@
/**
* @RDE_HEADER@
* Gui Plugin for FileManagement Explorer
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, SLSE, 2017-03-31
*/
#pragma once
#include <Services/FileManagement/logger.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <OperatorManagement/opm_dtc.h>
#include <ExerciseManagement/exm_dtc.h>
#include <LtsWidgets/lts_frameless_dialog.h>
#include <LtsUtilsGuiDds/request_helper.h>
#include "flm_dialog_model_file.h"
namespace TopicEditorBase { struct TopicData; }
namespace FileManagement
{
class ForeignGuiComboboxInterface;
class FileContentPreviewPlaybackWidget;
//----------------------------------------------------------------------------------
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
{
Q_PLUGIN_METADATA(IID "gui:3:flm.explorer")
Q_INTERFACES(GuiPluginBase::Plugin)
Q_OBJECT
public:
explicit GuiPlugin() = default;
~GuiPlugin() = default;
QString pluginName() override { return QStringLiteral("FileManagementExplorerGui"); }
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return (partition == IDL::PartitionType::Global ||
partition == IDL::PartitionType::Exercise ||
partition == IDL::PartitionType::Replay);
}
};
class InterfaceImpl final : public QObject, public GuiPluginBase::Interface, public ForeignGuiInterface
, public FileManagement::Interface::Ftc::GetFileContentDataReplyHandler
, public FileManagement::Interface::Ftc::FileContentModifyReplyHandler
, public FileManagement::Interface::Ftc::FileContentChangeStatusReplyHandler
{
Q_OBJECT
public:
explicit InterfaceImpl(LtsSession::LtsSession *session);
QVector<LtsWidgets::PluginData> getActions() override;
QString menuGroup() const override;
static const QString s_flmExplorerScheme;
static const QString s_flmHQReportScheme;
bool fetchInterfaces() override;
void clearInterfaces() override;
int loadFileContent(QWidget *parent,
QByteArray &content,
const QVector<FileType> &fileTypes,
int exerciseId,
const QString &xmlType = QString(),
int initialFolderId = 0) override;
int selectFileContent(QWidget *parent,
const QVector<FileType> &fileTypes,
int exerciseId,
int initialFolderId = 0) override;
int saveFileContent(QWidget *parent,
FileType targetFileType,
int exerciseId,
const QByteArray &content,
int initialFolderId = 0,
const QString &properties = QString()) override;
bool loadContent(int fileId,
QByteArray &content,
bool bQuiet = false) override;
bool saveContent(int fileId,
const QByteArray &content,
const QString &properties = QString()) override;
int newFileContent(FileManagement::FileContent fc,
const QByteArray &content) override;
bool deleteFileContent(int fileId) override;
int getFileId(FileManagement::FileType fileType, const QString &fileName, int exId, int phId) const override;
QString getFileName(int fileId) const override;
bool isXmlType(const QByteArray &content, const QString &searchedType) const override;
QString hasXmlType(const QByteArray &content) const override;
// Script Editor Topic Editor:
TopicEditorBase::TopicEditor *createTopicEditor(const TopicEditorBase::TopicData &data) override;
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private:
void onGetFileContentDataReply(const GetFileContentDataReply &reply) override { m_requestHelper->requestReply(reply); }
void onFileContentModifyReply(const Core::FunctionReplyObject &reply) override { m_requestHelper->requestReply(reply); }
void onFileContentChangeStatusReply(const Core::FunctionReplyObject &reply) override { m_requestHelper->requestReply(reply); }
LtsWidgets::LtsDialog *onShowFileManagementDialog(QWidget *parent);
LtsWidgets::LtsDialog *onShowFileManagementAdminDialog(QWidget *parent);
LtsWidgets::LtsDialog *onShowHQReportDialog(QWidget *parent);
void onShowHQReportDialog(int partyId = -1);
LtsWidgets::LtsFramelessDialog *onSelectFileDialog(QWidget *parent);
LtsUtils::RequestHelper *m_requestHelper { nullptr };
std::shared_ptr<FileManagement::Interface::Dtc> m_dtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc;
std::shared_ptr<FileManagement::ForeignGuiComboboxInterface> m_flmGuiCbxIfc;
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
// Script Player
class TopicReplayInterface : public TopicReplay::Interface
{
public:
TopicReplayInterface(const std::shared_ptr<FileManagement::Interface::Dtc> &dtc,
const std::shared_ptr<FileManagement::Interface::Ftc> &ftc);
~TopicReplayInterface();
QWidget *createWidget() override;
bool playbackInit(const QJsonObject &attributes) override;
bool exportTopic(const QJsonObject &attributes,
const QString &folderPath,
TopicEditorBase::ExportNotifier *pExportNotifier) override;
private:
static void saveFile(const QString &strPathToFile, const std::vector<uint8_t> &content, bool binary = true);
std::shared_ptr<FileManagement::Interface::Dtc> m_dtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc;
FileManagement::FileContentPreviewPlaybackWidget *m_previewWidget{nullptr};
NGL::INGLLogger &m_logger;
};
TopicReplay::Interface *createInterface(TopicEditorBase::TopicType) override { return new TopicReplayInterface(m_dtc, m_ftc); }
};
} // namespace FileManagement
@@ -0,0 +1,59 @@
/**
* @RDE_HEADER@
* * Common class to get a file content by FTC
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-08-22
*/
#include "flm_get_content.h"
namespace FileManagement
{
//------------------------------------------------------------------------------------
GetFileContent::GetFileContent(const std::shared_ptr<FileManagement::Interface::Ftc> &ftc,
QObject *parent)
: QObject(parent)
, m_requestHelper(new LtsUtils::RequestHelper(this))
, m_ftc(ftc)
, m_logger(getLogger("GetFileContent"))
{
}
//------------------------------------------------------------------------------------
GetFileContent::~GetFileContent()
{
delete m_requestHelper;
}
//-----------------------------------------------------------------------------------------------------------
bool GetFileContent::getContent(int fileContentId, std::vector<uint8_t> &content)
{
DEBUG_LOG(m_logger) << "New Get Content";
auto handleContent = [this, &content](const Core::FunctionReply & baseReply)
{
const GetFileContentDataReply &reply = static_cast<const GetFileContentDataReply &>(baseReply);
content = reply.content();
DEBUG_LOG(m_logger) << "Content size: " << content.size();
};
auto sendReq = [this, fileContentId]()
{
GetFileContentDataRequest req;
req.fileContentId(fileContentId);
return m_ftc->getFileContentDataRequest(req, this);
};
if (!m_requestHelper->startSingleRequest(sendReq, handleContent))
{
ERROR_LOG(m_logger) << "Cannot retrieve file content for id = " << fileContentId;
return false;
}
DEBUG_LOG(m_logger) << "Content size: " << content.size();
return true;
}
} // namespace FileManagement;
+41
View File
@@ -0,0 +1,41 @@
/**
* @RDE_HEADER@
* Common class to get a file content by FTC
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-08-22
*/
#pragma once
#include <LtsUtilsGuiDds/request_helper.h>
#include <FileManagement/logger.h>
#include <Services/FileManagement/flm_ftc.h>
#include <QObject>
namespace FileManagement
{
class GetFileContent
: public QObject
, protected FileManagement::Interface::Ftc::GetFileContentDataReplyHandler
{
Q_OBJECT
public:
explicit GetFileContent(const std::shared_ptr<FileManagement::Interface::Ftc> &ftc,
QObject *parent = nullptr);
~GetFileContent();
bool getContent(int fileContentId, std::vector<uint8_t> &content);
private:
void onGetFileContentDataReply(const GetFileContentDataReply &replyObject) override final { m_requestHelper->requestReply(replyObject); }
private:
LtsUtils::RequestHelper *m_requestHelper{nullptr};
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc;
LOGGER_T m_logger;
};
}
@@ -0,0 +1,36 @@
/**
* @RDE_HEADER@
* Async file content getter without request helper
* $Id: $
* $HeadURL: $
* $Author: $
*
* Created by Mike Lennart Wille, SLSTE, 2022-06-22
*/
#include "flm_get_content_async.h"
namespace FileManagement
{
GetFileContentAsync::GetFileContentAsync(int fileContentId, const std::shared_ptr<FileManagement::Interface::Ftc> &flmFtc)
: QObject()
{
GetFileContentDataRequest req;
req.fileContentId(fileContentId);
flmFtc->getFileContentDataRequest(req, this);
}
void GetFileContentAsync::onGetFileContentDataReply(const GetFileContentDataReply &reply)
{
if (!reply.errorString().empty())
{
emit signalFailed();
return;
}
m_content = reply.content();
emit signalDone();
}
} // namespace FileManagement;
@@ -0,0 +1,38 @@
#pragma once
/**
* @RDE_HEADER@
* Async file content getter without request helper
* $Id: $
* $HeadURL: $
* $Author: $
*
* Created by Mike Lennart Wille, SLSTE, 2022-06-22
*/
#include <FileManagement/flm_ftc.h>
#include <QObject>
namespace FileManagement
{
class GetFileContentAsync : public QObject, protected FileManagement::Interface::Ftc::GetFileContentDataReplyHandler
{
Q_OBJECT
public:
GetFileContentAsync(int fileContentId, const std::shared_ptr<FileManagement::Interface::Ftc> &flmFtc);
const std::vector<uint8_t> &content() const { return m_content; }
private:
void onGetFileContentDataReply(const GetFileContentDataReply &replyObject) override final;
private:
std::vector<uint8_t> m_content;
signals:
void signalDone();
void signalFailed();
};
} // namespace FileManagement
@@ -0,0 +1,190 @@
/**
* @RDE_HEADER@
* Call Libre/MS Office
* $Id$
* $HeadURL$
* $Author$
*/
#include "flm_office_integration.h"
#include <LtsSession/lts_session.h>
#include <LtsUtilsSettings/settings.h>
#include <nglsettings/nglsettings_settings.h>
#include <ngltools/ngltools_filesystem.h>
#include "settings.h"
#include <QFileInfo>
#include <QProcess>
#include <QTemporaryFile>
namespace FileManagement
{
OfficeIntegration::OfficeIntegration(const FileManagement::FileContent &fileContent, QObject *parent)
: QObject(parent)
, m_selectedFileContent(fileContent)
, m_logger(getLogger("FileManagementOfficeIntegration"))
{}
OfficeIntegration::~OfficeIntegration()
{
delete m_icaFile;
}
bool OfficeIntegration::openOfficeWindow()
{
m_errorString.clear();
const bool bUseMSOffice = LtsUtils::ProjectSettings::getInstance()->value(QStringLiteral("Office"), QStringLiteral("Type")).toString() == QStringLiteral("MSOffice");
const bool bRet = bUseMSOffice ? callWfica() : callLibreOffice();
if (!bRet)
ERROR_LOG(m_logger) << m_errorString;
return bRet;
}
bool OfficeIntegration::callWfica()
{
const QString program = QStringLiteral("/opt/Citrix/ICAClient/wfica");
QFileInfo fi(program);
if (!fi.exists() || !fi.isExecutable() || !fi.isFile())
{
m_errorString = tr("Could not find wfica executable at '%1'").arg(program);
return false;
}
const QString icaFileTemplate(QStringLiteral("office.ica"));
const QString icaFileTemplatePath = NGL::findFile(NGL::FileType::ConfigFile, icaFileTemplate);
if (icaFileTemplatePath.isEmpty())
{
m_errorString = tr("Could not find ICA config file '%1'").arg(icaFileTemplate);
return false;
}
delete m_icaFile;
m_icaFile = new QTemporaryFile(this);
QFile f(icaFileTemplatePath);
if (!f.open(QIODevice::ReadOnly))
{
m_errorString = tr("Could not open ICA config file '%1' for reading").arg(icaFileTemplatePath);
return false;
}
if (!m_icaFile->open())
{
m_errorString = tr("Could not open temporary file (%1)").arg(m_icaFile->errorString());
return false;
}
QByteArray ba = f.readAll();
ba = ba.replace("@USERNAME@", getWfIcaUsername().toUtf8());
m_icaFile->write(ba);
m_icaFile->flush();
f.close();
QStringList arguments;
arguments << m_icaFile->fileName() << QStringLiteral("-param") << getParas();
QProcess *myProcess = new QProcess(this);
connect (myProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &OfficeIntegration::deleteLater);
myProcess->start(program, arguments);
INFO_LOG(m_logger) << "icaFile: =" << m_icaFile->fileName() <<
", args: '" << arguments.join(QLatin1Char(' '));
DEBUG_LOG(m_logger) << "FileManagement::OfficeIntegration::callWfica(): " << myProcess->errorString();
return true;
}
bool OfficeIntegration::callLibreOffice()
{
startLibreOfficeServer();
// QString connString = QStringLiteral("jdbc:postgresql://localhost:5432/lts_ets_pro?user=postgres&password=postgres");
QString connString = QStringLiteral("jdbc:postgresql://%DB_HOST%:5432/%DB_NAME%?user=postgres&password=postgres");
auto s = Settings::settings();
connString.replace(QStringLiteral("%DB_NAME%"), s->databaseName());
connString.replace(QStringLiteral("%DB_HOST%"), s->databaseHostname());
DEBUG_LOG(m_logger) << "DB connection string: " << connString;
QString program = QStringLiteral("java");
QStringList arguments;
arguments << QStringLiteral("-jar") << QStringLiteral("/opt/libreOfficeAddin/RheinmetallLibreOfficeLauncher.jar")
<< QStringLiteral("--jdbcConnectionString") << connString
<< QStringLiteral("--operatorId") << QString::number(m_selectedFileContent.operatorId())
<< QStringLiteral("--documentId") << QString::number(m_selectedFileContent.id())
<< QStringLiteral("--fileCategoryId") << QString::number(m_selectedFileContent.fileCategory().underlying())
<< QStringLiteral("--libreOfficeHost") << QStringLiteral("localhost")
<< QStringLiteral("--libreOfficePort") << QStringLiteral("8100");
QProcess *myProcess = new QProcess(this);
connect(myProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), myProcess, &QProcess::deleteLater);
connect(myProcess, &QProcess::errorOccurred, this, [this, myProcess](QProcess::ProcessError error)
{
ERROR_LOG(m_logger) << "FileManagement::OfficeIntegration::callLibreOffice(): " << error << " = " << myProcess->errorString();
});
myProcess->start(program, arguments);
return true;
}
void OfficeIntegration::startLibreOfficeServer()
{
QString program = QStringLiteral("soffice");
QStringList arguments;
arguments << QStringLiteral("--norestore") << QStringLiteral("--nodefault") << QStringLiteral("--accept=""socket,host=localhost,port=8100,tcpNoDelay=1;urp;""");
QProcess *myProcess = new QProcess(this);
connect (myProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &OfficeIntegration::deleteLater);
myProcess->start(program, arguments);
DEBUG_LOG(m_logger) << "FileManagement::OfficeIntegration::startLibreOfficeServer(): " << myProcess->errorString();
}
QString OfficeIntegration::getParas() const
{
QString paras;
paras += QStringLiteral("\"{");
paras += QStringLiteral("jdbcConnectionString:"); // should be odbcConnectionString...
paras += buildJdbcString();
paras += QStringLiteral(",");
paras += QStringLiteral("operatorId:");
paras += QString::number(m_selectedFileContent.operatorId());
paras += QStringLiteral(",");
paras += QStringLiteral("documentId:");
paras += QString::number(m_selectedFileContent.id());
paras += QStringLiteral(",");
paras += QStringLiteral("fileCategoryId:");
paras += QString::number(m_selectedFileContent.fileCategory().underlying());
if (m_selectedFileContent.exerciseId().is_set())
{
paras += QStringLiteral(",");
paras += QStringLiteral("exerciseId:");
paras += QString::number(m_selectedFileContent.exerciseId().get());
if (m_selectedFileContent.phaseId().is_set())
{
paras += QStringLiteral(",");
paras += QStringLiteral("phaseId:");
paras += QString::number(m_selectedFileContent.phaseId().get());
}
}
paras += QStringLiteral("}\"");
return paras;
}
QString OfficeIntegration::buildJdbcString() const
{
auto s = Settings::settings();
return QStringLiteral("DSN=%1_%2_PSQL").arg(s->databaseHostname(), s->databaseName());
}
QString OfficeIntegration::getWfIcaUsername() const
{
// TODO: make configurable?
return QStringLiteral("guez\\%1").arg(LtsSession::LtsSession::workstationName());
}
} // namespace FileManagement
@@ -0,0 +1,42 @@
/**
* @RDE_HEADER@
* Call Libre/MS Office
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QObject>
#include "flm_get_content.h"
class QTemporaryFile;
namespace FileManagement
{
class OfficeIntegration : public QObject
{
Q_OBJECT
public:
explicit OfficeIntegration(const FileContent &fileContent, QObject *parent = nullptr);
~OfficeIntegration();
bool openOfficeWindow();
QString errorString() const { return m_errorString; }
private:
bool callWfica();
bool callLibreOffice();
void startLibreOfficeServer();
QString getParas() const;
QString buildJdbcString() const;
QString getWfIcaUsername() const;
private:
FileManagement::FileContent m_selectedFileContent;
QTemporaryFile *m_icaFile{nullptr};
QString m_errorString;
LOGGER_T m_logger;
};
}
@@ -0,0 +1,147 @@
/**
* @RDE_HEADER@
* The FileContentPreviewDialog offers an UI to preview an FileContent
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-06-02
*/
#include "flm_preview_file_dialog.h"
#include "ui_flm_preview_file_dialog.h"
#include <LtsUtilsCore/dds_vector_to_pixmap.h>
#include <LtsUtilsCore/dds_vector.h>
#include <LtsPrinting/printing.h>
#include <nglsettings/nglsettings_settings.h>
#include <settings.h>
#include <QScreen>
#define PREVIEW_MIN_WIDTH 1200
#define PREVIEW_MIN_HEIGHT 800
namespace FileManagement
{
//------------------------------------------------------------------------------------
FileContentPreviewDialog::FileContentPreviewDialog(LtsSession::LtsSession *session, const std::shared_ptr<Interface::Ftc> &ftc, QWidget *parent)
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
, m_ui(new Ui::FileContentPreviewDialog)
, m_session(session)
, m_getContent(new FileManagement::GetFileContent(ftc, this))
, m_content(QByteArray())
, m_logger(getLogger("FileContentPreviewDialog"))
{
m_ui->setupUi(this);
m_ui->line->setVisible(false);
}
//------------------------------------------------------------------------------------
FileContentPreviewDialog::~FileContentPreviewDialog()
{
//delete m_getContent; is parented
delete m_ui;
}
//------------------------------------------------------------------------------------
bool FileContentPreviewDialog::init(const FileContent &data)
{
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &FileContentPreviewDialog::close);
m_ui->buttonBox->setButtonVisible(LtsWidgets::DialogButton::Apply, false);
m_ui->buttonBox->setButtonVisible(LtsWidgets::DialogButton::Ok, false);
m_ui->buttonBox->setButtonVisible(LtsWidgets::DialogButton::Print, true);
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Print), &QPushButton::clicked, this, &FileContentPreviewDialog::onPrint);
m_data = data;
if (m_data.id() > 0) // valid id
{
std::vector<uint8_t> content;
m_getContent->getContent(m_data.id(), content);
m_content = LtsUtils::toQByteArray(content);
}
m_ui->lblTitle->setText(tr("Preview File Content: %1").arg(QString::fromStdString(data.name())));
DEBUG_LOG(m_logger) << "Content size: " << m_content.size();
switch (data.fileType().underlying())
{
case FileManagement::FileType::Png:
case FileManagement::FileType::Jpg:
{
QPixmap pix = LtsUtils::getPixmap(m_content);
QRect rect = QGuiApplication::primaryScreen()->availableGeometry();
// 80 %
int width = rect.width() * 4 / 5;
int height = rect.height() * 4 / 5;
if (pix.width() >= width || pix.height() >= height)
m_ui->lblPixmap->setPixmap(pix.scaled(width, height, Qt::KeepAspectRatio));
else
m_ui->lblPixmap->setPixmap(pix);
m_ui->lblPixmap->setScaledContents(false);
m_ui->stackedWidget->setCurrentWidget(m_ui->pageImage);
break;
}
case FileManagement::FileType::Text:
case FileManagement::FileType::Xml:
case FileManagement::FileType::TacticalPlan:
case FileManagement::FileType::OperatorFavourite:
case FileManagement::FileType::EvaluationSchema:
{
m_ui->teText->setHtml(QString::fromUtf8(m_content));
m_ui->stackedWidget->setCurrentWidget(m_ui->pageText);
break;
}
case FileManagement::FileType::Pdf:
{
m_ui->pdfWidget->showPDF(m_content);
m_ui->pdfWidget->setZoomFactor(1.0);
m_ui->pdfWidget->setRotation(Poppler::Page::Rotate0);
m_ui->pdfWidget->setPage(1);
m_ui->stackedWidget->setCurrentWidget(m_ui->pagePdf);
break;
}
case FileManagement::FileType::OperatorDefinedSymbol:
case FileManagement::FileType::MSOfficeDocument:
case FileManagement::FileType::MSOfficeDocument97:
case FileManagement::FileType::MSOfficePresentation:
case FileManagement::FileType::MSOfficePresentation97:
case FileManagement::FileType::MSOfficeSpreadsheet:
case FileManagement::FileType::MSOfficeSpreadsheet97:
case FileManagement::FileType::OpenOfficeDocument:
case FileManagement::FileType::OpenOfficePresentation:
case FileManagement::FileType::OpenOfficeSpreadsheet:
{
new LtsWidgets::LtsMessageDialogNew(this, tr("Not yet implemented"));
close();
break;
}
case FileManagement::FileType::Unknown:
{
new LtsWidgets::LtsMessageDialogNew(this, tr("Unknown file type! Preview not available."));
close();
break;
}
}
return true;
}
//-----------------------------------------------------------------------------------------------------------
void FileContentPreviewDialog::onPrint()
{
if (m_ui->stackedWidget->currentWidget() == m_ui->pagePdf)
{
auto s = Settings::settings();
QVector<QImage> images = m_ui->pdfWidget->getPrintableImages(150 /*dpi, default is 300*/);
LtsPrinting::printPDFImages(this, QString::fromStdString(m_data.name()), s->printPath(), images);
}
else
LtsPrinting::printWidget(m_session, this, m_ui->stackedWidget->currentWidget(), QString::fromStdString(m_data.name()));
}
} // namespace FileManagement;
@@ -0,0 +1,48 @@
/**
* @RDE_HEADER@
* The FileContentPreviewDialog offers an UI to preview an FileContent
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-06-02
*/
#pragma once
#include <LtsWidgets/lts_frameless_dialog.h>
#include <Services/FileManagement/flm_ftc.h>
#include <FileManagement/logger.h>
#include <LtsSession/lts_session.h>
#include "flm_get_content.h"
namespace Ui
{
class FileContentPreviewDialog;
}
namespace FileManagement
{
class FileContentPreviewDialog
: public LtsWidgets::LtsFramelessDialog
{
Q_OBJECT
public:
explicit FileContentPreviewDialog(LtsSession::LtsSession *session,
const std::shared_ptr<FileManagement::Interface::Ftc> &ftc,
QWidget *parent = nullptr);
~FileContentPreviewDialog();
bool init(const FileContent &data);
public slots:
void onPrint();
private:
Ui::FileContentPreviewDialog *m_ui{nullptr};
LtsSession::LtsSession *m_session{nullptr};
GetFileContent *m_getContent{nullptr};
QByteArray m_content;
FileContent m_data;
LOGGER_T m_logger;
};
}
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FileContentPreviewDialog</class>
<widget class="QWidget" name="FileContentPreviewDialog">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="windowTitle">
<string>Preview File Content</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lblTitle">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">Preview File Content:</string>
</property>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="pageText">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTextEdit" name="teText">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="pagePdf">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="NGL::PDFWidget" name="pdfWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="pageImage">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="lblPixmap">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsDialogButtonBox</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_dialog_button_box.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>NGL::PDFWidget</class>
<extends>QWidget</extends>
<header location="global">nglwidgets/nglpdfwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,270 @@
/**
* @RDE_HEADER@
* The FileContentPreviewPlaybackWidget offers an UI to preview a FileContent
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-06-02
*/
#include "flm_preview_playback.h"
#include "ui_flm_preview_playback.h"
#include <LtsUtilsCore/dds_vector_to_pixmap.h>
#include <LtsUtilsCore/dds_vector.h>
#include <LtsWidgets/lts_message_dialog.h>
#include <nglwidgets/nglpdfwidget.h>
namespace FileManagement
{
static Poppler::Page::Rotation getRotationFromValue(int rotation);
//------------------------------------------------------------------------------------
FileContentPreviewPlaybackWidget::FileContentPreviewPlaybackWidget(const std::shared_ptr<Interface::Ftc> &ftc, QWidget *parent)
: QWidget(parent)
, m_ui(new Ui::FileContentPreviewPlaybackWidget)
, m_getContent(new FileManagement::GetFileContent(ftc, this))
, m_closeTimer(new QTimer(this))
, m_logger(getLogger("FileContentPreviewPlaybackWidget"))
{
m_ui->setupUi(this);
m_ui->lblPixmap->setVisible(false);
m_ui->teText->setVisible(false);
// setup pdf widget
m_pdfWidget = new NGL::PDFWidget(this);
m_pdfWidget->setObjectName(QStringLiteral("pdfWidget"));
m_pdfWidget->setSizePolicy(QSizePolicy::Policy::MinimumExpanding, QSizePolicy::Policy::MinimumExpanding);
connect(m_pdfWidget, &NGL::PDFWidget::currentPageChanged, this, &FileContentPreviewPlaybackWidget::setPage);
connect(m_pdfWidget, &NGL::PDFWidget::rotationChanged, this, [this](Poppler::Page::Rotation rot)
{
switch (rot)
{
case Poppler::Page::Rotate90:
setRotation(90);
break;
case Poppler::Page::Rotate180:
setRotation(180);
break;
case Poppler::Page::Rotate270:
setRotation(270);
break;
case Poppler::Page::Rotate0:
setRotation(0);
break;
}
});
m_ui->horizontalLayout->addWidget(m_pdfWidget);
}
//------------------------------------------------------------------------------------
FileContentPreviewPlaybackWidget::~FileContentPreviewPlaybackWidget()
{
delete m_getContent;
delete m_ui;
}
//------------------------------------------------------------------------------------
bool FileContentPreviewPlaybackWidget::init(const FileContent &data, int pageNo,
double zoomFactor, int rotation,
int duration, const QString &userText)
{
m_data = data;
m_duration = (duration > 0) ? duration : 0;
m_pageNo = pageNo;
m_zoomFactor = (zoomFactor >= ZOOM_MIN && zoomFactor <= ZOOM_MAX) ? zoomFactor : ZOOM_DEFAULT;
m_rotation = rotation;
m_userText = userText;
DEBUG_LOG(m_logger) << "FileContentPreviewPlaybackWidget::init - (fileId, pageNo, zoomFactor, rotation) = ("
<< m_data.id() << "," << m_pageNo << "," << m_zoomFactor << ", " << m_rotation << ")";
if (m_userText.isEmpty() && m_data.id() > 0)
m_getContent->getContent(m_data.id(), m_content);
DEBUG_LOG(m_logger) << "Content size: " << m_content.size() << ", " << m_pageNo;
if (m_duration > 0)
startTimer();
m_ui->lblPixmap->setVisible(false);
m_ui->teText->setVisible(false);
m_pdfWidget->setVisible(false);
switch (data.fileType().underlying())
{
case FileManagement::FileType_def::Png:
case FileManagement::FileType_def::Jpg:
{
m_ui->lblPixmap->setPixmap(LtsUtils::getPixmap(m_content));
m_ui->lblPixmap->setVisible(true);
break;
}
case FileManagement::FileType_def::Text:
{
if (!m_userText.isEmpty() && m_data.id() == 0)
{
m_ui->teText->setHtml(m_userText);
m_ui->teText->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_ui->teText->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_ui->teText->setVisible(true);
}
break;
}
case FileManagement::FileType_def::Xml:
case FileManagement::FileType_def::TacticalPlan:
case FileManagement::FileType_def::OperatorFavourite:
case FileManagement::FileType_def::EvaluationSchema:
{
m_ui->teText->setHtml(QString::fromUtf8(LtsUtils::toQByteArray(m_content)));
m_ui->teText->setVisible(true);
break;
}
case FileManagement::FileType_def::Pdf:
{
m_pdfWidget->setVisible(true);
m_pdfWidget->setZoomFactor(m_zoomFactor);
m_pdfWidget->setPage(m_pageNo); // before setRotation since there currentPageChanged is emitted
m_pdfWidget->setRotation(getRotationFromValue(rotation));
m_pdfWidget->showPDF(LtsUtils::toQByteArray(m_content));
break;
}
case FileManagement::FileType_def::OperatorDefinedSymbol:
case FileManagement::FileType_def::MSOfficeDocument:
case FileManagement::FileType_def::MSOfficeDocument97:
case FileManagement::FileType_def::MSOfficePresentation:
case FileManagement::FileType_def::MSOfficePresentation97:
case FileManagement::FileType_def::MSOfficeSpreadsheet:
case FileManagement::FileType_def::MSOfficeSpreadsheet97:
case FileManagement::FileType_def::OpenOfficeDocument:
case FileManagement::FileType_def::OpenOfficePresentation:
case FileManagement::FileType_def::OpenOfficeSpreadsheet:
{
new LtsWidgets::LtsMessageDialogNew(this, tr("Not yet implemented"));
close();
break;
}
case FileManagement::FileType_def::Unknown:
default:
{
if (!m_userText.isEmpty() && m_data.id() == 0)
{
m_ui->teText->setHtml(m_userText);
m_ui->teText->setVisible(true);
}
else
{
new LtsWidgets::LtsMessageDialogNew(this, tr("Unknown file type! Playback not available."));
close();
}
break;
}
}
return true;
}
//-----------------------------------------------------------------------------------------------------------
bool FileContentPreviewPlaybackWidget::pauseTimer()
{
m_closeTimer.stop();
DEBUG_LOG(m_logger) << "Timer stopped ";
return true;
}
//-----------------------------------------------------------------------------------------------------------
bool FileContentPreviewPlaybackWidget::startTimer()
{
m_closeTimer.setInterval(m_duration * 1000); // duration is in secs, timer interval in msecs
connect(&m_closeTimer, &QTimer::timeout, this, &FileContentPreviewPlaybackWidget::close);
m_closeTimer.start();
DEBUG_LOG(m_logger) << "Timer started interval = " << m_closeTimer.interval();
return true;
}
//-----------------------------------------------------------------------------------------------------------
int FileContentPreviewPlaybackWidget::getNumPages() const
{
return m_pdfWidget->numPages();
}
//-----------------------------------------------------------------------------------------------------------
int FileContentPreviewPlaybackWidget::getCurPage() const
{
return m_pdfWidget->curPage();
}
//-----------------------------------------------------------------------------------------------------------
void FileContentPreviewPlaybackWidget::setPage(int pageNo)
{
if (m_pageNo == pageNo)
return;
DEBUG_LOG(m_logger) << "setPage = " << pageNo;
m_pageNo = pageNo;
m_pdfWidget->setPage(pageNo);
emit currentPageChanged(m_pageNo);
}
//-----------------------------------------------------------------------------------------------------------
void FileContentPreviewPlaybackWidget::setZoomFactor(double zoomFactor)
{
if (qFuzzyCompare(m_zoomFactor, zoomFactor))
return;
DEBUG_LOG(m_logger) << "setZoomFactor = " << zoomFactor;
m_zoomFactor = zoomFactor;
m_pdfWidget->setZoomFactor(zoomFactor);
}
//-----------------------------------------------------------------------------------------------------------
void FileContentPreviewPlaybackWidget::setRotation(int rotation)
{
if (m_rotation == rotation)
return;
DEBUG_LOG(m_logger) << "setRotation = " << rotation;
m_rotation = rotation;
m_pdfWidget->setRotation(getRotationFromValue(m_rotation));
emit rotationChanged(rotation);
}
//-----------------------------------------------------------------------------------------------------------
void FileContentPreviewPlaybackWidget::ensureDataIsSet()
{
if (m_pdfWidget->isVisible() && m_pageNo > 0)
{
m_pdfWidget->setZoomFactor(m_zoomFactor);
m_pdfWidget->setRotation(getRotationFromValue(m_rotation));
m_pdfWidget->setPage(m_pageNo);
}
}
//-----------------------------------------------------------------------------------------------------------
void FileContentPreviewPlaybackWidget::showEvent(QShowEvent *e)
{
QWidget::showEvent(e);
ensureDataIsSet();
}
//-----------------------------------------------------------------------------------------------------------
Poppler::Page::Rotation getRotationFromValue(int rotation)
{
Poppler::Page::Rotation rot;
switch (rotation)
{
case 90:
rot = Poppler::Page::Rotate90;
break;
case 180:
rot = Poppler::Page::Rotate180;
break;
case 270:
rot = Poppler::Page::Rotate270;
break;
case 0:
default:
rot = Poppler::Page::Rotate0;
break;
}
return rot;
}
} // namespace FileManagement
@@ -0,0 +1,79 @@
/**
* @RDE_HEADER@
* The FileContentPreviewPlaybackWidget offers an UI to preview a FileContent
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-06-02
*/
#pragma once
#include "flm_get_content.h"
#include <LtsWidgets/lts_frameless_dialog.h>
#include <FileManagement/logger.h>
#include <Services/FileManagement/flm_ftc.h>
#include <QTimer>
// TODO: in a config ?
#define ZOOM_MIN 0.5
#define ZOOM_MAX 2.0
#define ZOOM_DEFAULT 1.0
namespace Ui
{
class FileContentPreviewPlaybackWidget;
}
namespace NGL
{
class PDFWidget;
}
namespace FileManagement
{
class FileContentPreviewPlaybackWidget
: public QWidget
{
Q_OBJECT
public:
explicit FileContentPreviewPlaybackWidget(const std::shared_ptr<FileManagement::Interface::Ftc> &ftc,
QWidget *parent = nullptr);
~FileContentPreviewPlaybackWidget();
bool init(const FileContent &data, int pageNo = -1, double zoomFactor = ZOOM_DEFAULT,
int rotation = 0, int duration = 0, const QString &userText = QString());
bool pauseTimer();
bool startTimer();
int getNumPages() const;
int getCurPage() const;
void setPage(int pageNo);
void setZoomFactor(double zoomFactor);
void setRotation(int rotation);
void ensureDataIsSet();
void showEvent(QShowEvent *e) override;
Q_SIGNALS:
void currentPageChanged(int curPage);
void rotationChanged(int rotation);
private:
Ui::FileContentPreviewPlaybackWidget *m_ui{nullptr};
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc;
GetFileContent *m_getContent{nullptr};
FileContent m_data;
std::vector<uint8_t> m_content;
int m_duration{0};
int m_pageNo{-1};
double m_zoomFactor{ZOOM_DEFAULT};
int m_rotation; // degree
QTimer m_closeTimer;
NGL::PDFWidget *m_pdfWidget{nullptr};
QString m_userText;
LOGGER_T m_logger;
};
}
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FileContentPreviewPlaybackWidget</class>
<widget class="QWidget" name="FileContentPreviewPlaybackWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>200</height>
</size>
</property>
<property name="windowTitle">
<string notr="true">Playback File Content</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="RatioAwareLabel" name="lblPixmap">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="pixmap">
<pixmap>:/style/document-preview.svg</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="teText">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RatioAwareLabel</class>
<extends>QLabel</extends>
<header>RatioAwareLabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,173 @@
/**
* @RDE_HEADER@
* The SetPropertiesDialog offers an UI to edit the Properties of an FileContent
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-06-01
*/
#include "flm_set_properties_dialog.h"
#include "ui_flm_set_properties_dialog.h"
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QLabel>
#include <QtWidgets/QHBoxLayout>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
namespace FileManagement
{
//------------------------------------------------------------------------------------
SetPropertiesDialog::SetPropertiesDialog(QLineEdit *lineEdit, QWidget *parent)
: LtsWidgets::LtsFramelessDialog(parent)
, m_ui(new Ui::SetPropertiesDialog)
, m_lineEdit(lineEdit)
, m_logger(getLogger("SetPropertiesDialog"))
{
DEBUG_LOG(m_logger) << "Ctor SetPropertiesDialog";
m_ui->setupUi(this);
}
//------------------------------------------------------------------------------------
SetPropertiesDialog::~SetPropertiesDialog()
{
delete m_ui;
}
//------------------------------------------------------------------------------------
void SetPropertiesDialog::init()
{
DEBUG_LOG(m_logger) << "Init SetPropertiesDialog";
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &SetPropertiesDialog::close);
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Apply)->hide();
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok)->hide();
m_ui->buttonBox->setText(LtsWidgets::DialogButton::Save, tr("OK")); // TODO: undo workaround !
m_ui->buttonBox->connectButton(LtsWidgets::DialogButton::Save, this, &SetPropertiesDialog::onOkClicked); // TODO: PopupDialog in Framework
m_ui->buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &SetPropertiesDialog::onAddClicked);
m_ui->scrollArea->widget()->setLayout(m_ui->vlScrollBar);
if (!m_lineEdit->text().isEmpty())
{
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(m_lineEdit->text().toUtf8(), &error);
if (error.error != QJsonParseError::NoError)
{
ERROR_LOG(m_logger) << error.errorString();
return;
}
if (!doc.isObject())
{
ERROR_LOG(m_logger) << "Properties String is no JSON-Object";
return;
}
QJsonObject obj = doc.object();
for (auto it = obj.constBegin(); it != obj.constEnd(); ++it)
addProperty(it.key(), it.value().toVariant());
}
}
//------------------------------------------------------------------------------------
void SetPropertiesDialog::onOkClicked()
{
QJsonObject obj;
for (auto it = m_properties.constBegin(); it != m_properties.constEnd(); ++it)
{
QString propVal(it.value()->text());
QJsonValue jsonVal;
switch (propValType(propVal))
{
case PropValType::INT:
jsonVal = propVal.toInt();
break;
case PropValType::DOUBLE:
jsonVal = propVal.toDouble();
break;
case PropValType::BOOL:
{
if (propVal.toLower() == QStringLiteral("true"))
jsonVal = true;
if (propVal.toLower() == QStringLiteral("false"))
jsonVal = false;
break;
}
case PropValType::STRING:
default:
jsonVal = propVal;
}
obj.insert(it.key()->text(), jsonVal);
}
m_lineEdit->setText(QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)));
close();
}
//------------------------------------------------------------------------------------
void SetPropertiesDialog::onAddClicked()
{
addProperty(tr("name"), tr("value"));
}
//------------------------------------------------------------------------------------
void SetPropertiesDialog::addProperty(const QString &propName, const QVariant &propValue)
{
QHBoxLayout *layout = new QHBoxLayout(this);
QLineEdit *lePropName = new QLineEdit(propName, this);
QLineEdit *lePropVal = new QLineEdit(propValue.toString(), this);
QPushButton *pbRemove = new QPushButton(this);
QLabel *colon = new QLabel(QStringLiteral(":"), this);
pbRemove->setText(tr("remove"));
layout->addWidget(lePropName);
layout->addWidget(colon);
layout->addWidget(lePropVal);
layout->addWidget(pbRemove);
m_properties.insert(lePropName, lePropVal);
m_ui->vlProperties->addLayout(layout);
connect(pbRemove, &QPushButton::clicked,
this, [ = ]()
{
m_ui->vlProperties->removeItem(layout);
m_properties.remove(lePropName);
delete lePropName;
delete lePropVal;
delete colon;
pbRemove->deleteLater();
resize(sizeHint());
});
}
//------------------------------------------------------------------------------------
SetPropertiesDialog::PropValType SetPropertiesDialog::propValType(const QString &prop)
{
bool isOk;
(void)prop.toInt(&isOk);
if (isOk)
return PropValType::INT;
(void)prop.toDouble(&isOk);
if (isOk)
return PropValType::DOUBLE;
if (prop.toLower() == QStringLiteral("true") || prop.toLower() == QStringLiteral("false"))
return PropValType::BOOL;
return PropValType::STRING;
}
} // namespace FileManagement;
@@ -0,0 +1,58 @@
/**
* @RDE_HEADER@
* The SetPropertiesDialog offers an UI to edit the Properties of an FileContent
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-06-01
*/
#pragma once
#include <LtsWidgets/lts_frameless_dialog.h>
#include <FileManagement/logger.h>
#include <QMap>
class QLineEdit;
namespace Ui
{
class SetPropertiesDialog;
}
namespace FileManagement
{
class SetPropertiesDialog
: public LtsWidgets::LtsFramelessDialog
{
Q_OBJECT
public:
explicit SetPropertiesDialog(QLineEdit *lineEdit, QWidget *parent = nullptr);
~SetPropertiesDialog();
void init();
private Q_SLOTS:
void onOkClicked();
void onAddClicked();
private: // other
enum class PropValType
{
INT,
DOUBLE,
BOOL,
STRING
};
private: // methods
void addProperty(const QString &propName, const QVariant &propValue);
static PropValType propValType(const QString &prop);
private: // attributes
Ui::SetPropertiesDialog *m_ui{nullptr};
QMap<QLineEdit *, QLineEdit *> m_properties; // <propname, propval>
QLineEdit *m_lineEdit{nullptr};
LOGGER_T m_logger;
}; // class SetPropertiesDialog
} // namespace FileManagement
@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SetPropertiesDialog</class>
<widget class="QWidget" name="SetPropertiesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>902</width>
<height>292</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
<property name="windowTitle">
<string notr="true">Set Properties</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>886</width>
<height>236</height>
</rect>
</property>
<widget class="QWidget" name="verticalLayoutWidget_2">
<property name="geometry">
<rect>
<x>340</x>
<y>80</y>
<width>160</width>
<height>80</height>
</rect>
</property>
<layout class="QVBoxLayout" name="vlScrollBar">
<item>
<layout class="QVBoxLayout" name="vlProperties"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
<item>
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsDialogButtonBox</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_dialog_button_box.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+48
View File
@@ -0,0 +1,48 @@
[WFClient]
Version=2
username=@USERNAME@
clearpassword=!Mout11de
[ApplicationServers]
OPGLaunch=
[OPGLaunch]
Address=10.7.144.26:1494
AutologonAllowed=ON
BrowserProtocol=HTTPonTCP
CGPAddress=*:2598
ClientAudio=On
DesiredColor=8
DesiredHRES=0
DesiredVRES=0
DoNotUseDefaultCSL=On
FontSmoothingType=0
HDXoverUDP=Off
InitialProgram=#OPGLaunch
Launcher=WI
Title=Word 2016
TransportDriver=TCP/IP
TRWD=0
TWIMode=On
WinStationDriver=ICA 3.0
[Compress]
DriverNameWin16=pdcompw.dll
DriverNameWin32=pdcompn.dll
[EncRC5-0]
DriverNameWin16=pdc0w.dll
DriverNameWin32=pdc0n.dll
[EncRC5-128]
DriverNameWin16=pdc128w.dll
DriverNameWin32=pdc128n.dll
[EncRC5-40]
DriverNameWin16=pdc40w.dll
DriverNameWin32=pdc40n.dll
[EncRC5-56]
DriverNameWin16=pdc56w.dll
DriverNameWin32=pdc56n.dll
+54
View File
@@ -0,0 +1,54 @@
/**
* Settings for CentralEffectSimulation
* $Id$
* $HeadURL$
* $Author$
*/
#include "settings.h"
#include <QSettings>
#include <nglsettings/nglsettings_settings.h>
#include <ngltools/ngltools_filesystem.h>
namespace FileManagement
{
class NGLSettingsClass : public NGL::Settings
{
public:
NGLSettingsClass()
: NGL::Settings(s_iniFile.isEmpty() ? NGL::findProjectConfigFile() : s_iniFile)
{}
static void setIniFile(const QString &fn)
{
s_iniFile = fn;
}
static QString s_iniFile;
};
QString NGLSettingsClass::s_iniFile;
Q_GLOBAL_STATIC(NGLSettingsClass, s)
//-----------------------------------------------------------------------------
NGL::Settings *Settings::settings()
{
return s();
}
//-----------------------------------------------------------------------------
void Settings::setIniFile(const QString &ini)
{
NGLSettingsClass::setIniFile(ini);
}
//-----------------------------------------------------------------------------
QString Settings::dbServerHost()
{
return s()->databaseHostname();
}
//-----------------------------------------------------------------------------
QString Settings::dbServerName()
{
return s()->databaseName();
}
} // namespace
+26
View File
@@ -0,0 +1,26 @@
/**
* Settings for CentralEffectSimulation
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QString>
namespace NGL
{
class Settings;
}
namespace FileManagement
{
namespace Settings
{
NGL::Settings *settings();
void setIniFile(const QString &ini);
QString dbServerHost();
QString dbServerName();
}
} // namespace