Major Changes:
- Merged latest Qt5 devel content from dlbo (292 files changed, 7 new dirs)
- Consolidated forward-declarations and include folders
- Removed unneeded modules per Niklas' repo check list
Build System Fixes:
- Fixed CMake VERSION_GREATER syntax in ParticipantManagement/CMakeLists.txt
- Added VLC packages (libvlc-dev, vlc-plugin-base) to docker_build.sh
- Added PostgreSQL dev packages (libpq-dev, postgresql-server-dev-all) to Dockerfile
- Fixed locale warnings (ANSI_X3.4-1968 → C.UTF-8)
- Fixed ArcGIS SDK path warnings when BUILD_ARCGIS=OFF
Code Generation Fixes:
- Fixed IDL enum collisions (PortType→CorePortType/DdsutPortType, PdmEventType)
- Fixed Grantlee template svc_translation.cpp.grantlee:
- Changed {{ idl_enum.name }}_def:: to {{ idl_enum.name }}::
- Fixed .underlying() calls for C++11 scoped enums (enum class)
- Removed generated files from repo (moc_*, *_dtc.h, *_ftc.h)
Validation:
- BUILD_RTI=ON: SUCCESS
- BUILD_RTI=OFF: SUCCESS
- C++17 standard maintained for RTI 7.7 compatibility
- Ubuntu 26.04 Docker environment verified
Remaining Warnings (expected):
- BgViewer, KDChart, KDReports, Poppler-Qt6 not found (optional features)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
335 lines
10 KiB
C++
335 lines
10 KiB
C++
/**
|
|
* @RDE_HEADER@
|
|
* widget in MVC pattern which manages the entire timeline to add on a layout or widget
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Mike Wille, SLSE, 2014-10-01
|
|
*/
|
|
|
|
#include "TimelineWidget.h"
|
|
#include "EventDelegate.h"
|
|
#include "ui_TimelineWidgetUi.h"
|
|
#include "AbstractTimelineModel.h"
|
|
#include "EventGraphic.h"
|
|
|
|
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
|
|
#include <QSize>
|
|
#include <QPoint>
|
|
#include <QRect>
|
|
#include <QDateTime>
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
namespace LtsTimelineClassic
|
|
{
|
|
|
|
TimelineWidget::TimelineWidget(QWidget *parent) // model cannot be set here, as qt has to create this Widget and does not know how to handle more parameters as the parent parameter
|
|
: QWidget(parent)
|
|
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("Timeline.Widget"))
|
|
, m_timelineUi(new Ui::Timeline)
|
|
, m_min(0)
|
|
, m_max(1)
|
|
, m_sbPos(0)
|
|
, m_zoomFactor(1) // 100%
|
|
, m_headerView(new TimelineHeaderView)
|
|
, m_model(nullptr)
|
|
{
|
|
m_timelineUi->setupUi(this);
|
|
m_timelineUi->view->setHeader(m_headerView);
|
|
m_headerView->setMinimumSectionSize(150);
|
|
|
|
m_timelineUi->scrollbar->setMouseTracking(true);
|
|
connect(m_timelineUi->scrollbar, &QScrollBar::sliderReleased, this, &TimelineWidget::scrollBarFilter2);
|
|
connect(m_timelineUi->scrollbar, &QScrollBar::actionTriggered, this, &TimelineWidget::scrollBarFilter1);
|
|
|
|
connect(m_headerView, &QHeaderView::sectionResized, m_timelineUi->indicator, &TimelineIndicator::slotSectionResized);
|
|
connect(m_headerView, &QHeaderView::sectionResized, this, &TimelineWidget::slotSectionResized);
|
|
connect(m_timelineUi->view, &TimelineView::signalZoom, m_timelineUi->indicator, &TimelineIndicator::slotZoom);
|
|
connect(m_timelineUi->view, &TimelineView::signalUnzoom, m_timelineUi->indicator, &TimelineIndicator::slotUnzoom);
|
|
|
|
connect(m_timelineUi->view, &TimelineView::signalZoom, this, &TimelineWidget::signalZoomChanged);
|
|
connect(m_timelineUi->view, &TimelineView::signalUnzoom, this, &TimelineWidget::signalZoomChanged);
|
|
|
|
connect(m_timelineUi->indicator, &TimelineIndicator::signalZoomChanged, this, &TimelineWidget::signalZoomChanged);
|
|
connect(m_timelineUi->indicator, &TimelineIndicator::signalSetZoomFactor, this, &TimelineWidget::slotSetZoomFactor);
|
|
|
|
connect(m_timelineUi->view, &TimelineView::signalEventAction,
|
|
this, &TimelineWidget::signalEventAction); // use old connect style because grrrr, EventGraphic !
|
|
|
|
connect(m_timelineUi->cbDrawCache, &QCheckBox::toggled,
|
|
this, [this](bool toggled)
|
|
{
|
|
m_timelineUi->view->setDrawCache(toggled);
|
|
update(); // schedule repaint
|
|
});
|
|
|
|
connect(m_timelineUi->cbArm, &QCheckBox::toggled,
|
|
this, &TimelineWidget::signalArm);
|
|
connect(m_timelineUi->updateTimeline, &QPushButton::clicked,
|
|
this, &TimelineWidget::slotUpdateTimeline);
|
|
}
|
|
|
|
|
|
TimelineWidget::~TimelineWidget()
|
|
{
|
|
delete m_timelineUi;
|
|
}
|
|
|
|
|
|
void TimelineWidget::setLiveTime(qint64 time)
|
|
{
|
|
m_headerView->setLiveTime(time);
|
|
|
|
EventDelegate *ed = qobject_cast<EventDelegate *>(m_timelineUi->view->itemDelegate());
|
|
if (ed == nullptr)
|
|
{
|
|
qWarning() << "TimelineWidget::setLiveTime: ed == nullptr";
|
|
return;
|
|
}
|
|
|
|
ed->setLiveTime(time);
|
|
}
|
|
|
|
|
|
void TimelineWidget::hideDebugWidget()
|
|
{
|
|
m_timelineUi->debugWidget->hide();
|
|
m_timelineUi->lbMinMax->hide();
|
|
}
|
|
|
|
void TimelineWidget::knownRangesChanged(const QVector<Range> &newRanges)
|
|
{
|
|
EventDelegate *ed = qobject_cast<EventDelegate *>(m_timelineUi->view->itemDelegate());
|
|
if (ed == nullptr)
|
|
{
|
|
WARNING_LOG(m_logger) << "ed == nullptr";
|
|
return;
|
|
}
|
|
|
|
m_timelineUi->view->setKnownRanges(newRanges);
|
|
ed->setKnownRanges(newRanges);
|
|
m_timelineUi->view->refreshData(); // calls update in both views (itself & header)
|
|
}
|
|
|
|
|
|
void TimelineWidget::setMaxPos()
|
|
{
|
|
m_timelineUi->scrollbar->setValue(m_timelineUi->scrollbar->maximum());
|
|
}
|
|
|
|
|
|
int TimelineWidget::getMaxPos() const
|
|
{
|
|
return m_timelineUi->scrollbar->maximum();
|
|
}
|
|
|
|
|
|
int TimelineWidget::getPos() const
|
|
{
|
|
return m_timelineUi->scrollbar->value();
|
|
}
|
|
|
|
|
|
void TimelineWidget::setPos(qint64 pos)
|
|
{
|
|
m_timelineUi->scrollbar->setValue(pos / 1000); // in sec
|
|
}
|
|
|
|
|
|
void TimelineWidget::setPositionMarkerTime(const qint64 time)
|
|
{
|
|
m_timelineUi->view->slotSetPosMarkTime(time);
|
|
}
|
|
|
|
|
|
void TimelineWidget::slotUpdateTimeline() // called when either the scrollbar, zoom level or section is moved (refetch events!)
|
|
{
|
|
qint64 min = m_model->lowestPositionedItem();
|
|
qint64 max = m_model->highestPositionedItem();
|
|
|
|
if (m_timelineUi->cbMinMax->isChecked())
|
|
{
|
|
QString minmax(QStringLiteral("%1 (%2) - %3 (%4)")
|
|
.arg(QDateTime::fromMSecsSinceEpoch(min).toString())
|
|
.arg(min)
|
|
.arg(QDateTime::fromMSecsSinceEpoch(max).toString())
|
|
.arg(max));
|
|
m_timelineUi->lbMinMax->setText(minmax);
|
|
}
|
|
|
|
setTimelineRange(min, max);
|
|
emit signalRangeChanged();
|
|
}
|
|
|
|
|
|
void TimelineWidget::setTimelineModel(AbstractTimelineModel *model)
|
|
{
|
|
m_model = model;
|
|
|
|
connect(m_model, &AbstractTimelineModel::dataChanged,
|
|
this, &TimelineWidget::slotRefreshData /* no need to recalc all values, just the data changed, just render them */);
|
|
|
|
// redirect signalPlayback from model to widget (signal must now be connected to desired class from extern)
|
|
|
|
m_timelineUi->view->setTimelineModel(m_model);
|
|
|
|
// AddLine & ResetLineList
|
|
connect(m_timelineUi->indicator, &TimelineIndicator::signalAddLine,
|
|
m_timelineUi->view, &TimelineView::slotAddLine);
|
|
connect(m_timelineUi->indicator, &TimelineIndicator::signalResetLineList,
|
|
m_timelineUi->view, &TimelineView::slotResetLineList);
|
|
|
|
EventDelegate *ed = qobject_cast<EventDelegate *>(m_timelineUi->view->itemDelegate());
|
|
if (ed != nullptr)
|
|
{
|
|
connect(m_timelineUi->indicator, &TimelineIndicator::signalAddLine,
|
|
ed, &EventDelegate::slotAddLine);
|
|
connect(m_timelineUi->indicator, &TimelineIndicator::signalResetLineList,
|
|
ed, &EventDelegate::slotResetLineList);
|
|
}
|
|
|
|
m_timelineUi->view->expandToDepth(1);
|
|
|
|
m_headerView->resizeSection(0, m_headerView->minimumSectionSize()); // widget needs help to set minimum section size
|
|
m_headerView->resizeSection(1, m_headerView->minimumSectionSize()); // s.a.a
|
|
|
|
slotSetZoomFactor(m_timelineUi->indicator->zoomFactorPoints()); // initial z00m
|
|
}
|
|
|
|
|
|
qint64 TimelineWidget::getRangeMinimum() const
|
|
{
|
|
return EventTools::getAdjustedMin();
|
|
}
|
|
|
|
|
|
qint64 TimelineWidget::getRangeMaximum() const
|
|
{
|
|
return EventTools::getAdjustedMax();
|
|
}
|
|
|
|
|
|
void TimelineWidget::setTimelineRange(qint64 min, qint64 max) // also sets scrollbar range
|
|
{
|
|
m_min = min;
|
|
m_max = max;
|
|
|
|
if (m_min > 0 && m_max > 2) // only set scrollbar values if there are events
|
|
{
|
|
m_sbPos = EventTools::fromSecondsToMsecs(m_timelineUi->scrollbar->sliderPosition());
|
|
|
|
if (m_max <= m_min)
|
|
{
|
|
if (m_min > (10 * 60))
|
|
m_min -= (10 * 60); // be at least 10 minutes long (from the start until now)
|
|
}
|
|
else
|
|
{
|
|
qint64 diff = m_max - m_min;
|
|
if (diff < (10 * 60))
|
|
if (m_min > (10 * 60))
|
|
m_min -= (10 * 60); // be at least 10 minutes long (from the start until now) if the difference between min & max is lower than 10 minutes
|
|
}
|
|
|
|
// sadly we cannot use getBlockSizeTime here, as setValues would invalidate everything calculated by getBlockSizeTime, because it uses values calculated by setValues, which gets called next..
|
|
// else
|
|
// m_max = m_max - EventTools::s_diff + EventTools::getBlockSizeTime(0); // add one event width to the end, so that it is not cut off when live
|
|
|
|
|
|
// NOTE: every calculation done before the call in the next line invalidates every value calculated by EventTools !!
|
|
EventTools::setValues(m_min, m_max, m_sbPos, m_zoomFactor);
|
|
|
|
|
|
|
|
//qWarning() << "set scrollbar range" << m_min << m_max;
|
|
m_timelineUi->scrollbar->setRange(EventTools::fromMsecsToSeconds(EventTools::getTimelineMin()), EventTools::fromMsecsToSeconds(EventTools::getTimelineMax()));
|
|
|
|
if (m_sbPos < m_min) // sbPos can still be smaller than min
|
|
{
|
|
m_sbPos = m_min;
|
|
//qWarning() << "set slider pos" << m_sbPos;
|
|
m_timelineUi->scrollbar->setSliderPosition(EventTools::fromMsecsToSeconds(m_sbPos));
|
|
}
|
|
|
|
//qWarning() << "min" << EventTools::fromMsecsToSeconds(m_min) << "max" << EventTools::fromMsecsToSeconds(m_max) << "pagestep" << pagestep;
|
|
|
|
int pagestep = EventTools::fromMsecsToSeconds(EventTools::s_diff);
|
|
if (pagestep < 0)
|
|
pagestep = 1;
|
|
|
|
//qWarning() << "set scrollbar page step" << pagestep;
|
|
m_timelineUi->scrollbar->setPageStep(pagestep);
|
|
|
|
/*
|
|
qWarning() << "scrollbar: min" << m_timelineUi->scrollbar->minimum()
|
|
<< "max" << m_timelineUi->scrollbar->maximum()
|
|
<< "pagestep" << m_timelineUi->scrollbar->pageStep()
|
|
<< "value" << m_timelineUi->scrollbar->value();
|
|
*/
|
|
|
|
m_timelineUi->bsz->setText(QString::number(EventTools::getBlockSizeTime()));
|
|
}
|
|
|
|
|
|
refreshData();
|
|
}
|
|
|
|
|
|
void TimelineWidget::slotRefreshData()
|
|
{
|
|
refreshData();
|
|
}
|
|
|
|
|
|
void TimelineWidget::refreshData()
|
|
{
|
|
m_headerView->refreshData(); // calls update
|
|
m_timelineUi->indicator->refreshData(); // ONLY calls update
|
|
m_timelineUi->view->refreshData(); // calls update in both views (itself & header)
|
|
}
|
|
|
|
|
|
void TimelineWidget::slotSetZoomFactor(qint64 zoomFactor)
|
|
{
|
|
m_zoomFactor = zoomFactor;
|
|
slotUpdateTimeline(); // reuse method to set new pagestep of scrollbar FIMXE: method "refreshScrollBar" to do this?
|
|
}
|
|
|
|
|
|
void TimelineWidget::scrollBarFilter1(int )
|
|
{
|
|
scrollBarFilter2();
|
|
}
|
|
|
|
|
|
void TimelineWidget::scrollBarFilter2()
|
|
{
|
|
slotUpdateTimeline(); // updates all (views) containers
|
|
}
|
|
|
|
|
|
void TimelineWidget::slotSectionResized(int logicalIndex, int oldSize, int newSize)
|
|
{
|
|
(void)oldSize;
|
|
|
|
if (logicalIndex == 1) // event section [should always be called, even if col0 was resized, as the last column is always strechted, there would be no space for col0 to take that was not occupied by col1]
|
|
{
|
|
int viewScrollbarWidth = m_timelineUi->view->verticalScrollBar()->width();
|
|
m_timelineUi->scrollbar->setMinimumHeight(viewScrollbarWidth); // set scrollbar to same size as scrollbar in view
|
|
m_timelineUi->scrollbar->setMaximumHeight(viewScrollbarWidth); // set scrollbar to same size as scrollbar in view
|
|
|
|
m_timelineUi->scrollbar->setMaximumWidth(newSize);
|
|
m_timelineUi->scrollbar->setMinimumWidth(newSize);
|
|
|
|
EventTools::setSection(m_headerView->sectionPosition(1),
|
|
newSize /* as it was not yet set in m_headerView->sectionSize(1) ! */);
|
|
}
|
|
|
|
slotUpdateTimeline();
|
|
}
|
|
|
|
} // namespace LtsTimelineClassic
|