#include "TimelineView.h" #include "TimelineHeaderView.h" #include "TimelineWidget.h" #include "EventDelegate.h" #include "EventGraphic.h" #include #include #include #include #include #include #include #include #include namespace LtsTimelineClassic { TimelineView::TimelineView(QWidget *parent) : QTreeView(parent) , m_model(nullptr) , m_drawCache(false) { m_posMarkTime = 0; setAlternatingRowColors(true); setEditTriggers(QAbstractItemView::NoEditTriggers); setSelectionBehavior(QAbstractItemView::SelectItems); setSelectionMode(QAbstractItemView::NoSelection); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); } void TimelineView::setHeader(QHeaderView *header) { if (header) { QTreeView::setHeader(header); header->setMinimumSectionSize(150); } else { } } AbstractTimelineModel *TimelineView::timelineModel() { return m_model; } void TimelineView::setTimelineModel(AbstractTimelineModel *model) { m_model = model; setMouseTracking(true); setModel(m_model); EventDelegate *ed = new EventDelegate(this); EventTools::setSectionHeight(ed->sizeHint().height()); setItemDelegate(ed); } EventGraphic *TimelineView::getEventOnPosition(QPoint position) { position = viewport()->mapFromGlobal(position); QModelIndex index = indexAt(position); if (index.isValid() && position.x() > header()->sectionSize(0)) { Item *item = static_cast(index.internalPointer()); if (!item) return nullptr; qint64 curTime = EventTools::getEventTime(position.x()); EventGraphicList egl = item->getCurrentEGLFromPevcon(); qint64 blockSizeTime = EventTools::getBlockSizeTime(); for (int i = 0; i < egl.count(); i++) { EventGraphic *eg = egl.at(i); if (!eg) continue; qint64 eventStartTime = eg->lowestTime(); if (eventStartTime == 0) continue; qint64 eventEndTime = eventStartTime; qint64 eglDuration = eg->getDuration(); if (eglDuration > blockSizeTime) eventEndTime += eglDuration; else eventEndTime += blockSizeTime; if (curTime >= eventStartTime && curTime <= eventEndTime) return eg; } } return nullptr; } bool TimelineView::event(QEvent *event) { switch (event->type()) { case QEvent::ToolTip: { QHelpEvent *helpEvent = static_cast(event); if (!helpEvent) return true; EventGraphic *eg = getEventOnPosition(helpEvent->globalPos()); if (!eg) return true; emit signalEventAction(eg, EventGraphic::ACTION_TOOLTIP); return true; } default: { break; } } return QTreeView::event(event); } void TimelineView::wheelEvent(QWheelEvent *event) { QTreeView::wheelEvent(event); if (QGuiApplication::queryKeyboardModifiers() != Qt::ControlModifier) return; int scrolls = event->delta() / 120; if (scrolls > 0) { for (int i = 0; i < scrolls; i++) emit signalZoom(); } if (scrolls < 0) { for (int i = 0; i > scrolls; i--) emit signalUnzoom(); } } void TimelineView::mouseReleaseEvent(QMouseEvent *event) { QTreeView::mouseReleaseEvent(event); QPoint position = event->globalPos(); EventGraphic *eg = getEventOnPosition(position); if (!eg) return; switch (event->button()) { case Qt::LeftButton: { emit signalEventAction(eg, EventGraphic::ACTION_LEFT_CLICKED); break; } case Qt::RightButton: { emit signalEventAction(eg, EventGraphic::ACTION_RIGHT_CLICKED); break; } default: { break; } } } void TimelineView::slotAddLine(int posX, qint64 time) { m_lineMap.insert(posX, time); } void TimelineView::slotResetLineList() { m_lineMap.clear(); } void TimelineView::slotSetPosMarkTime(qint64 posMarkTime) { m_posMarkTime = posMarkTime; TimelineHeaderView *headerView = qobject_cast(header()); if (headerView) headerView->setPosMarkTime(posMarkTime); refreshData(); } void TimelineView::refreshData() { update(); viewport()->update(); } void TimelineView::paintEvent(QPaintEvent *event) { if (!m_model) return; QWidget *viewp0rt = viewport(); QPainter painter(viewp0rt); if (!painter.isActive()) { } painter.save(); int viewPortHeight = viewp0rt->height(); QHeaderView *head0r = header(); int sectionPos = head0r->sectionPosition(1); int sectionSize = head0r->sectionSize(1); int minSection = sectionPos; int maxSection = minSection + sectionSize; QRect paintRect(minSection, 0, maxSection - minSection, height()); painter.setClipping(true); painter.setClipRect(paintRect); for (auto i = m_lineMap.constBegin(); i != m_lineMap.constEnd(); ++i) { int pos = i.key(); painter.setPen(QPen(QBrush(QGuiApplication::palette().shadow()), 1.0)); if (pos > minSection && pos < maxSection) painter.drawLine(pos, 0, pos, viewPortHeight); else { #ifdef VERBOSE qCritical() << "out of view => pos" << pos << "min" << minSection << "max" << maxSection; #endif } } painter.restore(); QTreeView::paintEvent(event); painter.save(); if (m_drawCache) { painter.setPen(QPen(QBrush("gray"), 1)); painter.setBrush(QBrush("gray")); painter.drawRect(minSection, 0, maxSection, height()); painter.setPen(QPen(QBrush("white"), 1)); painter.setBrush(QBrush("white")); int h = height(); for (const auto &range : qAsConst(m_knownRanges)) { int start = EventTools::getEventPosition(range.start); if (start < minSection) start = minSection; int end = EventTools::getEventPosition(range.end); if (end > maxSection) end = maxSection; painter.drawRect(start, 0, end - start, h); } } ItemList il = m_model->getRootItem()->getFullItemList(true); for (int i = 0; i < il.count(); i++) { if (il.at(i)->getName() == tr("Markers")) EventTools::drawMarkLines(&painter, il.at(i)->getFullEventList(true), height()); } if (m_posMarkTime > 0) { int posMarkPosition = EventTools::getEventPosition(m_posMarkTime); if (posMarkPosition > sectionPos && posMarkPosition < sectionSize + sectionPos) { painter.setPen(QPen(QGuiApplication::palette().highlight(), 1.0)); int xpos = posMarkPosition; painter.drawLine(xpos, 0, xpos, height()); } } painter.restore(); } }