forked from qt-creator/qt-creator
QmlProfiler: fix selection propagation from event view to timeline
The event view deals in type ids and the timeline view has to handle selection by type id. Using the coincidence that typeId == selectionId in the cases we're interested in is ugly. Change-Id: I6f94ccd2c3945d5901d0a225deee7de077bfce58 Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
This commit is contained in:
@@ -374,7 +374,7 @@ QVariantMap AbstractTimelineModel::location(int index) const
|
||||
return map;
|
||||
}
|
||||
|
||||
bool AbstractTimelineModel::isSelectionIdValid(int typeIndex) const
|
||||
bool AbstractTimelineModel::handlesTypeId(int typeIndex) const
|
||||
{
|
||||
Q_UNUSED(typeIndex);
|
||||
return false;
|
||||
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
// returned map should contain "file", "line", "column" properties, or be empty
|
||||
virtual QVariantMap location(int index) const;
|
||||
virtual int selectionId(int index) const;
|
||||
virtual bool isSelectionIdValid(int selectionId) const;
|
||||
virtual bool handlesTypeId(int typeId) const;
|
||||
virtual int selectionIdForLocation(const QString &filename, int line, int column) const;
|
||||
virtual int bindingLoopDest(int index) const;
|
||||
virtual float relativeHeight(int index) const;
|
||||
|
||||
@@ -138,35 +138,41 @@ Rectangle {
|
||||
Math.max(0, totalRowOffset - flick.height / 2));
|
||||
}
|
||||
|
||||
function selectBySelectionId(modelIndex, selectionId)
|
||||
function selectByTypeId(typeId)
|
||||
{
|
||||
if (selectionId === -1 || (modelIndex === view.selectedModel && view.selectedItem !== -1 &&
|
||||
selectionId === qmlProfilerModelProxy.selectionId(modelIndex, view.selectedItem)))
|
||||
if (lockItemSelection || typeId === -1)
|
||||
return;
|
||||
|
||||
// this is a slot responding to events from the other pane
|
||||
// which tracks only events from the basic model
|
||||
if (!lockItemSelection) {
|
||||
lockItemSelection = true;
|
||||
var itemIndex = -1;
|
||||
var notes = qmlProfilerModelProxy.notesByTypeId(selectionId);
|
||||
if (notes.length !== 0) {
|
||||
itemIndex = qmlProfilerModelProxy.noteTimelineIndex(notes[0]);
|
||||
// for some models typeId != selectionId. In that case we cannot select the noted
|
||||
// events. This is purely theoretical as their data doesn't show up in the events
|
||||
// view so that we cannot receive a selection event for them.
|
||||
if (qmlProfilerModelProxy.typeId(modelIndex, itemIndex) !== selectionId)
|
||||
itemIndex = -1;
|
||||
}
|
||||
lockItemSelection = true;
|
||||
|
||||
if (itemIndex === -1)
|
||||
itemIndex = view.nextItemFromSelectionId(modelIndex, selectionId);
|
||||
var itemIndex = -1;
|
||||
var modelIndex = -1;
|
||||
var notes = qmlProfilerModelProxy.notesByTypeId(typeId);
|
||||
if (notes.length !== 0) {
|
||||
modelIndex = qmlProfilerModelProxy.noteTimelineModel(notes[0]);
|
||||
itemIndex = qmlProfilerModelProxy.noteTimelineIndex(notes[0]);
|
||||
} else {
|
||||
for (modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount(); ++modelIndex) {
|
||||
if (modelIndex === view.selectedModel && view.selectedItem !== -1 &&
|
||||
typeId === qmlProfilerModelProxy.typeId(modelIndex, view.selectedItem))
|
||||
break;
|
||||
|
||||
if (!qmlProfilerModelProxy.handlesTypeId(modelIndex, typeId))
|
||||
continue;
|
||||
|
||||
itemIndex = view.nextItemFromTypeId(modelIndex, typeId);
|
||||
if (itemIndex !== -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemIndex !== -1) {
|
||||
// select an item, lock to it, and recenter if necessary
|
||||
view.selectFromEventIndex(modelIndex, itemIndex); // triggers recentering
|
||||
if (itemIndex !== -1)
|
||||
view.selectionLocked = true;
|
||||
lockItemSelection = false;
|
||||
view.selectionLocked = true;
|
||||
}
|
||||
|
||||
lockItemSelection = false;
|
||||
}
|
||||
|
||||
// ***** slots
|
||||
|
||||
@@ -259,7 +259,7 @@ QVariantMap QmlProfilerRangeModel::location(int index) const
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QmlProfilerRangeModel::isSelectionIdValid(int typeId) const
|
||||
bool QmlProfilerRangeModel::handlesTypeId(int typeId) const
|
||||
{
|
||||
if (typeId < 0)
|
||||
return false;
|
||||
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
QVariantMap details(int index) const;
|
||||
QVariantMap location(int index) const;
|
||||
|
||||
bool isSelectionIdValid(int typeIndex) const;
|
||||
bool handlesTypeId(int typeIndex) const;
|
||||
int selectionIdForLocation(const QString &filename, int line, int column) const;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -182,15 +182,7 @@ void QmlProfilerTraceView::selectByTypeId(int typeId)
|
||||
QQuickItem *rootObject = d->m_mainView->rootObject();
|
||||
if (!rootObject)
|
||||
return;
|
||||
|
||||
for (int modelIndex = 0; modelIndex < d->m_modelProxy->modelCount(); ++modelIndex) {
|
||||
if (d->m_modelProxy->isSelectionIdValid(modelIndex, typeId)) {
|
||||
QMetaObject::invokeMethod(rootObject, "selectBySelectionId",
|
||||
Q_ARG(QVariant,QVariant(modelIndex)),
|
||||
Q_ARG(QVariant,QVariant(typeId)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
QMetaObject::invokeMethod(rootObject, "selectByTypeId", Q_ARG(QVariant,QVariant(typeId)));
|
||||
}
|
||||
|
||||
void QmlProfilerTraceView::selectBySourceLocation(const QString &filename, int line, int column)
|
||||
|
||||
@@ -289,9 +289,9 @@ QVariantMap TimelineModelAggregator::location(int modelIndex, int index) const
|
||||
return d->modelList[modelIndex]->location(index);
|
||||
}
|
||||
|
||||
bool TimelineModelAggregator::isSelectionIdValid(int modelIndex, int typeIndex) const
|
||||
bool TimelineModelAggregator::handlesTypeId(int modelIndex, int typeIndex) const
|
||||
{
|
||||
return d->modelList[modelIndex]->isSelectionIdValid(typeIndex);
|
||||
return d->modelList[modelIndex]->handlesTypeId(typeIndex);
|
||||
}
|
||||
|
||||
int TimelineModelAggregator::selectionIdForLocation(int modelIndex, const QString &filename,
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
Q_INVOKABLE QVariantMap details(int modelIndex, int index) const;
|
||||
Q_INVOKABLE QVariantMap location(int modelIndex, int index) const;
|
||||
|
||||
Q_INVOKABLE bool isSelectionIdValid(int modelIndex, int typeIndex) const;
|
||||
Q_INVOKABLE bool handlesTypeId(int modelIndex, int typeIndex) const;
|
||||
Q_INVOKABLE int selectionIdForLocation(int modelIndex, const QString &filename, int line,
|
||||
int column) const;
|
||||
|
||||
|
||||
@@ -676,6 +676,26 @@ void TimelineRenderer::selectPrev()
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -691,14 +711,15 @@ int TimelineRenderer::nextItemFromSelectionId(int modelIndex, int selectionId) c
|
||||
ndx = 0;
|
||||
int startIndex = ndx;
|
||||
do {
|
||||
if (m_profilerModelProxy->selectionId(modelIndex, ndx) == selectionId)
|
||||
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::prevItemFromSelectionId(int modelIndex, int selectionId) const
|
||||
int TimelineRenderer::prevItemFromId(int modelIndex, IdType idType, int id) const
|
||||
{
|
||||
int ndx = -1;
|
||||
if (m_selectedItem == -1 || modelIndex != m_selectedModel)
|
||||
@@ -709,7 +730,8 @@ int TimelineRenderer::prevItemFromSelectionId(int modelIndex, int selectionId) c
|
||||
ndx = m_profilerModelProxy->count(modelIndex) - 1;
|
||||
int startIndex = ndx;
|
||||
do {
|
||||
if (m_profilerModelProxy->selectionId(modelIndex, ndx) == selectionId)
|
||||
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;
|
||||
|
||||
@@ -89,7 +89,9 @@ public:
|
||||
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 selectNextFromSelectionId(int modelIndex, int selectionId);
|
||||
Q_INVOKABLE void selectPrevFromSelectionId(int modelIndex, int selectionId);
|
||||
@@ -174,6 +176,8 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
enum IdType { SelectionId, TypeId };
|
||||
|
||||
static const int OutOfScreenMargin = 3; // margin to make sure the rectangles stay invisible
|
||||
static const int MinimumItemWidth = 3;
|
||||
|
||||
@@ -199,6 +203,8 @@ private:
|
||||
bool m_selectionLocked;
|
||||
int m_startDragArea;
|
||||
int m_endDragArea;
|
||||
int nextItemFromId(int modelIndex, IdType idType, int id) const;
|
||||
int prevItemFromId(int modelIndex, IdType idType, int id) const;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
Reference in New Issue
Block a user