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

+41
View File
@@ -0,0 +1,41 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# Created by Mike Wille, SLSE, 2017-03-31
#
ADD_SUBDIRECTORY(Data)
ADD_SUBDIRECTORY(Gui)
ADD_SUBDIRECTORY(Templates)
#
# Gui Plugin Interface
#
ADD_INTERFACE_LIBRARY(
FlmExplorerGuiPluginInterface
${CMAKE_CURRENT_SOURCE_DIR}/flm_explorer_gui_plugin_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/../../
GuiPluginInterface TopicReplayInterface TopicEditorInterface Qt5::Core svcFlmCommon
)
#
# Data Plugin Interface
#
ADD_INTERFACE_LIBRARY(
FlmDataPluginInterface
${CMAKE_CURRENT_SOURCE_DIR}/flm_data_plugin_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/../../
DataPluginInterface
svcFlmCommon
)
#
# Combobox Gui Plugin Interface
#
ADD_INTERFACE_LIBRARY(FlmGuiComboboxPluginInterface
${CMAKE_CURRENT_SOURCE_DIR}/flm_combobox_gui_plugin_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/../../
GuiPluginInterface
)
+20
View File
@@ -0,0 +1,20 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# Created by Mike Wille, SLSE, 2017-03-31
#
#
# Data Plugin
#
NGL_ADD_LIBRARY(WS FlmDataPlugin MODULE flm_data_plugin.cpp flm_data_plugin.h)
NGL_TARGET_LINK_LIBRARIES(FlmDataPlugin
Qt5::Core
FlmDataPluginInterface
svcFlmClient
NGLLogger
LtsSessionDataDds
)
NGL_INSTALL_TARGET(FlmDataPlugin)
+37
View File
@@ -0,0 +1,37 @@
/**
* @RDE_HEADER@
* Data Plugin for FileManangement
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, SLSE, 2017-03-31
*/
#include "flm_data_plugin.h"
#include <DDS/DDSConnector/dds_connector.h>
#include <LtsSession/lts_session_data_dds.h>
namespace FileManagement
{
std::shared_ptr<DataPluginBase::Interface> DataPlugin::createDataInterface(LtsSession::LtsSessionDataDds *session)
{
std::shared_ptr<Interface::Dtc> dtc;
std::shared_ptr<Interface::Ftc> ftc;
if (!session->createTopicClient(dtc, ftc, false, true))
return std::shared_ptr<DataPluginBase::Interface>();
return std::make_shared<DataInterfaceImpl>(dtc, ftc);
}
DataInterfaceImpl::DataInterfaceImpl(const std::shared_ptr<FileManagement::Interface::Dtc> &dtc,
const std::shared_ptr<FileManagement::Interface::Ftc> &ftc)
: DataInterface()
, m_dtc(dtc)
, m_ftc(ftc)
{}
} // namespace FileManagement
+54
View File
@@ -0,0 +1,54 @@
/**
* @RDE_HEADER@
* Data Plugin for FileManangement
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, SLSE, 2017-03-31
*/
#pragma once
#include <PluginInterfaces/data_plugin_interface.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
namespace FileManagement
{
class DataPlugin final : public QObject, public DataPluginBase::Plugin
{
Q_PLUGIN_METADATA(IID "data:3:flm")
Q_INTERFACES(DataPluginBase::Plugin)
Q_OBJECT
public:
DataPlugin() = default;
~DataPlugin() = default;
QString pluginName() const override { return QStringLiteral("FileManagement"); }
std::shared_ptr<DataPluginBase::Interface> createDataInterface(LtsSession::LtsSessionDataDds *session) override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return partition == IDL::PartitionType::Exercise ||
partition == IDL::PartitionType::Global ||
partition == IDL::PartitionType::Replay; // really?
}
};
class DataInterfaceImpl final : public DataInterface
{
public:
DataInterfaceImpl(const std::shared_ptr<FileManagement::Interface::Dtc> &dtc,
const std::shared_ptr<FileManagement::Interface::Ftc> &ftc);
std::shared_ptr<FileManagement::Interface::Dtc> getDtc() override { return m_dtc; }
std::shared_ptr<FileManagement::Interface::Ftc> getFtc() override { return m_ftc; }
private:
std::shared_ptr<FileManagement::Interface::Dtc> m_dtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_ftc;
};
} // namespace FileManagement
+10
View File
@@ -0,0 +1,10 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# Created by Mike Wille, SLSE, 2017-03-31
#
ADD_SUBDIRECTORY(Explorer)
ADD_SUBDIRECTORY(FlmComboBox)
+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
+30
View File
@@ -0,0 +1,30 @@
#
# $Id$
# $HeadURL$
# $Author$
# Created by Mike Wille, SLSE, 2016-05-05
#
SET(flm_combobox_gui_SRCS
flm_combobox_gui_plugin.cpp
flm_combobox_gui_plugin.h
flm_combobox.cpp
flm_combobox.h
)
NGL_WRAP_UI(flm_combobox_gui_SRCS
)
NGL_ADD_LIBRARY(WS FlmComboBoxGuiPlugin MODULE ${flm_combobox_gui_SRCS})
NGL_TARGET_LINK_LIBRARIES(FlmComboBoxGuiPlugin
NGLLogger
FlmGuiComboboxPluginInterface
FlmDataPluginInterface
Qt5::Widgets
LtsWidgets
LtsSession
)
NGL_INSTALL_TARGET(FlmComboBoxGuiPlugin)
@@ -0,0 +1,64 @@
/**
* @RDE_HEADER@
* FileManagement - FlmComboBox Gui Plugin
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-29
*/
#include "flm_combobox.h"
#include <FileManagement/flm_translation.h>
namespace FileManagement
{
bool FlmComboBox::fill(LtsWidgets::LtsComboBox *cbx, FlmComboBoxType type)
{
switch (type)
{
case FlmComboBoxType::CbFileCategory:
{
cbx->addItem(FileManagement::toString(FileManagement::FileCategory::Global), FileManagement::FileCategory::Global);
cbx->addItem(FileManagement::toString(FileManagement::FileCategory::Exercise), FileManagement::FileCategory::Exercise);
cbx->addItem(FileManagement::toString(FileManagement::FileCategory::User), FileManagement::FileCategory::User);
break;
}
case FlmComboBoxType::CbFileStatus:
{
cbx->addItem(FileManagement::toString(FileManagement::FileStatus::Valid), FileManagement::FileStatus::Valid);
cbx->addItem(FileManagement::toString(FileManagement::FileStatus::Deleted), FileManagement::FileStatus::Deleted);
break;
}
case FlmComboBoxType::CbFileType:
{
cbx->addItem(FileManagement::toString(FileManagement::FileType::Unknown), FileManagement::FileType::Unknown);
cbx->addItem(FileManagement::toString(FileManagement::FileType::Text), FileManagement::FileType::Text);
cbx->addItem(FileManagement::toString(FileManagement::FileType::Xml), FileManagement::FileType::Xml);
cbx->addItem(FileManagement::toString(FileManagement::FileType::Pdf), FileManagement::FileType::Pdf);
cbx->addItem(FileManagement::toString(FileManagement::FileType::Jpg), FileManagement::FileType::Jpg);
cbx->addItem(FileManagement::toString(FileManagement::FileType::Png), FileManagement::FileType::Png);
cbx->addItem(FileManagement::toString(FileManagement::FileType::TacticalPlan), FileManagement::FileType::TacticalPlan);
cbx->addItem(FileManagement::toString(FileManagement::FileType::OperatorFavourite), FileManagement::FileType::OperatorFavourite);
cbx->addItem(FileManagement::toString(FileManagement::FileType::OperatorDefinedSymbol), FileManagement::FileType::OperatorDefinedSymbol);
cbx->addItem(FileManagement::toString(FileManagement::FileType::OpenOfficeDocument), FileManagement::FileType::OpenOfficeDocument);
cbx->addItem(FileManagement::toString(FileManagement::FileType::OpenOfficeSpreadsheet), FileManagement::FileType::OpenOfficeSpreadsheet);
cbx->addItem(FileManagement::toString(FileManagement::FileType::OpenOfficePresentation), FileManagement::FileType::OpenOfficePresentation);
cbx->addItem(FileManagement::toString(FileManagement::FileType::MSOfficeDocument), FileManagement::FileType::MSOfficeDocument);
cbx->addItem(FileManagement::toString(FileManagement::FileType::MSOfficeDocument97), FileManagement::FileType::MSOfficeDocument97);
cbx->addItem(FileManagement::toString(FileManagement::FileType::MSOfficeSpreadsheet), FileManagement::FileType::MSOfficeSpreadsheet);
cbx->addItem(FileManagement::toString(FileManagement::FileType::MSOfficeSpreadsheet97), FileManagement::FileType::MSOfficeSpreadsheet97);
cbx->addItem(FileManagement::toString(FileManagement::FileType::MSOfficePresentation), FileManagement::FileType::MSOfficePresentation);
cbx->addItem(FileManagement::toString(FileManagement::FileType::MSOfficePresentation97), FileManagement::FileType::MSOfficePresentation97);
cbx->addItem(FileManagement::toString(FileManagement::FileType::EvaluationSchema), FileManagement::FileType::EvaluationSchema);
cbx->addItem(FileManagement::toString(FileManagement::FileType::AdlerJson), FileManagement::FileType::AdlerJson);
break;
}
case FlmComboBoxType::CbUnknown:
default:
break;
}
return cbx->count() > 0;
}
} // namespace FileManagement
+35
View File
@@ -0,0 +1,35 @@
/**
* @RDE_HEADER@
* FileManagement - FlmComboBox Gui Plugin
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-29
*/
#pragma once
#include <LtsWidgets/lts_combo_box.h>
#include <FileManagement/logger.h>
namespace FileManagement
{
enum FlmComboBoxType
{
CbUnknown = 0,
CbFileCategory,
CbFileStatus,
CbFileType
};
// --------------------------------------------------------
// ComboBox
// --------------------------------------------------------
class FlmComboBox
{
public:
Q_REQUIRED_RESULT static bool fill(LtsWidgets::LtsComboBox *cbx,
FlmComboBoxType type);
};
} // namespace FileManagement
@@ -0,0 +1,54 @@
/**
* @RDE_HEADER@
* GUI Plugin for FileManagement - FlmComboBox
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-29
*/
#include "flm_combobox_gui_plugin.h"
namespace FileManagement
{
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
{
return std::make_shared<InterfaceImpl>(session);
}
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.FlmCombobox"))
{}
bool InterfaceImpl::fetchInterfaces()
{
return true;
}
void InterfaceImpl::clearInterfaces()
{
}
bool InterfaceImpl::fillFileCategoryComboBox(LtsWidgets::LtsComboBox *cbx)
{
return fillFlmComboBox(cbx, FlmComboBoxType::CbFileCategory);
}
bool InterfaceImpl::fillFileStatusComboBox(LtsWidgets::LtsComboBox *cbx)
{
return fillFlmComboBox(cbx, FlmComboBoxType::CbFileStatus);
}
bool InterfaceImpl::fillFileTypeComboBox(LtsWidgets::LtsComboBox *cbx)
{
return fillFlmComboBox(cbx, FlmComboBoxType::CbFileType);
}
//private
bool InterfaceImpl::fillFlmComboBox(LtsWidgets::LtsComboBox *cbx, FlmComboBoxType type)
{
return FlmComboBox::fill(cbx, type);
}
} // namespace FileManagement
@@ -0,0 +1,67 @@
/**
* @RDE_HEADER@
* Gui Plugin for FileManagement - FlmComboBox
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-29
*/
#pragma once
#include "flm_combobox.h"
#include <LtsSession/lts_session.h>
#include <FileManagement/logger.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_combobox_gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <QComboBox>
namespace FileManagement
{
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
{
Q_PLUGIN_METADATA(IID "gui:3:flm.combobox")
Q_INTERFACES(GuiPluginBase::Plugin)
Q_OBJECT
public:
GuiPlugin() = default;
~GuiPlugin() = default;
QString pluginName() override { return QStringLiteral("FileManagement.GuiPlugin.ComboBox"); }
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 ForeignGuiComboboxInterface, public GuiPluginBase::Interface
{
Q_OBJECT
public:
explicit InterfaceImpl(LtsSession::LtsSession *session);
bool fetchInterfaces() override;
void clearInterfaces() override;
QString menuGroup() const override { return QString(); }
bool availableInPartition(IDL::PartitionType partition) const override { return partition == IDL::PartitionType::Global || partition == IDL::PartitionType::Exercise; }
// ForeignDataInterface
bool fillFileCategoryComboBox(LtsWidgets::LtsComboBox *cbx) override;
bool fillFileStatusComboBox(LtsWidgets::LtsComboBox *cbx) override;
bool fillFileTypeComboBox(LtsWidgets::LtsComboBox *cbx) override;
private:
bool fillFlmComboBox(LtsWidgets::LtsComboBox *cbx, FlmComboBoxType type);
};
} // namespace FileManagement
+22
View File
@@ -0,0 +1,22 @@
# TODO: templates project specific ?
# Libre Office templates
SET(libreOfficeTemplates
Default.odt
Default.ods
Default.odp
)
# MS Office templates
SET(MSOfficeTemplates
Default.doc
Default.docx
Default.xls
Default.xlsx
Default.ppt
Default.pptx
VWU_Karten.docx
)
NGL_INSTALL(WS FILES ${libreOfficeTemplates} DESTINATION share/Lts/templates)
NGL_INSTALL(WS FILES ${MSOfficeTemplates} DESTINATION share/Lts/templates)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,32 @@
/**
* @RDE_HEADER@
* Gui Combobox Plugin for FileManagement
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2017-05-29
*/
#pragma once
#include <QObject>
namespace LtsWidgets
{
class LtsComboBox;
}
namespace FileManagement
{
class ForeignGuiComboboxInterface
{
public:
ForeignGuiComboboxInterface() = default;
virtual ~ForeignGuiComboboxInterface() = default;
virtual bool fillFileCategoryComboBox(LtsWidgets::LtsComboBox *cbx) = 0;
virtual bool fillFileStatusComboBox(LtsWidgets::LtsComboBox *cbx) = 0;
virtual bool fillFileTypeComboBox(LtsWidgets::LtsComboBox *cbx) = 0;
};
} // namespace FileManagement
+30
View File
@@ -0,0 +1,30 @@
/**
* @RDE_HEADER@
* FileManagement Explorer Interface for access from other Plugins
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, SLSE, 2017-03-31
*/
#pragma once
#include <PluginInterfaces/data_plugin_interface.h>
#include <FileManagement/flm_dtc.h>
#include <FileManagement/flm_ftc.h>
namespace FileManagement
{
/**
* @brief The DataInterface class provides the Topics Clients only for the GUI Plugins
*/
class DataInterface : public DataPluginBase::Interface
{
public:
using DataPluginBase::Interface::Interface;
virtual std::shared_ptr<FileManagement::Interface::Dtc> getDtc() = 0;
virtual std::shared_ptr<FileManagement::Interface::Ftc> getFtc() = 0;
};
} // namespace FileManagement
@@ -0,0 +1,81 @@
/**
* @RDE_HEADER@
* FileManagement Explorer Interface for access from other Plugins
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, SLSE, 2017-03-31
*/
#pragma once
#include <FileManagement/flm_enums.hpp>
#include <FileManagement/flm_dtc.h>
#include <PluginInterfaces/topic_replay_interface.h>
#include <TopicEditorBase/topic_editor_interface.h>
namespace FileManagement
{
// TODO: ForeignGuiInterface => ForeignExplorerGuiInterface
class ForeignGuiInterface : public TopicReplay::Factory, public TopicEditorBase::Interface
{
public:
ForeignGuiInterface() = default;
virtual ~ForeignGuiInterface() = default;
static QString pluginName() { return QStringLiteral("FlmExplorerGuiPlugin"); }
// opens the file open dialog and directly downloads the file (if possible), returns the fileId
virtual int loadFileContent(QWidget *parent,
QByteArray &content,
const QVector<FileType> &fileTypes,
int exerciseId,
const QString &xmlType = QString(),
int initialFolderId = 0) = 0;
// only select file content, returns fileId
virtual int selectFileContent(QWidget *parent,
const QVector<FileType> &fileTypes,
int exerciseId,
int initialFolderId = 0) = 0;
// save the content and optional properties, returns fileId
virtual int saveFileContent(QWidget *parent,
FileType targetFileType,
int exerciseId,
const QByteArray &content,
int initialFolderId = 0,
const QString &properties = QString()) = 0;
// load file content
virtual bool loadContent(int fileId,
QByteArray &content,
bool bQuiet = false) = 0;
// overwrite content and properties for fileId
virtual bool saveContent(int fileId,
const QByteArray &content,
const QString &properties = QString()) = 0;
// create new file content based on fc, returns fileId
virtual int newFileContent(FileManagement::FileContent fc,
const QByteArray &content) = 0;
// change status to deleted
virtual bool deleteFileContent(int fileId) = 0;
// return fileId for a fileName
virtual int getFileId(FileManagement::FileType fileType, const QString &fileName, int exId, int phId) const = 0;
// return fileName for a fileId (without using dtc)
virtual QString getFileName(int fileId) const = 0;
// check if a xml content has key "XmlType" with value searchedType
virtual bool isXmlType(const QByteArray &content, const QString &searchedType) const = 0;
// return the value of key XmlType, if exists
virtual QString hasXmlType(const QByteArray &content) const = 0;
};
} // namespace FileManagement