Continues migration with DDS, Common
This commit is contained in:
1 parent
9b15cee841
commit
fa48db111e
668 files changed
+111841
-2
No files matched your search
Executable
+48
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLSE, 2017-04-27
|
||||
#
|
||||
|
||||
|
||||
# Topic Editor Interface
|
||||
ADD_INTERFACE_LIBRARY(
|
||||
TopicEditorInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/topic_editor_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
Qt5::Core
|
||||
)
|
||||
|
||||
# Library
|
||||
SET(topic_editor_base_SRCS
|
||||
topic_editor_base.cpp
|
||||
topic_editor_base.h
|
||||
topic_editor_utils.cpp
|
||||
topic_editor_utils.h
|
||||
topic_preview_widget.cpp
|
||||
topic_preview_widget.h
|
||||
topic_previewer.cpp
|
||||
topic_previewer.h
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(topic_editor_base_SRCS
|
||||
topic_preview_widget.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS TopicEditorBase SHARED ${topic_editor_base_SRCS})
|
||||
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(TopicEditorBase
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../ # auto-export file
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(TopicEditorBase
|
||||
LtsScriptTimeline
|
||||
Qt5::Widgets
|
||||
Qt5::Core
|
||||
LtsWidgets
|
||||
LtsUtilsCore
|
||||
)
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
|
||||
|
||||
|
||||
#include "topic_editor_base.h"
|
||||
#include "topic_preview_widget.h"
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace TopicEditorBase
|
||||
{
|
||||
|
||||
TopicEditor::TopicEditor(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_previewWidget(nullptr)
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->hide();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TopicEditor::setTopicData(const TopicEditorBase::TopicData &data)
|
||||
{
|
||||
m_topicData = data;
|
||||
m_topicDuration = data.duration;
|
||||
|
||||
if (m_previewWidget == nullptr)
|
||||
{
|
||||
QMessageBox::critical(
|
||||
nullptr, QStringLiteral("An den Entwickler!"),
|
||||
QStringLiteral("!! STOP !! - Dieser Topic Editor hatte 'init()' vorher nicht aufgerufen!")
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_previewWidget->setTopicData(m_topicData);
|
||||
|
||||
bool isAlreadyUnchangeable = unchangeable();
|
||||
if (!isAlreadyUnchangeable)
|
||||
setUnchangeable(true);
|
||||
|
||||
updateInternalData();
|
||||
|
||||
if (!isAlreadyUnchangeable)
|
||||
setUnchangeable(false);
|
||||
}
|
||||
|
||||
|
||||
void TopicEditor::setDuration(int duration)
|
||||
{
|
||||
m_topicData.duration = duration;
|
||||
updateInternalLength();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TopicEditor::init(TopicPreviewWidget *widget)
|
||||
{
|
||||
m_previewWidget = widget;
|
||||
connect(m_previewWidget, &TopicPreviewWidget::deleteMe,
|
||||
this, &TopicEditor::deleteLater);
|
||||
|
||||
|
||||
m_previewWidget->setTopicEnabled(false);
|
||||
connect(this, &TopicEditor::signalChangesMade, this, [this]()
|
||||
{
|
||||
m_previewWidget->setTopicEnabled(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void TopicEditor::setTopicDataProperty(const QString &key, const QJsonValue &value)
|
||||
{
|
||||
m_topicData.properties[key] = value;
|
||||
emit signalChangesMade();
|
||||
}
|
||||
|
||||
|
||||
void TopicEditor::applied()
|
||||
{
|
||||
m_previewWidget->setTopicEnabled(true);
|
||||
emit topicDataChanged();
|
||||
}
|
||||
|
||||
void TopicEditor::setIsPlaying(bool isPlaying)
|
||||
{
|
||||
m_isPlaying = isPlaying;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool TopicEditor::apply()
|
||||
{
|
||||
if (m_previewWidget == nullptr)
|
||||
{
|
||||
QMessageBox::critical(
|
||||
nullptr, QStringLiteral("An den Entwickler!"),
|
||||
QStringLiteral("!! STOP !! - Dieser Topic Editor hatte 'init()' vorher nicht aufgerufen!")
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
if (m_isPlaying)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Please Stop Playback first"));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = apply2();
|
||||
if (result)
|
||||
applied();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "topic_editor_utils.h"
|
||||
|
||||
#include <TopicEditorBase/topiceditorbase_export.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsCore/promise.h>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
namespace LtsUtils { class Promise; }
|
||||
|
||||
|
||||
namespace TopicEditorBase
|
||||
{
|
||||
|
||||
class TopicPreviewWidget;
|
||||
|
||||
|
||||
class TOPICEDITORBASE_EXPORT ExportNotifier : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ExportNotifier(QObject *parent)
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
bool isSuccessful = false;
|
||||
QString successMessage;
|
||||
|
||||
void setExportSuccessful(const QString &message)
|
||||
{
|
||||
isSuccessful = true;
|
||||
successMessage = message;
|
||||
emit exportSuccessful(message);
|
||||
emit exportFinished();
|
||||
}
|
||||
|
||||
void setExportFailed()
|
||||
{
|
||||
isSuccessful = false;
|
||||
successMessage = QString();
|
||||
emit exportFailed();
|
||||
emit exportFinished();
|
||||
}
|
||||
|
||||
signals:
|
||||
void stillAlive();
|
||||
void exportSuccessful(const QString &);
|
||||
void exportFailed();
|
||||
void exportFinished();
|
||||
};
|
||||
|
||||
|
||||
class TOPICEDITORBASE_EXPORT TopicEditor: public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TopicEditor(QWidget *parent = nullptr);
|
||||
virtual ~TopicEditor() = default;
|
||||
|
||||
TopicData &topicData() { return m_topicData; }
|
||||
void setTopicData(const TopicData &data);
|
||||
|
||||
int topicId() const { return m_topicData.id; }
|
||||
|
||||
int startTime() const { return m_topicData.startTime; }
|
||||
void setStartTime(int start) { m_topicData.startTime = start; }
|
||||
|
||||
int duration() const { return m_topicData.duration; }
|
||||
void setDuration(int duration);
|
||||
|
||||
QString description() const { return m_topicData.description; }
|
||||
void setDescription(const QString &description) { m_topicData.description = description; }
|
||||
|
||||
TopicPreviewWidget *topicPreviewWidget() { return m_previewWidget; }
|
||||
|
||||
protected:
|
||||
void init(TopicPreviewWidget *widget);
|
||||
|
||||
|
||||
|
||||
virtual void updateInternalData() = 0;
|
||||
virtual void updateInternalLength() {}
|
||||
|
||||
TopicType topicType() const { return m_topicData.topicType; }
|
||||
QJsonValue getTopicDataValue(const QString &key) const { return m_topicData.properties.value(key); }
|
||||
QJsonArray getTopicVDataAsArray(const QString &key) const { return m_topicData.properties.value(key).toArray(); }
|
||||
|
||||
bool hasTopicDataProperties() const { return !m_topicData.properties.isEmpty(); }
|
||||
void setTopicDataProperty(const QString &key, const QJsonValue &value);
|
||||
|
||||
void applied();
|
||||
|
||||
public slots:
|
||||
virtual bool apply2() = 0;
|
||||
void setIsPlaying(bool isPlaying);
|
||||
|
||||
private slots:
|
||||
bool apply() override final;
|
||||
|
||||
signals:
|
||||
void topicDataChanged();
|
||||
void topicEditorRequested(const TopicData &);
|
||||
void durationCheckRequested(int duration, LtsUtils::Promise *promise);
|
||||
void signalSetTopicPosition(QWidget *widget, int ignoreTopicForReplay);
|
||||
void changesSaved(const TopicData &data);
|
||||
|
||||
protected:
|
||||
TopicData m_topicData;
|
||||
int m_topicDuration{-1};
|
||||
bool m_isPlaying {false};
|
||||
|
||||
TopicPreviewWidget *m_previewWidget{nullptr};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "topic_editor_utils.h"
|
||||
|
||||
|
||||
namespace TopicEditorBase
|
||||
{
|
||||
|
||||
class TopicEditor;
|
||||
|
||||
class Interface
|
||||
{
|
||||
|
||||
public:
|
||||
virtual ~Interface() = default;
|
||||
|
||||
|
||||
|
||||
virtual TopicEditor *createTopicEditor(const TopicData &) = 0;
|
||||
virtual bool initTopicEditor() { return true; }
|
||||
virtual void finishTopicEditor() {}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+318
@@ -0,0 +1,318 @@
|
||||
#include "topic_editor_utils.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QHash>
|
||||
#include <QIcon>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QLabel>
|
||||
#include <QString>
|
||||
|
||||
|
||||
namespace TopicEditorBase
|
||||
{
|
||||
|
||||
QString topicTypeTranslation(TopicType topicType)
|
||||
{
|
||||
switch (topicType)
|
||||
{
|
||||
case TopicType::SituationMap:
|
||||
return QLabel::tr("SituationMap");
|
||||
case TopicType::SituationReplay:
|
||||
return QLabel::tr("SituationReplay");
|
||||
case TopicType::Image:
|
||||
return QLabel::tr("Image");
|
||||
case TopicType::Text:
|
||||
return QLabel::tr("Text");
|
||||
case TopicType::Pdf:
|
||||
return QLabel::tr("Pdf");
|
||||
case TopicType::Xml:
|
||||
return QLabel::tr("Xml");
|
||||
case TopicType::TacticalPlan:
|
||||
return QLabel::tr("TacticalPlan");
|
||||
case TopicType::MSOffice:
|
||||
return QLabel::tr("MSOffice");
|
||||
case TopicType::OpenOffice:
|
||||
return QLabel::tr("OpenOffice");
|
||||
case TopicType::Audio:
|
||||
return QLabel::tr("Audio");
|
||||
case TopicType::Video:
|
||||
return QLabel::tr("Video");
|
||||
case TopicType::Building:
|
||||
return QLabel::tr("Building");
|
||||
case TopicType::SituationMapFilter:
|
||||
return QLabel::tr("SituationMapFilter");
|
||||
case TopicType::Snapshot:
|
||||
return QLabel::tr("Snapshot");
|
||||
case TopicType::Evaluation:
|
||||
return QLabel::tr("Evaluation");
|
||||
case TopicType::Report:
|
||||
return QLabel::tr("Report");
|
||||
case TopicType::Situation:
|
||||
return QLabel::tr("Situation");
|
||||
case TopicType::Invalid:
|
||||
default:
|
||||
return QLabel::tr("Invalid");
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
|
||||
}
|
||||
|
||||
QString topicTypeString(TopicType topicType)
|
||||
{
|
||||
switch (topicType)
|
||||
{
|
||||
case TopicType::SituationMap:
|
||||
return QStringLiteral("SituationMap");
|
||||
case TopicType::SituationReplay:
|
||||
return QStringLiteral("SituationReplay");
|
||||
case TopicType::Image:
|
||||
return QStringLiteral("Image");
|
||||
case TopicType::Text:
|
||||
return QStringLiteral("Text");
|
||||
case TopicType::Pdf:
|
||||
return QStringLiteral("Pdf");
|
||||
case TopicType::Xml:
|
||||
return QStringLiteral("Xml");
|
||||
case TopicType::TacticalPlan:
|
||||
return QStringLiteral("TacticalPlan");
|
||||
case TopicType::MSOffice:
|
||||
return QStringLiteral("MSOffice");
|
||||
case TopicType::OpenOffice:
|
||||
return QStringLiteral("OpenOffice");
|
||||
case TopicType::Audio:
|
||||
return QStringLiteral("Audio");
|
||||
case TopicType::Video:
|
||||
return QStringLiteral("Video");
|
||||
case TopicType::Building:
|
||||
return QStringLiteral("Building");
|
||||
case TopicType::SituationMapFilter:
|
||||
return QStringLiteral("SituationMapFilter");
|
||||
case TopicType::Snapshot:
|
||||
return QStringLiteral("Snapshot");
|
||||
case TopicType::Evaluation:
|
||||
return QStringLiteral("Evaluation");
|
||||
case TopicType::Report:
|
||||
return QStringLiteral("Report");
|
||||
case TopicType::Situation:
|
||||
return QStringLiteral("Situation");
|
||||
case TopicType::Invalid:
|
||||
default:
|
||||
return QStringLiteral("Invalid");
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
TopicType topicTypeFromString(const QString &topicName)
|
||||
{
|
||||
static const QHash<QString, TopicType> topics =
|
||||
{
|
||||
{ QStringLiteral("Invalid"), TopicType::Invalid },
|
||||
{ QStringLiteral("SituationMap"), TopicType::SituationMap },
|
||||
{ QStringLiteral("SituationReplay"), TopicType::SituationReplay },
|
||||
{ QStringLiteral("Image"), TopicType::Image },
|
||||
{ QStringLiteral("Text"), TopicType::Text },
|
||||
{ QStringLiteral("Pdf"), TopicType::Pdf },
|
||||
{ QStringLiteral("Xml"), TopicType::Xml },
|
||||
{ QStringLiteral("TacticalPlan"), TopicType::TacticalPlan },
|
||||
{ QStringLiteral("MSOffice"), TopicType::MSOffice },
|
||||
{ QStringLiteral("OpenOffice"), TopicType::OpenOffice },
|
||||
{ QStringLiteral("Audio"), TopicType::Audio },
|
||||
{ QStringLiteral("Video"), TopicType::Video },
|
||||
{ QStringLiteral("Building"), TopicType::Building },
|
||||
{ QStringLiteral("SituationMapFilter"), TopicType::SituationMapFilter },
|
||||
{ QStringLiteral("Snapshot"), TopicType::Snapshot },
|
||||
{ QStringLiteral("Evaluation"), TopicType::Evaluation },
|
||||
{ QStringLiteral("Report"), TopicType::Report },
|
||||
{ QStringLiteral("Situation"), TopicType::Situation },
|
||||
};
|
||||
return topics.contains(topicName) ? topics.value(topicName) : TopicType::Invalid;
|
||||
}
|
||||
|
||||
QIcon topicIcon(const TopicType topicType)
|
||||
{
|
||||
switch (topicType)
|
||||
{
|
||||
case TopicType::SituationMap:
|
||||
return QIcon(QLatin1String("icon:add_situation.svg"));
|
||||
case TopicType::Situation:
|
||||
return QIcon(QLatin1String("icon:add_situation_combined.svg"));
|
||||
case TopicType::SituationReplay:
|
||||
return QIcon(QLatin1String("icon:add_restart.svg"));
|
||||
case TopicType::Image:
|
||||
return QIcon(QLatin1String("icon:create_image_topic.svg"));
|
||||
case TopicType::Text:
|
||||
return QIcon(QLatin1String("icon:document-new-txt.svg"));
|
||||
case TopicType::Pdf:
|
||||
return QIcon(QLatin1String("icon:create_pdf_topic.svg"));
|
||||
case TopicType::Xml:
|
||||
return QIcon(QLatin1String("icon:document-new-xml.svg"));
|
||||
case TopicType::TacticalPlan:
|
||||
return QIcon(QLatin1String("icon:tactical_organization.svg"));
|
||||
case TopicType::MSOffice:
|
||||
return QIcon(QLatin1String("icon:ms_office.svg"));
|
||||
case TopicType::OpenOffice:
|
||||
return QIcon(QLatin1String("icon:documents.svg"));
|
||||
case TopicType::Audio:
|
||||
return QIcon(QLatin1String("icon:create_lecture_topic.svg"));
|
||||
case TopicType::Video:
|
||||
return QIcon(QLatin1String("icon:add_video_menu.svg"));
|
||||
case TopicType::Building:
|
||||
return QIcon(QLatin1String("icon:configure_buildings.svg"));
|
||||
case TopicType::SituationMapFilter:
|
||||
return QIcon(QLatin1String("icon:filter_player.svg"));
|
||||
case TopicType::Snapshot:
|
||||
return QIcon(QLatin1String("icon:create_snapshot.svg"));
|
||||
case TopicType::Evaluation:
|
||||
return QIcon(QLatin1String("icon:add_evaluation_elements.svg"));
|
||||
case TopicType::Report:
|
||||
return QIcon(QLatin1String("icon:add_reports_display.svg"));
|
||||
case TopicType::Invalid:
|
||||
default:
|
||||
return QIcon();
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
QColor topicTypeColor(TopicType topicType)
|
||||
{
|
||||
switch (topicType)
|
||||
{
|
||||
case TopicType::SituationMap:
|
||||
return QRgb(0xb1cbbb);
|
||||
case TopicType::SituationReplay:
|
||||
return QRgb(0xc94c4c);
|
||||
case TopicType::Image:
|
||||
return QRgb(0xfefbd8);
|
||||
case TopicType::Text:
|
||||
return QRgb(0x92a8d1);
|
||||
case TopicType::Pdf:
|
||||
return QRgb(0x80ced6);
|
||||
case TopicType::Xml:
|
||||
return QRgb(0xeea29a);
|
||||
case TopicType::TacticalPlan:
|
||||
return QRgb(0xdac292);
|
||||
case TopicType::MSOffice:
|
||||
return QRgb(0xf7cac9);
|
||||
case TopicType::OpenOffice:
|
||||
return QRgb(0xb2b2b2);
|
||||
case TopicType::Audio:
|
||||
return QRgb(0x034f84);
|
||||
case TopicType::Video:
|
||||
return QRgb(0x618685);
|
||||
case TopicType::Building:
|
||||
return QRgb(0xc6bcb6);
|
||||
case TopicType::SituationMapFilter:
|
||||
return QRgb(0x36486b);
|
||||
case TopicType::Snapshot:
|
||||
return QRgb(0xf18973);
|
||||
case TopicType::Evaluation:
|
||||
return QRgb(0xd6cbd3);
|
||||
case TopicType::Report:
|
||||
return QRgb(0xfeb236);
|
||||
case TopicType::Situation:
|
||||
return QRgb(0xb1c1cb);
|
||||
case TopicType::Invalid:
|
||||
default:
|
||||
return Qt::black;
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, TopicType topicType)
|
||||
{
|
||||
stream << "TopicType::" << topicTypeString(topicType).toStdString().c_str();
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const QString TopicData::mime = QStringLiteral("application/rheinmetall.topiceditorbase.topicdata");
|
||||
|
||||
|
||||
TopicData::TopicData(TopicType topicType)
|
||||
: topicType(topicType)
|
||||
{}
|
||||
|
||||
TopicData::TopicData(TopicType topicType, int duration)
|
||||
: topicType(topicType)
|
||||
, duration(duration)
|
||||
{}
|
||||
|
||||
TopicData::TopicData(
|
||||
int id, TopicType topicType, int startTime, int duration, const QString &description, const QString &channel,
|
||||
const QJsonObject &properties
|
||||
)
|
||||
: topicType(topicType)
|
||||
, id(id)
|
||||
, startTime(startTime)
|
||||
, duration(duration)
|
||||
, properties(properties)
|
||||
, description(description)
|
||||
, channel(channel)
|
||||
{}
|
||||
|
||||
|
||||
void TopicData::fromJson(const QJsonObject &obj)
|
||||
{
|
||||
id = obj[QStringLiteral("topicId")].toInt();
|
||||
topicType = static_cast<TopicType>(obj[QStringLiteral("type")].toInt());
|
||||
startTime = obj[QStringLiteral("startTime")].toInt(-1);
|
||||
duration = obj[QStringLiteral("length")].toInt(-1);
|
||||
state = obj[QStringLiteral("isSet")].toBool();
|
||||
index = obj[QStringLiteral("index")].toInt();
|
||||
properties = obj[QStringLiteral("detailData")].toObject();
|
||||
description = obj[QStringLiteral("description")].toString();
|
||||
channel = obj[QStringLiteral("channelName")].toString();
|
||||
parentChannel = obj[QStringLiteral("filterParentChannel")].toString();
|
||||
x = obj[QStringLiteral("x")].toDouble();
|
||||
y = obj[QStringLiteral("y")].toDouble();
|
||||
w = obj[QStringLiteral("w")].toDouble();
|
||||
h = obj[QStringLiteral("h")].toDouble();
|
||||
}
|
||||
|
||||
|
||||
QJsonObject TopicData::toJson() const
|
||||
{
|
||||
return QJsonObject({
|
||||
{ QStringLiteral("topicId"), id },
|
||||
{ QStringLiteral("startTime"), startTime },
|
||||
{ QStringLiteral("length"), duration },
|
||||
{ QStringLiteral("type"), static_cast<int>(topicType) },
|
||||
{ QStringLiteral("isSet"), state },
|
||||
{ QStringLiteral("index"), index },
|
||||
{ QStringLiteral("detailData"), properties },
|
||||
{ QStringLiteral("description"), description },
|
||||
{ QStringLiteral("channelName"), channel },
|
||||
{ QStringLiteral("filterParentChannel"), parentChannel },
|
||||
{ QStringLiteral("x"), x },
|
||||
{ QStringLiteral("y"), y },
|
||||
{ QStringLiteral("w"), w },
|
||||
{ QStringLiteral("h"), h }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
QDataStream &operator<<(QDataStream &stream, const TopicData &data)
|
||||
{
|
||||
const QByteArray properties = QJsonDocument(data.properties).toBinaryData();
|
||||
stream << data.id << static_cast<quint8>(data.topicType) << data.startTime << data.duration << data.state << data.index
|
||||
<< properties << data.description << data.channel << data.parentChannel << data.x << data.y << data.w << data.h;
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &operator >>(QDataStream &stream, TopicData &data)
|
||||
{
|
||||
QByteArray properties;
|
||||
quint8 topicType;
|
||||
stream >> data.id >> topicType >> data.startTime >> data.duration >> data.state >> data.index >> properties
|
||||
>> data.description >> data.channel >> data.parentChannel >> data.x >> data.y >> data.w >> data.h;
|
||||
data.topicType = static_cast<TopicType>(topicType);
|
||||
data.properties = QJsonDocument::fromBinaryData(properties).object();
|
||||
return stream;
|
||||
}
|
||||
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <TopicEditorBase/topiceditorbase_export.h>
|
||||
|
||||
#include <LtsScriptTimeline/track_entry.h>
|
||||
|
||||
#include <QVector>
|
||||
|
||||
|
||||
class QColor;
|
||||
|
||||
|
||||
namespace TopicEditorBase
|
||||
{
|
||||
|
||||
enum class TopicType
|
||||
{
|
||||
Invalid,
|
||||
SituationMap,
|
||||
SituationReplay,
|
||||
Image,
|
||||
Text,
|
||||
Pdf,
|
||||
Xml,
|
||||
TacticalPlan,
|
||||
MSOffice,
|
||||
OpenOffice,
|
||||
Audio,
|
||||
Video,
|
||||
Building,
|
||||
SituationMapFilter,
|
||||
Snapshot,
|
||||
Evaluation,
|
||||
Report,
|
||||
Situation
|
||||
};
|
||||
typedef QVector<TopicType> TopicTypes;
|
||||
|
||||
TOPICEDITORBASE_EXPORT QString topicTypeTranslation(TopicType topicType);
|
||||
|
||||
TOPICEDITORBASE_EXPORT QString topicTypeString(TopicType topicType);
|
||||
|
||||
TOPICEDITORBASE_EXPORT TopicType topicTypeFromString(const QString &topicName);
|
||||
|
||||
TOPICEDITORBASE_EXPORT QIcon topicIcon(TopicType topicType);
|
||||
|
||||
TOPICEDITORBASE_EXPORT QColor topicTypeColor(TopicType topicType);
|
||||
|
||||
TOPICEDITORBASE_EXPORT std::ostream& operator<<(std::ostream& stream, TopicType topicType);
|
||||
|
||||
|
||||
struct TOPICEDITORBASE_EXPORT TopicData
|
||||
{
|
||||
static const QString mime;
|
||||
|
||||
TopicType topicType{TopicType::Invalid};
|
||||
int id{-1};
|
||||
int startTime{-1};
|
||||
int duration{0};
|
||||
|
||||
bool state{false};
|
||||
int index{-1};
|
||||
|
||||
QJsonObject properties;
|
||||
QString description;
|
||||
QString channel;
|
||||
QString parentChannel;
|
||||
|
||||
|
||||
double x{0.};
|
||||
double y{0.};
|
||||
double h{0.};
|
||||
double w{0.};
|
||||
|
||||
TopicData() = default;
|
||||
TopicData(const TopicData &data) = default;
|
||||
explicit TopicData(TopicType topicType);
|
||||
explicit TopicData(TopicType topicType, int duration);
|
||||
explicit TopicData(
|
||||
int id, TopicType topicType, int startTime, int duration, const QString &description, const QString &channel,
|
||||
const QJsonObject &properties
|
||||
);
|
||||
|
||||
void fromJson(const QJsonObject &obj);
|
||||
QJsonObject toJson() const;
|
||||
};
|
||||
|
||||
TOPICEDITORBASE_EXPORT QDataStream &operator<<(QDataStream &stream, const TopicData &data);
|
||||
TOPICEDITORBASE_EXPORT QDataStream &operator>>(QDataStream &stream, TopicData &data);
|
||||
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
#include "topic_preview_widget.h"
|
||||
#include "ui_topic_preview_widget.h"
|
||||
#include "topic_previewer.h"
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
|
||||
#include <QContextMenuEvent>
|
||||
#include <QJsonDocument>
|
||||
#include <QMenu>
|
||||
#include <QTextEdit>
|
||||
|
||||
|
||||
namespace TopicEditorBase
|
||||
{
|
||||
|
||||
TopicPreviewWidget::TopicPreviewWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::TopicPreviewWidget)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->lbxTopicId->hide();
|
||||
m_ui->lblTopicId->hide();
|
||||
|
||||
m_ui->lbxDuration->hide();
|
||||
m_ui->lblDuration->hide();
|
||||
#endif
|
||||
connect(m_ui->widget, &TopicPreviewer::deleteMe,
|
||||
this, &TopicPreviewWidget::deleteMe);
|
||||
|
||||
|
||||
connect(m_ui->widget, &TopicPreviewer::startDragMe,
|
||||
this, &TopicPreviewWidget::startDragMe);
|
||||
connect(m_ui->widget, &TopicPreviewer::stopDragMe,
|
||||
this, &TopicPreviewWidget::stopDragMe);
|
||||
}
|
||||
|
||||
TopicPreviewWidget::~TopicPreviewWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TopicPreviewWidget::setTopicEnabled(bool enabled)
|
||||
{
|
||||
m_ui->widget->setEnabled(enabled);
|
||||
}
|
||||
|
||||
|
||||
void TopicPreviewWidget::setTopicData(const TopicData &data)
|
||||
{
|
||||
m_ui->lbxDragAndDrop->setVisible(!data.state);
|
||||
m_ui->widget->setVisible(!data.state);
|
||||
|
||||
m_ui->leDescription->setText(data.description);
|
||||
m_ui->lblTopicId->setText(QString::number(data.id));
|
||||
m_ui->lblDuration->setText(QString::number(data.duration));
|
||||
m_ui->widget->setTopicData(data);
|
||||
}
|
||||
|
||||
|
||||
QString TopicPreviewWidget::description() const
|
||||
{
|
||||
return m_ui->leDescription->text();
|
||||
}
|
||||
|
||||
|
||||
void TopicPreviewWidget::setDescription(const QString &description)
|
||||
{
|
||||
m_ui->leDescription->setText(description);
|
||||
}
|
||||
|
||||
|
||||
TopicPreviewer *TopicPreviewWidget::previewer()
|
||||
{
|
||||
return m_ui->widget;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TopicPreviewWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
#ifndef LTS_DEBUG
|
||||
if (LtsSessionData::LtsSessionData::getInstance()->debugFlagValue(QStringLiteral("TopicPreviewWidget.DebugMenu")) == QVariant(true))
|
||||
#endif
|
||||
{
|
||||
QMenu *menu = new QMenu(this);
|
||||
menu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QPoint p = mapToGlobal(menu->pos());
|
||||
menu->setGeometry(QRect(p, QPoint(event->x(), event->y())));
|
||||
menu->addAction(QStringLiteral("enable"), this, [this]()
|
||||
{
|
||||
setTopicEnabled(true);
|
||||
});
|
||||
|
||||
menu->addAction(QStringLiteral("disable"), this, [this]()
|
||||
{
|
||||
setTopicEnabled(false);
|
||||
});
|
||||
menu->addAction(QStringLiteral("show properties"), this, [this]()
|
||||
{
|
||||
TopicData data = m_ui->widget->topicData();
|
||||
if (data.properties.isEmpty())
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, QStringLiteral("no properties available"));
|
||||
return;
|
||||
}
|
||||
|
||||
QTextEdit *ted = new QTextEdit(nullptr);
|
||||
ted->setAttribute(Qt::WA_DeleteOnClose);
|
||||
ted->setWindowTitle(QStringLiteral("Track Entry #%1 - Detail Data string").arg(data.id));
|
||||
ted->setText(QString::fromUtf8(QJsonDocument(data.properties).toJson()));
|
||||
ted->setReadOnly(true);
|
||||
ted->show();
|
||||
});
|
||||
|
||||
menu->show();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "topic_editor_utils.h"
|
||||
|
||||
#include <TopicEditorBase/topiceditorbase_export.h>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace Ui { class TopicPreviewWidget; }
|
||||
|
||||
|
||||
namespace TopicEditorBase
|
||||
{
|
||||
|
||||
class TopicPreviewer;
|
||||
|
||||
|
||||
class TOPICEDITORBASE_EXPORT TopicPreviewWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TopicPreviewWidget(QWidget *parent = nullptr);
|
||||
~TopicPreviewWidget();
|
||||
|
||||
void setTopicData(const TopicData &data);
|
||||
void setTopicEnabled(bool enabled);
|
||||
|
||||
QString description() const;
|
||||
void setDescription(const QString &description);
|
||||
|
||||
TopicPreviewer *previewer();
|
||||
|
||||
private:
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
|
||||
signals:
|
||||
void startDragMe();
|
||||
void stopDragMe();
|
||||
void deleteMe();
|
||||
|
||||
private:
|
||||
Ui::TopicPreviewWidget *m_ui{nullptr};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TopicPreviewWidget</class>
|
||||
<widget class="QWidget" name="TopicPreviewWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>296</width>
|
||||
<height>132</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<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="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblTopicId">
|
||||
<property name="text">
|
||||
<string notr="true">?</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lbxDragAndDrop">
|
||||
<property name="text">
|
||||
<string>Drag & Drop:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxDescription">
|
||||
<property name="text">
|
||||
<string>Description:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxTopicId">
|
||||
<property name="text">
|
||||
<string>[Topic id:]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lblDuration">
|
||||
<property name="text">
|
||||
<string>?</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbxDuration">
|
||||
<property name="text">
|
||||
<string>[Topic duration:]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="TopicEditorBase::TopicPreviewer" name="widget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="leDescription"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>TopicEditorBase::TopicPreviewer</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>TopicEditorBase/topic_previewer.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
#include "topic_previewer.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDrag>
|
||||
#include <QMimeData>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
namespace TopicEditorBase
|
||||
{
|
||||
|
||||
TopicPreviewer::TopicPreviewer(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
|
||||
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
TopicPreviewer::~TopicPreviewer()
|
||||
{}
|
||||
|
||||
|
||||
|
||||
|
||||
void TopicPreviewer::setTopicData(const TopicData &data)
|
||||
{
|
||||
m_topicData = data;
|
||||
|
||||
if (m_topicData.state)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TopicPreviewer::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
|
||||
if (m_topicData.topicType == TopicType::Invalid || m_topicData.duration < 1 || event->buttons() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
m_topicData.state = true;
|
||||
QByteArray byteArray;
|
||||
QDataStream dataStream(&byteArray, QIODevice::WriteOnly);
|
||||
dataStream << m_topicData;
|
||||
m_topicData.state = false;
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(TopicData::mime, byteArray);
|
||||
QDrag *drag = new QDrag(this);
|
||||
drag->setDragCursor(QPixmap(), Qt::CopyAction);
|
||||
drag->setMimeData(mimeData);
|
||||
emit startDragMe();
|
||||
if (drag->exec(Qt::CopyAction) == Qt::CopyAction)
|
||||
emit deleteMe();
|
||||
emit stopDragMe();
|
||||
}
|
||||
|
||||
|
||||
void TopicPreviewer::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QWidget::paintEvent(event);
|
||||
|
||||
if (m_topicData.topicType == TopicType::Invalid)
|
||||
return;
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setClipping(true);
|
||||
painter.setClipRect(rect(), Qt::ReplaceClip);
|
||||
painter.setPen(isEnabled() ? Qt::black : Qt::lightGray);
|
||||
painter.setBrush(QBrush(topicTypeColor(m_topicData.topicType)));
|
||||
painter.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||
painter.drawText(rect().adjusted(3, 16, -1, -1), m_topicData.description);
|
||||
if (!isEnabled())
|
||||
{
|
||||
painter.setBrush(QBrush(QColor(255, 255, 255, 204)));
|
||||
painter.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "topic_editor_utils.h"
|
||||
|
||||
#include <TopicEditorBase/topiceditorbase_export.h>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace TopicEditorBase
|
||||
{
|
||||
|
||||
class TOPICEDITORBASE_EXPORT TopicPreviewer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TopicPreviewer(QWidget *parent = nullptr);
|
||||
~TopicPreviewer();
|
||||
|
||||
void setTopicData(const TopicData &data);
|
||||
TopicData topicData() const { return m_topicData; }
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
signals:
|
||||
void startDragMe();
|
||||
void stopDragMe();
|
||||
void deleteMe();
|
||||
|
||||
private:
|
||||
TopicData m_topicData;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user