Files
qt-migration-legatus/qt5-before/dlbo/Lts/Common/LtsTimeline/track.h
T
torstenandCopilot 7173785915 Qt6 Migration: Complete migration with DDS/RTI support and build validation
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>
2026-09-15 18:20:26 +00:00

270 lines
8.7 KiB
C++

/**
* @RDE_HEADER@
* manages & represents a row in view and contains children Tracks & events
* $Id: Track.h 51102 2020-05-08 13:42:17Z wille_m $
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/hotline/Lts/Common/LtsEventTimeline/Track.h $
* $Author: wille_m $
* Created by Mike Wille, SLSE, 2014-10-01
*/
#pragma once
#include "item.h"
#include <LtsTimeline/ltstimeline_export.h>
#include <QObject>
#include <QSet>
#include <QVariant>
#include <memory>
namespace LtsTimeline
{
class Track;
//class ModelTrack;
class TimelineModel;
typedef std::unique_ptr<Track> TrackPtr;
typedef std::vector<TrackPtr> Tracks;
typedef std::reference_wrapper<TrackPtr> TrackPtrRef;
typedef std::vector<TrackPtrRef> TrackPtrRefs;
class LTSTIMELINE_EXPORT Track
{
public:
Track(const QString &text = {})
: m_text(text)
{}
Track(const QString &text, int specialTrackType)
: m_text(text)
, m_userData(specialTrackType)
{}
Track(const Track &) = delete;
Track &operator=(const Track &) = delete;
Track(Track &&t) noexcept = default; // why-ever my compiler doesn't auto-create the move ctor
virtual ~Track() = default;
[[deprecated("Use model's track(int) instead.")]] const Track &track(int id) const noexcept(false);
[[deprecated("Use model's track(int) instead.")]] Track &track(int id) noexcept(false);
[[deprecated("Use model's item(int) instead.")]] Item &item(int id) noexcept(false); // recursive!
[[deprecated("Use model's item(int) instead.")]] const Item &item(int id) const noexcept(false); // recursive!
Item &previous(int id) noexcept(false);
Item &next(int id) noexcept(false);
//bool itemAt(qint64 time, Item &item_out) noexcept(false);
const Item &copyItemAt(qint64 time) const noexcept(false); // copy item can't be modified!
Item &itemAt(qint64 time) noexcept(false);
const Item &itemAt(qint64 time) const noexcept(false);
Track &trackAt(int index) noexcept(false);
const Track &trackAt(int index) const noexcept(false);
bool hasTrack(int id, bool recursive = false) const; // non-recursive, direct!
bool hasTracks() const { return !m_childrenTracks.empty(); }
int rowOfTrack(int id) const noexcept(false);
const Track &parentOf(int id) const noexcept(false);
//int trackIdOfRow(int row) const noexcept(false);
//const Track &trackOfRow(const int row) const noexcept(false);
const QSet<int> &copyItemIds() const { return m_copyItemIds; }
void clearCopyItemIds() { m_copyItemIds.clear(); }
void addCopyItemIds(const QSet<int> &ids);
void addCopyItemId(int id);
bool hasItems() const { return !m_items.empty(); }
bool hasCopyItems() const { return !m_copyItemIds.empty(); }
int itemCount() const { return m_items.size(); }
Items &items() { return m_items; }
const Items &items() const { return m_items; }
int trackCount() const { return m_childrenTracks.size(); }
Tracks &tracks() { return m_childrenTracks; }
const Tracks &tracks() const { return m_childrenTracks; }
QVector<int> itemIds(bool recursive = false, bool sorted = false) const;
const QVector<int> itemIdsBetween(qint64 start, qint64 end, bool strict = false, bool complete = false, bool recursive = false, bool sorted = false, qint64 minimumDuration = 0) const;
[[deprecated]] const QVector<int> copyItemIdsBetween(qint64 start, qint64 end, bool strict = false, bool complete = false, bool recursive = false, bool sorted = false, qint64 minimumDuration = 0) const; // non-recursive! because copy items will always be also on the highest track, because of the sum channeling
bool isItemsBetween(qint64 start, qint64 end, const QVector<int> &ignoreIds, bool strict = false, bool complete = false, bool recursive = false, qint64 minimumDuration = 0) const;
bool isItemsBetween(qint64 start, qint64 end, int ignoreId, bool strict = false, bool complete = false, bool recursive = false, qint64 minimumDuration = 0) const;
//bool hasTrack(int id) const;// { return m_tracks.contains(id); } NOTE: non-recursive
//void addItem(Item &item);
int id() const { return m_id; }
virtual const QString text() const { return m_text; }
int parent() const { return m_parentId; }
int parentId() const { return m_parentId; }
void printTrackIds(bool withItems = false, int level = 0) const;
void removeCopyItem(int itemId) noexcept(false); // recursive! as a copy item is on many child tracks, because of the sum channeling
void removeItem(int itemId) noexcept(false); // non-recursive!
ItemPtr takeItem(int itemId) noexcept(false);
QVariant userData() const { return m_userData; }
void setUserData(const QVariant &data) { m_userData = data; }
inline static void sort(Items &items)
{
std::sort(items.begin(), items.end(), [](const ItemPtr &itemA, const ItemPtr &itemB)
{
return itemA->startTime() < itemB->startTime();
});
}
inline static void sort(ItemPtrNCVRefs &items)
{
std::sort(items.begin(), items.end(), [](const ItemPtrNCVRef &itemA, const ItemPtrNCVRef &itemB)
{
return itemA.get()->startTime() < itemB.get()->startTime();
});
}
inline static void sort(ItemPtrRefs &items)
{
std::sort(items.begin(), items.end(), [](const ItemPtrRef &itemA, const ItemPtrRef &itemB)
{
return itemA.get()->startTime() < itemB.get()->startTime();
});
}
bool hasInsertButton() const { return m_hasInsertButton; }
void setInsertButton(bool hasButton) { m_hasInsertButton = hasButton; }
bool hasRemoveButton() const { return m_hasRemoveButton; }
void setRemoveButton(bool hasButton) { m_hasRemoveButton = hasButton; }
protected:
QString m_text;
QVariant m_userData;
private:
void removeTrack(int trackId) noexcept(false); // non-recursive!
void addItemPtr(ItemPtr &&itemPtr);
//const QVector<int> _itemIds(bool recursive) const; // doesn't sort, as only the last callee should sort the final result
static bool isItemBetween(const Item &item, qint64 start, qint64 end, bool strict, bool complete, qint64 minimumDuration = 0);
ItemPtrRefs _copyItems() const; // private, non-recursive, sorted
ItemPtrRefs _items(bool recursive) const;
ItemPtrNCVRefs _itemsNCV(bool recursive);
ItemPtrNCVRef _itemNCV(int id) noexcept(false);
ItemPtrRef _item(int id) const noexcept(false);
const QVector<int> _itemIds(bool recursive) const;
public:
void clearItems() { m_items.clear(); }
private:
friend class TimelineModel;
void sort()
{
sort(m_items);
}
template <typename TrackClass>
Track *addTrack(TrackClass &&trackClass)
{
TrackClass _trackClass = std::move(trackClass);
m_childrenTracks.push_back(std::move(std::move(std::make_unique<TrackClass>(std::move(_trackClass)))));
return m_childrenTracks.back().get();
}
template <typename TrackClass>
[[deprecated("Use model's track(...) and call addTrack(TrackClass) directly on that track.")]]
Track *addTrack(int parentTrackId, TrackClass &&trackClass) noexcept(false)
{
if (m_id == parentTrackId)
return addTrack<TrackClass>(std::move(trackClass));
return track(parentTrackId).addTrack(std::move(trackClass)); // throws!
}
template <typename ItemClass>
Item *addItem(ItemClass &&itemClass)
{
ItemClass _itemClass(std::move(itemClass));
auto it = m_items.insert(std::upper_bound(m_items.begin(), m_items.end(), _itemClass.startTime(),
[](qint64 startTime, const ItemPtr &other)
{
return (other->startTime() > startTime);
}), std::move(std::make_unique<ItemClass>(std::move(_itemClass))));
return it->get();
}
Item *addItem(ItemPtr &&itemPtr)
{
auto it = m_items.insert(std::upper_bound(m_items.begin(), m_items.end(), itemPtr->startTime(),
[](qint64 startTime, const ItemPtr &other)
{
return (other->startTime() > startTime);
}), std::move(itemPtr));
return it->get();
}
template <typename ItemContainer>
[[deprecated]]
QVector<int> transformItemPtrsToIds(const ItemContainer &itemContainer) const
{
QVector<int> ids;
std::transform(itemContainer.cbegin(), itemContainer.cend(), std::back_inserter(ids),
[](const ItemPtr &itemPtr) -> int
{
return itemPtr->id();
});
return ids;
}
// const QVector<std::reference_wrapper<Track>> _tracks()
// {
// QVector<std::reference_wrapper<Track>> x;
// for (const TrackPtr &y : qAsConst(m_childrenTracks))
// {
// x += (*y);
// }
// return x;
// }
int m_id { -1 };
Tracks m_childrenTracks;
Items m_items;
int m_parentId { -1 };
bool m_hasInsertButton { false };
bool m_hasRemoveButton { false };
//#warning // TODO: move into specialized item class!!!
QSet<int> m_copyItemIds; // items that are on children tracks TODO: QVector should be enough and faster
};
} // namespace LtsTimeline
//