Continues migration with DDS, Common

This commit is contained in:
torsten committed 2026-07-17 12:41:42 +02:00
1 parent 9b15cee841
commit fa48db111e
668 files changed
+111841 -2

No files matched your search

+48
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 &amp; 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
View File
@@ -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));
}
}
}
+38
View File
@@ -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;
};
}