Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Plugins/AudioVideoManagement/Gui/AVMenuEdit/interval_model.cpp
T

175 lines
3.9 KiB
C++
Executable File

#include "interval_model.h"
#include <AudioVideoManagement/av_helper.h>
#include <QVariant>
#include <QString>
#include <QColor>
#include <QModelIndex>
#include <QDateTime>
namespace AudioVideoManagement
{
IntervalModel::IntervalModel()
: LtsAbstractTableModel({tr("Start"), tr("End"), tr("Duration [s]")}, nullptr)
{
}
QString IntervalModel::dateTimeToStringy(const QDateTime &dt) const
{
return QDateTime::fromMSecsSinceEpoch(dt.toMSecsSinceEpoch() + (m_timezoneHoursOffset * 3600 * 1000)).toString(QStringLiteral("dd.MM.yy HH:mm:ss.zzz"));
}
QString IntervalModel::msecsSinceEpochToStringy(qint64 msecs) const
{
return dateTimeToStringy(QDateTime::fromMSecsSinceEpoch(msecs));
}
void IntervalModel::setTimezoneHoursOffset(int timezoneHoursOffset)
{
m_timezoneHoursOffset = timezoneHoursOffset;
emit dataChanged({}, {}, {Qt::DisplayRole});
}
QVariant IntervalModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
const AvaTimelinePart &interval = m_vecData.at(index.row());
switch (role)
{
case Qt::DisplayRole:
{
switch (index.column())
{
case Start:
return msecsSinceEpochToStringy(toMSecSinceEpoch(interval.first));
case End:
return msecsSinceEpochToStringy(toMSecSinceEpoch(interval.second));
case Duration:
{
qint64 duration = (toMSecSinceEpoch(interval.second) - toMSecSinceEpoch(interval.first));
qint64 secs = duration / 1000;
qint64 msecs = (duration % 1000);
return QStringLiteral("%1.%2").arg(secs).arg(msecs, 3, 10, QLatin1Char('0'));
}
}
Q_ASSERT(false);
break;
}
case Qt::BackgroundRole:
{
if (m_currentInterval == (2 * index.row()))
return QVariant(QColor(Qt::green));
return QVariant();
}
default:
break;
}
return QVariant();
}
void IntervalModel::reset()
{
m_currentPos.reset();
m_currentInterval.reset();
setData({});
emit currentIntervalChanged(false, false, QModelIndex());
}
void IntervalModel::setCurrentPosition(AvaTimePoint pos, bool forceSignal)
{
if (m_vecData.isEmpty())
return;
HalfIndex newInterval = intervalForPos(pos);
bool intervalChanged = newInterval != m_currentInterval;
m_currentPos = pos;
m_currentInterval = newInterval;
if (!intervalChanged && !forceSignal)
return;
bool hasPrev = newInterval >= 0;
bool hasNext = newInterval < 2 * (m_vecData.size() - 1);
QModelIndex rowIndex;
if (newInterval % 2 == 0)
rowIndex = index(newInterval / 2, 0);
emit currentIntervalChanged(hasPrev, hasNext, rowIndex);
QModelIndex topLeft = index(0, 0);
QModelIndex bottomRight = index(rowCount() - 1, columnCount() - 1);
emit dataChanged(topLeft, bottomRight, {Qt::BackgroundRole});
}
const AvaTimelinePart &IntervalModel::previousInterval() const
{
Q_ASSERT(m_currentInterval);
Q_ASSERT(*m_currentInterval != -1);
bool withinInterval = *m_currentInterval % 2 == 0;
int intervalIndex = *m_currentInterval / 2;
if (!withinInterval)
return m_vecData.at(intervalIndex);
if (intervalIndex == 0)
return m_vecData.at(intervalIndex);
const AvaTimelinePart &interval = m_vecData.at(intervalIndex);
if (*m_currentPos > interval.first + std::chrono::seconds(2))
return interval;
else
return m_vecData.at(intervalIndex - 1);
}
const AvaTimelinePart &IntervalModel::nextInterval() const
{
Q_ASSERT(m_currentInterval);
int intervalIndex = (*m_currentInterval + 2) / 2;
return m_vecData.at(intervalIndex);
}
IntervalModel::HalfIndex IntervalModel::intervalForPos(AvaTimePoint pos) const
{
Q_ASSERT(!m_vecData.isEmpty());
for (int i = 0; i < m_vecData.size(); ++i)
{
const AvaTimelinePart &interval = m_vecData.at(i);
if (pos < interval.first)
{
return 2 * i - 1;
}
if (pos >= interval.first && pos <= interval.second)
{
return 2 * i;
}
}
return 2 * m_vecData.size() - 1;
}
}