QmlProfiler: Move timeline prev/next functions to models

That's where they belong. Having them in the view makes no sense.

Change-Id: Ia2a6c8b02804ed8a1e10b0731cd62b6fd6489b0c
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
This commit is contained in:
Ulf Hermann
2014-11-04 12:54:27 +01:00
committed by Ulf Hermann
parent c53a8da3a1
commit 7f7ebadae1
8 changed files with 219 additions and 201 deletions

View File

@@ -254,8 +254,16 @@ Rectangle {
height: 24 height: 24
onZoomControlChanged: zoomSliderToolBar.visible = !zoomSliderToolBar.visible onZoomControlChanged: zoomSliderToolBar.visible = !zoomSliderToolBar.visible
onFilterMenuChanged: filterMenu.visible = !filterMenu.visible onFilterMenuChanged: filterMenu.visible = !filterMenu.visible
onJumpToNext: view.selectNext(); onJumpToNext: {
onJumpToPrev: view.selectPrev(); var next = qmlProfilerModelProxy.nextItem(view.selectedModel, view.selectedItem,
zoomControl.rangeStart);
view.selectFromEventIndex(next.model, next.item);
}
onJumpToPrev: {
var prev = qmlProfilerModelProxy.prevItem(view.selectedModel, view.selectedItem,
zoomControl.rangeEnd);
view.selectFromEventIndex(prev.model, prev.item);
}
onRangeSelectChanged: selectionRangeMode = rangeButtonChecked(); onRangeSelectChanged: selectionRangeMode = rangeButtonChecked();
onLockChanged: selectionLocked = !lockButtonChecked(); onLockChanged: selectionLocked = !lockButtonChecked();
} }

View File

@@ -275,7 +275,7 @@ int TimelineModel::typeId(int index) const
int TimelineModel::firstIndex(qint64 startTime) const int TimelineModel::firstIndex(qint64 startTime) const
{ {
Q_D(const TimelineModel); Q_D(const TimelineModel);
int index = firstIndexNoParents(startTime); int index = d->firstIndexNoParents(startTime);
if (index == -1) if (index == -1)
return -1; return -1;
int parent = d->ranges[index].parent; int parent = d->ranges[index].parent;
@@ -286,18 +286,17 @@ int TimelineModel::firstIndex(qint64 startTime) const
Looks up the first range with an end time later than the specified \a startTime and Looks up the first range with an end time later than the specified \a startTime and
returns its index. If no such range is found, it returns -1. returns its index. If no such range is found, it returns -1.
*/ */
int TimelineModel::firstIndexNoParents(qint64 startTime) const int TimelineModel::TimelineModelPrivate::firstIndexNoParents(qint64 startTime) const
{ {
Q_D(const TimelineModel);
// in the "endtime" list, find the first event that ends after startTime // in the "endtime" list, find the first event that ends after startTime
if (d->endTimes.isEmpty()) if (endTimes.isEmpty())
return -1; return -1;
if (d->endTimes.count() == 1 || d->endTimes.first().end > startTime) if (endTimes.count() == 1 || endTimes.first().end > startTime)
return d->endTimes.first().startIndex; return endTimes.first().startIndex;
if (d->endTimes.last().end <= startTime) if (endTimes.last().end <= startTime)
return -1; return -1;
return d->endTimes[d->lowerBound(d->endTimes, startTime) + 1].startIndex; return endTimes[lowerBound(endTimes, startTime) + 1].startIndex;
} }
/*! /*!
@@ -506,6 +505,80 @@ void TimelineModel::clear()
emit hiddenChanged(); emit hiddenChanged();
} }
int TimelineModel::nextItemBySelectionId(int selectionId, qint64 time, int currentItem) const
{
Q_D(const TimelineModel);
return d->nextItemById(TimelineModelPrivate::SelectionId, selectionId, time, currentItem);
}
int TimelineModel::nextItemByTypeId(int typeId, qint64 time, int currentItem) const
{
Q_D(const TimelineModel);
return d->nextItemById(TimelineModelPrivate::TypeId, typeId, time, currentItem);
}
int TimelineModel::prevItemBySelectionId(int selectionId, qint64 time, int currentItem) const
{
Q_D(const TimelineModel);
return d->prevItemById(TimelineModelPrivate::SelectionId, selectionId, time, currentItem);
}
int TimelineModel::prevItemByTypeId(int typeId, qint64 time, int currentItem) const
{
Q_D(const TimelineModel);
return d->prevItemById(TimelineModelPrivate::TypeId, typeId, time, currentItem);
}
int TimelineModel::TimelineModelPrivate::nextItemById(IdType idType, int id, qint64 time,
int currentItem) const
{
Q_Q(const TimelineModel);
if (ranges.empty())
return -1;
int ndx = -1;
if (currentItem == -1)
ndx = firstIndexNoParents(time);
else
ndx = currentItem + 1;
if (ndx < 0 || ndx >= ranges.count())
ndx = 0;
int startIndex = ndx;
do {
if ((idType == TypeId && q->typeId(ndx) == id) ||
(idType == SelectionId && ranges[ndx].selectionId == id))
return ndx;
ndx = (ndx + 1) % ranges.count();
} while (ndx != startIndex);
return -1;
}
int TimelineModel::TimelineModelPrivate::prevItemById(IdType idType, int id, qint64 time,
int currentItem) const
{
Q_Q(const TimelineModel);
if (ranges.empty())
return -1;
int ndx = -1;
if (currentItem == -1)
ndx = firstIndexNoParents(time);
else
ndx = currentItem - 1;
if (ndx < 0)
ndx = ranges.count() - 1;
int startIndex = ndx;
do {
if ((idType == TypeId && q->typeId(ndx) == id) ||
(idType == SelectionId && ranges[ndx].selectionId == id))
return ndx;
if (--ndx < 0)
ndx = ranges.count()-1;
} while (ndx != startIndex);
return -1;
}
} }
#include "moc_timelinemodel.cpp" #include "moc_timelinemodel.cpp"

View File

@@ -69,7 +69,6 @@ public:
int selectionId(int index) const; int selectionId(int index) const;
int firstIndex(qint64 startTime) const; int firstIndex(qint64 startTime) const;
int firstIndexNoParents(qint64 startTime) const;
int lastIndex(qint64 endTime) const; int lastIndex(qint64 endTime) const;
bool expanded() const; bool expanded() const;
@@ -95,6 +94,11 @@ public:
virtual int rowMinValue(int rowNumber) const; virtual int rowMinValue(int rowNumber) const;
virtual int rowMaxValue(int rowNumber) const; virtual int rowMaxValue(int rowNumber) const;
Q_INVOKABLE int nextItemBySelectionId(int selectionId, qint64 time, int currentItem) const;
Q_INVOKABLE int nextItemByTypeId(int typeId, qint64 time, int currentItem) const;
Q_INVOKABLE int prevItemBySelectionId(int selectionId, qint64 time, int currentItem) const;
Q_INVOKABLE int prevItemByTypeId(int typeId, qint64 time, int currentItem) const;
static int defaultRowHeight(); static int defaultRowHeight();
signals: signals:

View File

@@ -39,6 +39,8 @@ class QMLPROFILER_EXPORT TimelineModel::TimelineModelPrivate {
public: public:
static const int DefaultRowHeight = 30; static const int DefaultRowHeight = 30;
enum IdType { SelectionId, TypeId };
enum BoxColorProperties { enum BoxColorProperties {
SelectionIdHueMultiplier = 25, SelectionIdHueMultiplier = 25,
FractionHueMultiplier = 96, FractionHueMultiplier = 96,
@@ -111,6 +113,9 @@ public:
return fromIndex; return fromIndex;
} }
int prevItemById(IdType idType, int id, qint64 time, int currentSelected) const;
int nextItemById(IdType idType, int id, qint64 time, int currentSelected) const;
QVector<Range> ranges; QVector<Range> ranges;
QVector<RangeEnd> endTimes; QVector<RangeEnd> endTimes;

View File

@@ -214,11 +214,6 @@ int TimelineModelAggregator::firstIndex(int modelIndex, qint64 startTime) const
return d->modelList[modelIndex]->firstIndex(startTime); return d->modelList[modelIndex]->firstIndex(startTime);
} }
int TimelineModelAggregator::firstIndexNoParents(int modelIndex, qint64 startTime) const
{
return d->modelList[modelIndex]->firstIndexNoParents(startTime);
}
int TimelineModelAggregator::lastIndex(int modelIndex, qint64 endTime) const int TimelineModelAggregator::lastIndex(int modelIndex, qint64 endTime) const
{ {
return d->modelList[modelIndex]->lastIndex(endTime); return d->modelList[modelIndex]->lastIndex(endTime);
@@ -376,5 +371,114 @@ int TimelineModelAggregator::modelCount() const
return d->modelList.count(); return d->modelList.count();
} }
QVariantMap TimelineModelAggregator::nextItem(int selectedModel, int selectedItem,
qint64 time) const
{
if (selectedItem != -1)
time = model(selectedModel)->startTime(selectedItem);
QVarLengthArray<int> itemIndexes(modelCount());
for (int i = 0; i < modelCount(); i++) {
const QmlProfilerTimelineModel *currentModel = model(i);
if (currentModel->count() > 0) {
if (selectedModel == i) {
itemIndexes[i] = (selectedItem + 1) % currentModel->count();
} else {
if (currentModel->startTime(0) > time)
itemIndexes[i] = 0;
else
itemIndexes[i] = (currentModel->lastIndex(time) + 1) % currentModel->count();
}
} else {
itemIndexes[i] = -1;
}
}
int candidateModelIndex = -1;
qint64 candidateStartTime = std::numeric_limits<qint64>::max();
for (int i = 0; i < modelCount(); i++) {
if (itemIndexes[i] == -1)
continue;
qint64 newStartTime = model(i)->startTime(itemIndexes[i]);
if (newStartTime > time && newStartTime < candidateStartTime) {
candidateStartTime = newStartTime;
candidateModelIndex = i;
}
}
int itemIndex;
if (candidateModelIndex != -1) {
itemIndex = itemIndexes[candidateModelIndex];
} else {
itemIndex = -1;
candidateStartTime = std::numeric_limits<qint64>::max();
for (int i = 0; i < modelCount(); i++) {
const QmlProfilerTimelineModel *currentModel = model(i);
if (currentModel->count() > 0 && currentModel->startTime(0) < candidateStartTime) {
candidateModelIndex = i;
itemIndex = 0;
candidateStartTime = currentModel->startTime(0);
}
}
}
QVariantMap ret;
ret.insert(QLatin1String("model"), candidateModelIndex);
ret.insert(QLatin1String("item"), itemIndex);
return ret;
}
QVariantMap TimelineModelAggregator::prevItem(int selectedModel, int selectedItem,
qint64 time) const
{
if (selectedItem != -1)
time = model(selectedModel)->startTime(selectedItem);
QVarLengthArray<int> itemIndexes(modelCount());
for (int i = 0; i < modelCount(); i++) {
if (selectedModel == i) {
itemIndexes[i] = selectedItem - 1;
if (itemIndexes[i] < 0)
itemIndexes[i] = model(selectedModel)->count() -1;
}
else
itemIndexes[i] = model(i)->lastIndex(time);
}
int candidateModelIndex = -1;
qint64 candidateStartTime = std::numeric_limits<qint64>::min();
for (int i = 0; i < modelCount(); i++) {
const QmlProfilerTimelineModel *currentModel = model(i);
if (itemIndexes[i] == -1 || itemIndexes[i] >= currentModel->count())
continue;
qint64 newStartTime = currentModel->startTime(itemIndexes[i]);
if (newStartTime < time && newStartTime > candidateStartTime) {
candidateStartTime = newStartTime;
candidateModelIndex = i;
}
}
int itemIndex = -1;
if (candidateModelIndex != -1) {
itemIndex = itemIndexes[candidateModelIndex];
} else {
candidateStartTime = std::numeric_limits<qint64>::min();
for (int i = 0; i < modelCount(); i++) {
const QmlProfilerTimelineModel *currentModel = model(i);
if (currentModel->count() > 0 &&
currentModel->startTime(currentModel->count() - 1) > candidateStartTime) {
candidateModelIndex = i;
itemIndex = currentModel->count() - 1;
candidateStartTime = currentModel->startTime(itemIndex);
}
}
}
QVariantMap ret;
ret.insert(QLatin1String("model"), candidateModelIndex);
ret.insert(QLatin1String("item"), itemIndex);
return ret;
}
} // namespace Internal } // namespace Internal
} // namespace QmlProfiler } // namespace QmlProfiler

View File

@@ -78,7 +78,6 @@ public:
Q_INVOKABLE int rowMaxValue(int modelIndex, int row) const; Q_INVOKABLE int rowMaxValue(int modelIndex, int row) const;
Q_INVOKABLE int firstIndex(int modelIndex, qint64 startTime) const; Q_INVOKABLE int firstIndex(int modelIndex, qint64 startTime) const;
Q_INVOKABLE int firstIndexNoParents(int modelIndex, qint64 startTime) const;
Q_INVOKABLE int lastIndex(int modelIndex, qint64 endTime) const; Q_INVOKABLE int lastIndex(int modelIndex, qint64 endTime) const;
Q_INVOKABLE int row(int modelIndex, int index) const; Q_INVOKABLE int row(int modelIndex, int index) const;
@@ -111,6 +110,9 @@ public:
Q_INVOKABLE QVariantList notesByTypeId(int typeId) const; Q_INVOKABLE QVariantList notesByTypeId(int typeId) const;
Q_INVOKABLE int noteCount() const; Q_INVOKABLE int noteCount() const;
Q_INVOKABLE QVariantMap nextItem(int selectedModel, int selectedItem, qint64 time) const;
Q_INVOKABLE QVariantMap prevItem(int selectedModel, int selectedItem, qint64 time) const;
signals: signals:
void dataAvailable(); void dataAvailable();
void stateChanged(); void stateChanged();

View File

@@ -567,178 +567,6 @@ int TimelineRenderer::getYPosition(int modelIndex, int index) const
m_profilerModelProxy->row(modelIndex, index)); m_profilerModelProxy->row(modelIndex, index));
} }
void TimelineRenderer::selectNext()
{
if (m_profilerModelProxy->isEmpty())
return;
qint64 searchTime = m_zoomer->rangeStart();
if (m_selectedItem != -1)
searchTime = m_profilerModelProxy->startTime(m_selectedModel, m_selectedItem);
QVarLengthArray<int> itemIndexes(m_profilerModelProxy->modelCount());
for (int i = 0; i < m_profilerModelProxy->modelCount(); i++) {
if (m_profilerModelProxy->count(i) > 0) {
if (m_selectedModel == i) {
itemIndexes[i] = (m_selectedItem + 1) % m_profilerModelProxy->count(i);
} else {
if (m_profilerModelProxy->startTime(i, 0) > searchTime)
itemIndexes[i] = 0;
else
itemIndexes[i] = (m_profilerModelProxy->lastIndex(i, searchTime) + 1) % m_profilerModelProxy->count(i);
}
} else {
itemIndexes[i] = -1;
}
}
int candidateModelIndex = -1;
qint64 candidateStartTime = m_zoomer->traceEnd();
for (int i = 0; i < m_profilerModelProxy->modelCount(); i++) {
if (itemIndexes[i] == -1)
continue;
qint64 newStartTime = m_profilerModelProxy->startTime(i, itemIndexes[i]);
if (newStartTime > searchTime && newStartTime < candidateStartTime) {
candidateStartTime = newStartTime;
candidateModelIndex = i;
}
}
int itemIndex;
if (candidateModelIndex != -1) {
itemIndex = itemIndexes[candidateModelIndex];
} else {
// find the first index of them all (todo: the modelproxy should do this)
itemIndex = -1;
candidateStartTime = m_zoomer->traceEnd();
for (int i = 0; i < m_profilerModelProxy->modelCount(); i++)
if (m_profilerModelProxy->count(i) > 0 &&
m_profilerModelProxy->startTime(i,0) < candidateStartTime) {
candidateModelIndex = i;
itemIndex = 0;
candidateStartTime = m_profilerModelProxy->startTime(i,0);
}
}
selectFromEventIndex(candidateModelIndex, itemIndex);
}
void TimelineRenderer::selectPrev()
{
if (m_profilerModelProxy->isEmpty())
return;
qint64 searchTime = m_zoomer->rangeEnd();
if (m_selectedItem != -1)
searchTime = m_profilerModelProxy->startTime(m_selectedModel, m_selectedItem);
QVarLengthArray<int> itemIndexes(m_profilerModelProxy->modelCount());
for (int i = 0; i < m_profilerModelProxy->modelCount(); i++) {
if (m_selectedModel == i) {
itemIndexes[i] = m_selectedItem - 1;
if (itemIndexes[i] < 0)
itemIndexes[i] = m_profilerModelProxy->count(m_selectedModel) -1;
}
else
itemIndexes[i] = m_profilerModelProxy->lastIndex(i, searchTime);
}
int candidateModelIndex = -1;
qint64 candidateStartTime = m_zoomer->traceStart();
for (int i = 0; i < m_profilerModelProxy->modelCount(); i++) {
if (itemIndexes[i] == -1
|| itemIndexes[i] >= m_profilerModelProxy->count(i))
continue;
qint64 newStartTime = m_profilerModelProxy->startTime(i, itemIndexes[i]);
if (newStartTime < searchTime && newStartTime > candidateStartTime) {
candidateStartTime = newStartTime;
candidateModelIndex = i;
}
}
int itemIndex = -1;
if (candidateModelIndex != -1) {
itemIndex = itemIndexes[candidateModelIndex];
} else {
// find the last index of them all (todo: the modelproxy should do this)
candidateModelIndex = 0;
candidateStartTime = m_zoomer->traceStart();
for (int i = 0; i < m_profilerModelProxy->modelCount(); i++)
if (m_profilerModelProxy->count(i) > 0 &&
m_profilerModelProxy->startTime(i,m_profilerModelProxy->count(i)-1) > candidateStartTime) {
candidateModelIndex = i;
itemIndex = m_profilerModelProxy->count(candidateModelIndex) - 1;
candidateStartTime = m_profilerModelProxy->startTime(i,m_profilerModelProxy->count(i)-1);
}
}
selectFromEventIndex(candidateModelIndex, itemIndex);
}
int TimelineRenderer::nextItemFromSelectionId(int modelIndex, int selectionId) const
{
return nextItemFromId(modelIndex, SelectionId, selectionId);
}
int TimelineRenderer::nextItemFromTypeId(int modelIndex, int typeId) const
{
return nextItemFromId(modelIndex, TypeId, typeId);
}
int TimelineRenderer::prevItemFromSelectionId(int modelIndex, int selectionId) const
{
return prevItemFromId(modelIndex, SelectionId, selectionId);
}
int TimelineRenderer::prevItemFromTypeId(int modelIndex, int typeId) const
{
return prevItemFromId(modelIndex, TypeId, typeId);
}
int TimelineRenderer::nextItemFromId(int modelIndex, IdType idType, int id) const
{
int modelCount = m_profilerModelProxy->count(modelIndex);
if (modelCount == 0)
return -1;
int ndx = -1;
if (m_selectedItem == -1 || modelIndex != m_selectedModel)
ndx = m_profilerModelProxy->firstIndexNoParents(modelIndex, m_zoomer->rangeStart());
else
ndx = m_selectedItem + 1;
if (ndx < 0 || ndx >= modelCount)
ndx = 0;
int startIndex = ndx;
do {
if ((idType == TypeId && m_profilerModelProxy->typeId(modelIndex, ndx) == id) ||
(idType == SelectionId && m_profilerModelProxy->selectionId(modelIndex, ndx) == id))
return ndx;
ndx = (ndx + 1) % modelCount;
} while (ndx != startIndex);
return -1;
}
int TimelineRenderer::prevItemFromId(int modelIndex, IdType idType, int id) const
{
int ndx = -1;
if (m_selectedItem == -1 || modelIndex != m_selectedModel)
ndx = m_profilerModelProxy->firstIndexNoParents(modelIndex, m_zoomer->rangeStart());
else
ndx = m_selectedItem - 1;
if (ndx < 0)
ndx = m_profilerModelProxy->count(modelIndex) - 1;
int startIndex = ndx;
do {
if ((idType == TypeId && m_profilerModelProxy->typeId(modelIndex, ndx) == id) ||
(idType == SelectionId && m_profilerModelProxy->selectionId(modelIndex, ndx) == id))
return ndx;
if (--ndx < 0)
ndx = m_profilerModelProxy->count(modelIndex)-1;
} while (ndx != startIndex);
return -1;
}
void TimelineRenderer::selectFromEventIndex(int modelIndex, int eventIndex) void TimelineRenderer::selectFromEventIndex(int modelIndex, int eventIndex)
{ {
if (modelIndex != m_selectedModel || eventIndex != m_selectedItem) { if (modelIndex != m_selectedModel || eventIndex != m_selectedItem) {
@@ -748,12 +576,14 @@ void TimelineRenderer::selectFromEventIndex(int modelIndex, int eventIndex)
} }
} }
void TimelineRenderer::selectNextFromSelectionId(int modelIndex, int typeId) void TimelineRenderer::selectNextFromSelectionId(int modelIndex, int selectionId)
{ {
selectFromEventIndex(modelIndex, nextItemFromSelectionId(modelIndex, typeId)); selectFromEventIndex(modelIndex, m_profilerModelProxy->model(modelIndex)->nextItemBySelectionId(
selectionId, m_zoomer->rangeStart(), m_selectedItem));
} }
void TimelineRenderer::selectPrevFromSelectionId(int modelIndex, int typeId) void TimelineRenderer::selectPrevFromSelectionId(int modelIndex, int selectionId)
{ {
selectFromEventIndex(modelIndex, prevItemFromSelectionId(modelIndex, typeId)); selectFromEventIndex(modelIndex, m_profilerModelProxy->model(modelIndex)->prevItemBySelectionId(
selectionId, m_zoomer->rangeStart(), m_selectedItem));
} }

View File

@@ -86,12 +86,6 @@ public:
Q_INVOKABLE int getYPosition(int modelIndex, int index) const; Q_INVOKABLE int getYPosition(int modelIndex, int index) const;
Q_INVOKABLE void selectNext();
Q_INVOKABLE void selectPrev();
Q_INVOKABLE int nextItemFromSelectionId(int modelIndex, int selectionId) const;
Q_INVOKABLE int nextItemFromTypeId(int modelIndex, int typeId) const;
Q_INVOKABLE int prevItemFromSelectionId(int modelIndex, int selectionId) const;
Q_INVOKABLE int prevItemFromTypeId(int modelIndex, int typeId) const;
Q_INVOKABLE void selectFromEventIndex(int modelIndex, int index); Q_INVOKABLE void selectFromEventIndex(int modelIndex, int index);
Q_INVOKABLE void selectNextFromSelectionId(int modelIndex, int selectionId); Q_INVOKABLE void selectNextFromSelectionId(int modelIndex, int selectionId);
Q_INVOKABLE void selectPrevFromSelectionId(int modelIndex, int selectionId); Q_INVOKABLE void selectPrevFromSelectionId(int modelIndex, int selectionId);
@@ -203,8 +197,6 @@ private:
bool m_selectionLocked; bool m_selectionLocked;
int m_startDragArea; int m_startDragArea;
int m_endDragArea; int m_endDragArea;
int nextItemFromId(int modelIndex, IdType idType, int id) const;
int prevItemFromId(int modelIndex, IdType idType, int id) const;
}; };
} // namespace Internal } // namespace Internal