477 lines
13 KiB
C++
477 lines
13 KiB
C++
#include "track_widget.h"
|
|
|
|
#include "filter_background_widget.h"
|
|
#include "filter_track_widget.h"
|
|
#include "tools.h"
|
|
#include "track_content_widget.h"
|
|
#include "track_entry.h"
|
|
#include "ui_track_widget.h"
|
|
|
|
#include <QtGui/QBrush>
|
|
#include <QtGui/QColor>
|
|
#include <QtCore/QDebug>
|
|
#include <QtCore/QJsonArray>
|
|
#include <QtCore/QJsonObject>
|
|
#include <QtCore/QJsonValue>
|
|
#include <QtGui/QPainter>
|
|
#include <QtGui/QPen>
|
|
#include <utility>
|
|
|
|
namespace LtsScriptTimeline
|
|
{
|
|
TrackWidget::TrackWidget(int baseWidth, bool readonly, Tools* tools, bool filtersAllowed, QWidget* parent)
|
|
: QWidget(parent), ui(new Ui::TrackWidget), m_baseWidth(baseWidth), m_readonly(readonly), m_tools(tools)
|
|
{
|
|
Q_ASSERT(m_tools != nullptr);
|
|
|
|
ui->setupUi(this);
|
|
ui->mainTrack->setTrackWidget(this);
|
|
ui->mainTrack->setTools(tools);
|
|
|
|
ui->chkSelect->hide();
|
|
|
|
ui->filtersWidget->hide();
|
|
ui->leName->hide();
|
|
ui->pbApply->hide();
|
|
ui->pbCancel->hide();
|
|
|
|
ui->pbEditName->hide();
|
|
|
|
if (!filtersAllowed)
|
|
ui->pbExpand->hide();
|
|
|
|
ui->pbAddFilter->hide();
|
|
|
|
setBaseWidth(baseWidth);
|
|
setReadonly(readonly);
|
|
|
|
connect(ui->mainTrack, &TrackContentWidget::signalUnselectAll, this, &TrackWidget::signalUnselectAll);
|
|
connect(ui->mainTrack, &TrackContentWidget::signalTrackEntrySelectionChanged, this,
|
|
&TrackWidget::signalTrackEntrySelectionChanged);
|
|
connect(ui->mainTrack, &TrackContentWidget::signalChangesMade, this, &TrackWidget::signalChangesMade);
|
|
connect(ui->mainTrack, &TrackContentWidget::signalChangesMade, this, &TrackWidget::slotMainChangesMade);
|
|
connect(ui->mainTrack, &TrackContentWidget::signalTrackEntryAdded, this, &TrackWidget::slotTrackEntryAdded);
|
|
connect(ui->mainTrack, &TrackContentWidget::signalTrackEntryDeleted, this, &TrackWidget::slotTrackEntryDeleted);
|
|
connect(ui->mainTrack, &TrackContentWidget::signalEditEntry, this, &TrackWidget::signalEditEntry);
|
|
|
|
connect(ui->chkSelect, &QCheckBox::checkStateChanged, this, &TrackWidget::signalSelectTrack);
|
|
connect(ui->pbExpand, &QPushButton::clicked, this, &TrackWidget::slotExpand);
|
|
connect(ui->pbAddFilter, &QPushButton::clicked, this, &TrackWidget::slotAddFilter);
|
|
}
|
|
|
|
TrackWidget::~TrackWidget()
|
|
{
|
|
m_filterLines.clear();
|
|
delete ui;
|
|
}
|
|
|
|
void TrackWidget::setReadonly(bool readonly)
|
|
{
|
|
m_readonly = readonly;
|
|
ui->mainTrack->setReadonly(readonly);
|
|
|
|
if (readonly)
|
|
ui->pbAddFilter->hide();
|
|
else if (ui->filtersWidget->isVisible())
|
|
ui->pbAddFilter->show();
|
|
|
|
for (auto i3 = m_filterLines.begin(); i3 != m_filterLines.end(); ++i3)
|
|
{
|
|
FilterTrackWidget* ftw = *i3;
|
|
ftw->setReadonly(readonly);
|
|
}
|
|
}
|
|
|
|
void TrackWidget::setScriptTimeline(ScriptTimeline* scriptTimeline)
|
|
{
|
|
m_scriptTimeline = scriptTimeline;
|
|
ui->mainTrack->setScriptTimeline(m_scriptTimeline);
|
|
}
|
|
|
|
void TrackWidget::keyPressEvent(QKeyEvent* event)
|
|
{
|
|
getTrackContentWidget()->keyPressEvent(event);
|
|
}
|
|
|
|
QVector<TrackEntry*> TrackWidget::getSelectedFilterEntries() const
|
|
{
|
|
QVector<TrackEntry*> result;
|
|
const QVector<FilterTrackWidget*>& ftws = filterLines();
|
|
|
|
for (const FilterTrackWidget* ftw : std::as_const(ftws))
|
|
{
|
|
const FilterBackgroundWidget* fbw = ftw->fbw();
|
|
const QMap<int, TrackContentWidget*>& fcws = fbw->filterContentWidgets();
|
|
|
|
for (auto i = fcws.constBegin(); i != fcws.constEnd(); ++i)
|
|
{
|
|
TrackContentWidget* tcw = i.value();
|
|
result += tcw->getSelectedEntries();
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
const QVector<TrackEntry*>& TrackWidget::getSelectedEntries() const
|
|
{
|
|
return ui->mainTrack->getSelectedEntries();
|
|
}
|
|
|
|
void TrackWidget::slotAddFilter()
|
|
{
|
|
FilterTrackWidget* ftw = new FilterTrackWidget(m_baseWidth, m_readonly);
|
|
ftw->setTrackWidget(this);
|
|
ftw->setTools(m_tools);
|
|
ftw->setScriptTimeline(m_scriptTimeline);
|
|
ui->filtersWidget->layout()->addWidget(ftw);
|
|
m_filterLines.append(ftw);
|
|
|
|
connect(ftw, &FilterTrackWidget::signalChangesMade, this, &TrackWidget::signalChangesMade);
|
|
|
|
connect(ftw, &FilterTrackWidget::signalUnselectAll, this, &TrackWidget::signalUnselectAll);
|
|
|
|
connect(ftw, &FilterTrackWidget::signalTrackEntrySelectionChanged, this,
|
|
&TrackWidget::signalTrackEntrySelectionChanged);
|
|
|
|
connect(ftw, &FilterTrackWidget::signalEditEntry, this, &TrackWidget::signalEditEntry);
|
|
|
|
connect(ftw, &FilterTrackWidget::signalTrackEntryDeleted, this, &TrackWidget::signalTrackEntryDeleted);
|
|
|
|
connect(ftw, &FilterTrackWidget::signalDeleteMe, this, [this]() {
|
|
m_filterLines.removeAll(qobject_cast<FilterTrackWidget*>(sender()));
|
|
sender()->deleteLater();
|
|
emit signalChangesMade();
|
|
});
|
|
|
|
emit signalChangesMade();
|
|
slotMainChangesMade();
|
|
}
|
|
|
|
void TrackWidget::slotMainChangesMade()
|
|
{
|
|
const QVector<TrackEntry*> trackEntries = ui->mainTrack->getTrackEntries();
|
|
|
|
for (auto i1 = trackEntries.constBegin(); i1 != trackEntries.constEnd(); ++i1)
|
|
{
|
|
const TrackEntry* te = *i1;
|
|
|
|
for (auto i3 = m_filterLines.begin(); i3 != m_filterLines.end(); ++i3)
|
|
{
|
|
FilterTrackWidget* ftw = *i3;
|
|
ftw->fbw()->adjustFilterContentWidgets(te);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TrackWidget::slotTrackEntryAdded(TrackEntry* te)
|
|
{
|
|
|
|
for (FilterTrackWidget* ftw : std::as_const(m_filterLines))
|
|
ftw->fbw()->trackEntryAdded(te);
|
|
|
|
emit signalTrackEntryAdded(te);
|
|
}
|
|
|
|
void TrackWidget::slotTrackEntryDeleted(const int topicId)
|
|
{
|
|
|
|
for (FilterTrackWidget* ftw : std::as_const(m_filterLines))
|
|
ftw->fbw()->trackEntryDeleted(topicId);
|
|
|
|
emit signalTrackEntryDeleted(topicId);
|
|
}
|
|
|
|
void TrackWidget::slotExpand()
|
|
{
|
|
if (ui->filtersWidget->isVisible())
|
|
{
|
|
ui->pbExpand->setText(tr("More"));
|
|
ui->pbAddFilter->hide();
|
|
ui->filtersWidget->hide();
|
|
}
|
|
else
|
|
{
|
|
ui->pbExpand->setText(tr("Less"));
|
|
|
|
if (!m_readonly)
|
|
ui->pbAddFilter->show();
|
|
|
|
ui->filtersWidget->show();
|
|
slotMainChangesMade();
|
|
}
|
|
}
|
|
|
|
void TrackWidget::selectEntry(int topicId)
|
|
{
|
|
ui->mainTrack->selectEntry(topicId);
|
|
}
|
|
|
|
int TrackWidget::getParentTopicIdOfFilter(const TrackEntry* te) const
|
|
{
|
|
|
|
for (const FilterTrackWidget* ftw : m_filterLines)
|
|
{
|
|
const FilterBackgroundWidget* fbw = ftw->fbw();
|
|
const QMap<int, TrackContentWidget*>& filterContentWidgets = fbw->filterContentWidgets();
|
|
|
|
for (auto i = filterContentWidgets.constBegin(); i != filterContentWidgets.constEnd(); ++i)
|
|
{
|
|
int parentTopicId = i.key();
|
|
const TrackContentWidget* datWidget = i.value();
|
|
const QVector<TrackEntry*>& filterEntries = datWidget->getTrackEntries();
|
|
|
|
for (const TrackEntry* filterTE : filterEntries)
|
|
{
|
|
if (filterTE == te)
|
|
return parentTopicId;
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
QVector<TrackEntry*> TrackWidget::getTrackEntriesWithFilters(bool selectedEntriesOnly) const
|
|
{
|
|
QVector<TrackEntry*> result;
|
|
const QVector<TrackEntry*> trackEntryList = ui->mainTrack->getTrackEntries();
|
|
|
|
for (TrackEntry* te : trackEntryList)
|
|
{
|
|
if (selectedEntriesOnly && !ui->mainTrack->getSelectedEntries().contains(te))
|
|
continue;
|
|
|
|
result += te;
|
|
|
|
QJsonArray jsonFilterLines;
|
|
|
|
for (const FilterTrackWidget* ftw : std::as_const(m_filterLines))
|
|
{
|
|
const FilterBackgroundWidget* fbw = ftw->fbw();
|
|
const QMap<int, TrackContentWidget*>& filterContentWidgets = fbw->filterContentWidgets();
|
|
|
|
const TrackContentWidget* datWidget = filterContentWidgets.value(te->m_topicId);
|
|
|
|
if (datWidget == nullptr)
|
|
continue;
|
|
|
|
const QVector<TrackEntry*>& filterEntries = datWidget->getTrackEntries();
|
|
|
|
if (filterEntries.isEmpty())
|
|
continue;
|
|
|
|
QJsonArray jsonFilterLine;
|
|
for (const TrackEntry* fte : filterEntries)
|
|
jsonFilterLine.append(fte->toJson());
|
|
|
|
jsonFilterLines.append(jsonFilterLine);
|
|
}
|
|
|
|
te->m_detailData[QStringLiteral("Filters")] = jsonFilterLines;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
QVector<TrackEntry*> TrackWidget::getTrackEntriesFiltersAsEntries(bool selectedEntriesOnly) const
|
|
{
|
|
QVector<TrackEntry*> result;
|
|
const QVector<TrackEntry*> trackEntryList = ui->mainTrack->getTrackEntries();
|
|
|
|
for (TrackEntry* te : trackEntryList)
|
|
{
|
|
if (selectedEntriesOnly && !ui->mainTrack->getSelectedEntries().contains(te))
|
|
continue;
|
|
|
|
result += te;
|
|
|
|
for (FilterTrackWidget* ftw : m_filterLines)
|
|
{
|
|
const QMap<int, TrackContentWidget*>& filterContentWidgets = ftw->fbw()->filterContentWidgets();
|
|
|
|
for (auto i1 = filterContentWidgets.constBegin(); i1 != filterContentWidgets.constEnd(); ++i1)
|
|
{
|
|
TrackContentWidget* tcw = i1.value();
|
|
result += tcw->getTrackEntries();
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
QVector<TrackEntry*> TrackWidget::getTrackEntries(bool selectedEntriesOnly) const
|
|
{
|
|
QVector<TrackEntry*> result;
|
|
const QVector<TrackEntry*> trackEntryList = ui->mainTrack->getTrackEntries();
|
|
|
|
if (selectedEntriesOnly)
|
|
{
|
|
for (TrackEntry* te : trackEntryList)
|
|
{
|
|
if (!ui->mainTrack->getSelectedEntries().contains(te))
|
|
continue;
|
|
|
|
result += te;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return trackEntryList;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void TrackWidget::setBaseWidth(int width)
|
|
{
|
|
m_baseWidth = width;
|
|
|
|
ui->mainLeft->setMinimumWidth(width);
|
|
ui->mainLeft->setMaximumWidth(width);
|
|
|
|
for (FilterTrackWidget* ftw : std::as_const(m_filterLines))
|
|
ftw->setBaseWidth(m_baseWidth);
|
|
}
|
|
|
|
void TrackWidget::addCorrespondingTrackWidget(TrackContentWidget* pCorrespondingTrackWidget)
|
|
{
|
|
ui->mainTrack->addCorrespondingTrackWidget(pCorrespondingTrackWidget);
|
|
}
|
|
|
|
TrackContentWidget* TrackWidget::getTrackContentWidget() const
|
|
{
|
|
return ui->mainTrack;
|
|
}
|
|
|
|
void TrackWidget::setInternalName(const QString& name)
|
|
{
|
|
m_internalName = name;
|
|
ui->mainTrack->setTrackName(name);
|
|
}
|
|
|
|
void TrackWidget::setTrackName(const QString& name)
|
|
{
|
|
ui->lblTrackName->setText(name);
|
|
}
|
|
|
|
bool TrackWidget::addTrackEntry(TrackEntry* te, bool selectTrackEntry)
|
|
{
|
|
if (!ui->mainTrack->addTrackEntry(te, selectTrackEntry))
|
|
return false;
|
|
|
|
const QJsonObject detailData = te->m_detailData;
|
|
|
|
if (detailData.isEmpty())
|
|
{
|
|
|
|
return true;
|
|
}
|
|
|
|
const QJsonArray filterLines = detailData[QStringLiteral("Filters")].toArray();
|
|
|
|
if (filterLines.isEmpty())
|
|
return true;
|
|
|
|
int missingFilterLines = filterLines.count() - m_filterLines.count();
|
|
|
|
while (missingFilterLines > 0)
|
|
{
|
|
slotAddFilter();
|
|
missingFilterLines--;
|
|
}
|
|
|
|
for (int i1 = 0; i1 != filterLines.count(); i1++)
|
|
{
|
|
const QJsonArray filterLine = filterLines.at(i1).toArray();
|
|
|
|
for (const QJsonValue& filter : filterLine)
|
|
{
|
|
TrackEntry* filterTe = new TrackEntry;
|
|
filterTe->fromJson(filter.toObject());
|
|
|
|
m_filterLines.at(i1)->addFilterEntry(te, filterTe);
|
|
}
|
|
}
|
|
|
|
emit signalChangesMade();
|
|
|
|
return true;
|
|
}
|
|
|
|
QString TrackWidget::trackName() const
|
|
{
|
|
return m_internalName;
|
|
}
|
|
|
|
bool TrackWidget::isSelected() const
|
|
{
|
|
return (ui->chkSelect->checkState() == Qt::CheckState::Checked);
|
|
}
|
|
|
|
void TrackWidget::unselectAll()
|
|
{
|
|
ui->mainTrack->unselectAll();
|
|
|
|
for (FilterTrackWidget* ftw : std::as_const(m_filterLines))
|
|
{
|
|
const auto fcw = ftw->fbw()->filterContentWidgets();
|
|
for (TrackContentWidget* tcw : fcw)
|
|
tcw->unselectAll();
|
|
}
|
|
}
|
|
|
|
void TrackWidget::updateMe()
|
|
{
|
|
update();
|
|
ui->mainTrack->update();
|
|
slotMainChangesMade();
|
|
}
|
|
|
|
void TrackWidget::setIndicatorTime(int time)
|
|
{
|
|
ui->mainTrack->setIndicatorTime(time);
|
|
|
|
for (FilterTrackWidget* ftw : std::as_const(m_filterLines))
|
|
{
|
|
const auto filterContentWidgets = ftw->fbw()->filterContentWidgets();
|
|
|
|
for (auto i1 = filterContentWidgets.begin(); i1 != filterContentWidgets.end(); ++i1)
|
|
{
|
|
int mainTeId = i1.key();
|
|
int mainTeStart = 0;
|
|
|
|
const QVector<TrackEntry*>& tes = ui->mainTrack->getTrackEntries();
|
|
for (const TrackEntry* te : tes)
|
|
{
|
|
if (te->m_topicId == mainTeId)
|
|
{
|
|
mainTeStart = te->m_startTime;
|
|
break;
|
|
}
|
|
}
|
|
|
|
TrackContentWidget* filterTcw = i1.value();
|
|
filterTcw->setIndicatorTime(time - mainTeStart);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TrackWidget::paintEvent(QPaintEvent* event)
|
|
{
|
|
Q_UNUSED(event);
|
|
|
|
QPainter painter(this);
|
|
|
|
painter.save();
|
|
|
|
painter.setPen(QGuiApplication::palette().windowText().color());
|
|
painter.setBrush(QGuiApplication::palette().window().color());
|
|
painter.drawRect(rect());
|
|
|
|
painter.restore();
|
|
}
|
|
|
|
} // namespace LtsScriptTimeline
|