Files
qt6-migration-pipeline/Lts/Common/LtsTimeline/track.h
T

264 lines
7.2 KiB
C++
Executable File

#pragma once
#include "item.h"
#include <LtsTimeline/ltstimeline_export.h>
#include <QObject>
#include <QSet>
#include <QVariant>
#include <memory>
namespace LtsTimeline
{
class Track;
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;
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);
[[deprecated("Use model's item(int) instead.")]] const Item &item(int id) const noexcept(false);
Item &previous(int id) noexcept(false);
Item &next(int id) noexcept(false);
const Item &copyItemAt(qint64 time) const noexcept(false);
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;
bool hasTracks() const { return !m_childrenTracks.empty(); }
int rowOfTrack(int id) const noexcept(false);
const Track &parentOf(int id) 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;
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;
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);
void removeItem(int itemId) noexcept(false);
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);
void addItemPtr(ItemPtr &&itemPtr);
static bool isItemBetween(const Item &item, qint64 start, qint64 end, bool strict, bool complete, qint64 minimumDuration = 0);
ItemPtrRefs _copyItems() const;
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));
}
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;
}
int m_id { -1 };
Tracks m_childrenTracks;
Items m_items;
int m_parentId { -1 };
bool m_hasInsertButton { false };
bool m_hasRemoveButton { false };
QSet<int> m_copyItemIds;
};
}